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 |
(...skipping 17 matching lines...) Expand all Loading... |
91 | 93 |
92 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); | 94 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); |
93 GURL url = util::ConvertDrivePathToFileSystemUrl( | 95 GURL url = util::ConvertDrivePathToFileSystemUrl( |
94 profile, job_info.file_path, extension_id); | 96 profile, job_info.file_path, extension_id); |
95 status->file_url = url.spec(); | 97 status->file_url = url.spec(); |
96 status->transfer_state = file_browser_private::ParseTransferState(job_status); | 98 status->transfer_state = file_browser_private::ParseTransferState(job_status); |
97 status->transfer_type = | 99 status->transfer_type = |
98 IsUploadJob(job_info.job_type) ? | 100 IsUploadJob(job_info.job_type) ? |
99 file_browser_private::TRANSFER_TYPE_UPLOAD : | 101 file_browser_private::TRANSFER_TYPE_UPLOAD : |
100 file_browser_private::TRANSFER_TYPE_DOWNLOAD; | 102 file_browser_private::TRANSFER_TYPE_DOWNLOAD; |
| 103 status->num_total_jobs = job_info.num_total_jobs; |
101 // JavaScript does not have 64-bit integers. Instead we use double, which | 104 // 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 | 105 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice |
103 // in C++. Larger values are rounded. | 106 // in C++. Larger values are rounded. |
104 status->processed.reset( | 107 status->processed.reset( |
105 new double(static_cast<double>(job_info.num_completed_bytes))); | 108 new double(static_cast<double>(job_info.num_completed_bytes))); |
106 status->total.reset( | 109 status->total.reset( |
107 new double(static_cast<double>(job_info.num_total_bytes))); | 110 new double(static_cast<double>(job_info.num_total_bytes))); |
108 } | 111 } |
109 | 112 |
110 // Checks if the Recovery Tool is running. This is a temporary solution. | 113 // Checks if the Recovery Tool is running. This is a temporary solution. |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 EventRouter::DriveJobInfoWithStatus::DriveJobInfoWithStatus() | 361 EventRouter::DriveJobInfoWithStatus::DriveJobInfoWithStatus() |
359 : job_info(drive::TYPE_DOWNLOAD_FILE) { | 362 : job_info(drive::TYPE_DOWNLOAD_FILE) { |
360 } | 363 } |
361 | 364 |
362 EventRouter::DriveJobInfoWithStatus::DriveJobInfoWithStatus( | 365 EventRouter::DriveJobInfoWithStatus::DriveJobInfoWithStatus( |
363 const drive::JobInfo& info, const std::string& status) | 366 const drive::JobInfo& info, const std::string& status) |
364 : job_info(info), status(status) { | 367 : job_info(info), status(status) { |
365 } | 368 } |
366 | 369 |
367 EventRouter::EventRouter(Profile* profile) | 370 EventRouter::EventRouter(Profile* profile) |
368 : pref_change_registrar_(new PrefChangeRegistrar), | 371 : startup_time_delta_(base::TimeDelta::FromMilliseconds(100)), |
| 372 pref_change_registrar_(new PrefChangeRegistrar), |
369 profile_(profile), | 373 profile_(profile), |
370 multi_user_window_manager_observer_registered_(false), | 374 multi_user_window_manager_observer_registered_(false), |
371 device_event_router_(new DeviceEventRouterImpl(profile)), | 375 device_event_router_(new DeviceEventRouterImpl(profile)), |
372 weak_factory_(this) { | 376 weak_factory_(this) { |
373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
374 } | 378 } |
375 | 379 |
376 EventRouter::~EventRouter() { | 380 EventRouter::~EventRouter() { |
377 } | 381 } |
378 | 382 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 } | 617 } |
614 | 618 |
615 BroadcastEvent( | 619 BroadcastEvent( |
616 profile_, | 620 profile_, |
617 file_browser_private::OnPreferencesChanged::kEventName, | 621 file_browser_private::OnPreferencesChanged::kEventName, |
618 file_browser_private::OnPreferencesChanged::Create()); | 622 file_browser_private::OnPreferencesChanged::Create()); |
619 } | 623 } |
620 | 624 |
621 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { | 625 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { |
622 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 626 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
623 OnJobUpdated(job_info); | 627 if (!drive::IsActiveFileTransferJobInfo(job_info)) |
| 628 return; |
| 629 DriveJobInfoWithStatus job_info_with_status = |
| 630 DriveJobInfoWithStatus(job_info, kFileTransferStateAdded); |
| 631 SendDriveFileTransferEventDelay( |
| 632 job_info_with_status, base::Time::Now(), false /* is_delayed */); |
624 } | 633 } |
625 | 634 |
626 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { | 635 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { |
627 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 636 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
628 if (!drive::IsActiveFileTransferJobInfo(job_info)) | 637 if (!drive::IsActiveFileTransferJobInfo(job_info)) |
629 return; | 638 return; |
630 | 639 |
631 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end()); | 640 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end()); |
632 | 641 |
633 // Replace with the latest job info. | 642 // Replace with the latest job info. |
634 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( | 643 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( |
635 job_info, | 644 job_info, |
636 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress); | 645 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress); |
637 | 646 |
638 // Fire event if needed. | 647 DriveJobInfoWithStatus job_info_with_status = drive_jobs_[job_info.job_id]; |
639 bool always = is_new_job; | 648 SendDriveFileTransferEventDelay( |
640 SendDriveFileTransferEvent(always); | 649 job_info_with_status, base::Time::Now(), false /* is_delayed */); |
641 } | 650 } |
642 | 651 |
643 void EventRouter::OnJobDone(const drive::JobInfo& job_info, | 652 void EventRouter::OnJobDone(const drive::JobInfo& job_info, |
644 drive::FileError error) { | 653 drive::FileError error) { |
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 654 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
646 if (!drive::IsActiveFileTransferJobInfo(job_info)) | 655 if (!drive::IsActiveFileTransferJobInfo(job_info)) |
647 return; | 656 return; |
648 | 657 |
649 // Replace with the latest job info. | 658 // Replace with the latest job info. |
650 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( | 659 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( |
651 job_info, | 660 job_info, |
652 error == drive::FILE_ERROR_OK ? kFileTransferStateCompleted | 661 error == drive::FILE_ERROR_OK ? kFileTransferStateCompleted |
653 : kFileTransferStateFailed); | 662 : kFileTransferStateFailed); |
654 | 663 |
655 // Fire event if needed. | 664 // Fire event if needed. |
656 bool always = true; | 665 bool always = true; |
657 SendDriveFileTransferEvent(always); | 666 SendDriveFileTransferEvent(always); |
658 | 667 |
659 // Forget about the job. | 668 // Forget about the job. |
660 drive_jobs_.erase(job_info.job_id); | 669 drive_jobs_.erase(job_info.job_id); |
661 } | 670 } |
662 | 671 |
| 672 void EventRouter::SendDriveFileTransferEventDelay( |
| 673 const DriveJobInfoWithStatus& job_info_with_status, |
| 674 base::Time call_time, |
| 675 bool is_delayed) { |
| 676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 677 |
| 678 if (!is_delayed) { |
| 679 last_post_delayed_task_ = base::Time::Now(); |
| 680 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 681 FROM_HERE, |
| 682 base::Bind(&EventRouter::SendDriveFileTransferEventDelay, |
| 683 weak_factory_.GetWeakPtr(), |
| 684 job_info_with_status, |
| 685 last_post_delayed_task_, |
| 686 true /* is_delayed */), |
| 687 startup_time_delta_); |
| 688 return; |
| 689 } |
| 690 |
| 691 DCHECK(!last_post_delayed_task_.is_null()); |
| 692 |
| 693 if (call_time < last_post_delayed_task_) { |
| 694 return; |
| 695 } |
| 696 |
| 697 // Convert the current |drive_jobs_| to IDL type. |
| 698 std::vector<linked_ptr<file_browser_private::FileTransferStatus> > |
| 699 status_list; |
| 700 |
| 701 linked_ptr<file_browser_private::FileTransferStatus> status( |
| 702 new file_browser_private::FileTransferStatus()); |
| 703 JobInfoToTransferStatus(profile_, |
| 704 kFileManagerAppId, |
| 705 job_info_with_status.status, |
| 706 job_info_with_status.job_info, |
| 707 status.get()); |
| 708 status_list.push_back(status); |
| 709 |
| 710 BroadcastEvent( |
| 711 profile_, |
| 712 file_browser_private::OnFileTransfersUpdated::kEventName, |
| 713 file_browser_private::OnFileTransfersUpdated::Create(status_list)); |
| 714 } |
| 715 |
663 void EventRouter::SendDriveFileTransferEvent(bool always) { | 716 void EventRouter::SendDriveFileTransferEvent(bool always) { |
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 717 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
665 | 718 |
666 // When |always| flag is not set, we don't send the event until certain | 719 // When |always| flag is not set, we don't send the event until certain |
667 // amount of time passes after the previous one. This is to avoid | 720 // amount of time passes after the previous one. This is to avoid |
668 // flooding the IPC between extensions by many onFileTransferUpdated events. | 721 // flooding the IPC between extensions by many onFileTransferUpdated events. |
669 if (!ShouldSendProgressEvent(always, &last_file_transfer_event_)) | 722 if (!ShouldSendProgressEvent(always, &last_file_transfer_event_)) |
670 return; | 723 return; |
671 | 724 |
672 // Convert the current |drive_jobs_| to IDL type. | 725 // Convert the current |drive_jobs_| to IDL type. |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 } | 1019 } |
967 } | 1020 } |
968 | 1021 |
969 void EventRouter::OnOwnerEntryChanged(aura::Window* window) { | 1022 void EventRouter::OnOwnerEntryChanged(aura::Window* window) { |
970 BroadcastEvent(profile_, | 1023 BroadcastEvent(profile_, |
971 file_browser_private::OnDesktopChanged::kEventName, | 1024 file_browser_private::OnDesktopChanged::kEventName, |
972 file_browser_private::OnDesktopChanged::Create()); | 1025 file_browser_private::OnDesktopChanged::Create()); |
973 } | 1026 } |
974 | 1027 |
975 } // namespace file_manager | 1028 } // namespace file_manager |
OLD | NEW |