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

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

Issue 343073003: Files.app: Provide detailed change information on onDirectoryChanged event (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed the comments Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/file_util.h" 8 #include "base/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/threading/sequenced_worker_pool.h" 13 #include "base/threading/sequenced_worker_pool.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "chrome/browser/app_mode/app_mode_utils.h" 15 #include "chrome/browser/app_mode/app_mode_utils.h"
16 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/chromeos/drive/drive_integration_service.h" 17 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
18 #include "chrome/browser/chromeos/drive/file_change.h"
18 #include "chrome/browser/chromeos/drive/file_system_interface.h" 19 #include "chrome/browser/chromeos/drive/file_system_interface.h"
19 #include "chrome/browser/chromeos/drive/file_system_util.h" 20 #include "chrome/browser/chromeos/drive/file_system_util.h"
20 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h" 21 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
21 #include "chrome/browser/chromeos/file_manager/app_id.h" 22 #include "chrome/browser/chromeos/file_manager/app_id.h"
22 #include "chrome/browser/chromeos/file_manager/fileapi_util.h" 23 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
23 #include "chrome/browser/chromeos/file_manager/open_util.h" 24 #include "chrome/browser/chromeos/file_manager/open_util.h"
24 #include "chrome/browser/chromeos/file_manager/volume_manager.h" 25 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
25 #include "chrome/browser/chromeos/login/lock/screen_locker.h" 26 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
26 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" 27 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
27 #include "chrome/browser/drive/drive_service_interface.h" 28 #include "chrome/browser/drive/drive_service_interface.h"
28 #include "chrome/browser/extensions/extension_service.h" 29 #include "chrome/browser/extensions/extension_service.h"
30 #include "chrome/browser/extensions/extension_util.h"
29 #include "chrome/browser/profiles/profile.h" 31 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/profiles/profile_manager.h" 32 #include "chrome/browser/profiles/profile_manager.h"
31 #include "chrome/common/pref_names.h" 33 #include "chrome/common/pref_names.h"
32 #include "chromeos/login/login_state.h" 34 #include "chromeos/login/login_state.h"
33 #include "chromeos/network/network_handler.h" 35 #include "chromeos/network/network_handler.h"
34 #include "chromeos/network/network_state_handler.h" 36 #include "chromeos/network/network_state_handler.h"
35 #include "content/public/browser/browser_thread.h" 37 #include "content/public/browser/browser_thread.h"
36 #include "content/public/browser/notification_source.h" 38 #include "content/public/browser/notification_source.h"
37 #include "content/public/browser/render_process_host.h" 39 #include "content/public/browser/render_process_host.h"
40 #include "content/public/browser/storage_partition.h"
38 #include "extensions/browser/event_router.h" 41 #include "extensions/browser/event_router.h"
39 #include "extensions/browser/extension_host.h" 42 #include "extensions/browser/extension_host.h"
40 #include "extensions/browser/extension_prefs.h" 43 #include "extensions/browser/extension_prefs.h"
41 #include "extensions/browser/extension_system.h" 44 #include "extensions/browser/extension_system.h"
42 #include "webkit/common/fileapi/file_system_types.h" 45 #include "webkit/common/fileapi/file_system_types.h"
43 #include "webkit/common/fileapi/file_system_util.h" 46 #include "webkit/common/fileapi/file_system_util.h"
44 47
45 using chromeos::disks::DiskMountManager; 48 using chromeos::disks::DiskMountManager;
46 using chromeos::NetworkHandler; 49 using chromeos::NetworkHandler;
47 using content::BrowserThread; 50 using content::BrowserThread;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 84
82 // Constants for the "transferState" field of onFileTransferUpdated event. 85 // Constants for the "transferState" field of onFileTransferUpdated event.
83 const char kFileTransferStateStarted[] = "started"; 86 const char kFileTransferStateStarted[] = "started";
84 const char kFileTransferStateInProgress[] = "in_progress"; 87 const char kFileTransferStateInProgress[] = "in_progress";
85 const char kFileTransferStateCompleted[] = "completed"; 88 const char kFileTransferStateCompleted[] = "completed";
86 const char kFileTransferStateFailed[] = "failed"; 89 const char kFileTransferStateFailed[] = "failed";
87 90
88 // Frequency of sending onFileTransferUpdated. 91 // Frequency of sending onFileTransferUpdated.
89 const int64 kProgressEventFrequencyInMilliseconds = 1000; 92 const int64 kProgressEventFrequencyInMilliseconds = 1000;
90 93
94 // Maximim size of detailed change info on directory change event. If the size
95 // exceeds the maximum size, the detailed info is omitted and the force refresh
96 // is kicked.
97 const int kDirectoryChangeEventMaxDetailInfoSize = 1000;
kinaba 2014/06/24 07:24:47 maybe: size_t
yoshiki 2014/06/24 14:09:29 Done.
98
91 // Utility function to check if |job_info| is a file uploading job. 99 // Utility function to check if |job_info| is a file uploading job.
92 bool IsUploadJob(drive::JobType type) { 100 bool IsUploadJob(drive::JobType type) {
93 return (type == drive::TYPE_UPLOAD_NEW_FILE || 101 return (type == drive::TYPE_UPLOAD_NEW_FILE ||
94 type == drive::TYPE_UPLOAD_EXISTING_FILE); 102 type == drive::TYPE_UPLOAD_EXISTING_FILE);
95 } 103 }
96 104
97 // Converts the job info to a IDL generated type. 105 // Converts the job info to a IDL generated type.
98 void JobInfoToTransferStatus( 106 void JobInfoToTransferStatus(
99 Profile* profile, 107 Profile* profile,
100 const std::string& extension_id, 108 const std::string& extension_id,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_BEGIN_COPY_ENTRY; 269 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_BEGIN_COPY_ENTRY;
262 case fileapi::FileSystemOperation::END_COPY_ENTRY: 270 case fileapi::FileSystemOperation::END_COPY_ENTRY:
263 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_END_COPY_ENTRY; 271 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_END_COPY_ENTRY;
264 case fileapi::FileSystemOperation::PROGRESS: 272 case fileapi::FileSystemOperation::PROGRESS:
265 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_PROGRESS; 273 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_PROGRESS;
266 } 274 }
267 NOTREACHED(); 275 NOTREACHED();
268 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_NONE; 276 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_NONE;
269 } 277 }
270 278
279 file_browser_private::ChangeType ConvertChangeTypeFromDriveToApi(
280 drive::FileChange::ChangeType type) {
281 switch (type) {
282 case drive::FileChange::ADD_OR_UPDATE:
283 return file_browser_private::CHANGE_TYPE_ADD_OR_UPDATE;
284 case drive::FileChange::DELETE:
285 return file_browser_private::CHANGE_TYPE_DELETE;
286 }
287 NOTREACHED();
288 return file_browser_private::CHANGE_TYPE_ADD_OR_UPDATE;
289 }
290
271 std::string FileErrorToErrorName(base::File::Error error_code) { 291 std::string FileErrorToErrorName(base::File::Error error_code) {
272 namespace js = extensions::api::file_browser_private; 292 namespace js = extensions::api::file_browser_private;
273 switch (error_code) { 293 switch (error_code) {
274 case base::File::FILE_ERROR_NOT_FOUND: 294 case base::File::FILE_ERROR_NOT_FOUND:
275 return "NotFoundError"; 295 return "NotFoundError";
276 case base::File::FILE_ERROR_INVALID_OPERATION: 296 case base::File::FILE_ERROR_INVALID_OPERATION:
277 case base::File::FILE_ERROR_EXISTS: 297 case base::File::FILE_ERROR_EXISTS:
278 case base::File::FILE_ERROR_NOT_EMPTY: 298 case base::File::FILE_ERROR_NOT_EMPTY:
279 return "InvalidModificationError"; 299 return "InvalidModificationError";
280 case base::File::FILE_ERROR_NOT_A_DIRECTORY: 300 case base::File::FILE_ERROR_NOT_A_DIRECTORY:
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 484
465 if (is_on_drive) { 485 if (is_on_drive) {
466 // For Drive, file watching is done via OnDirectoryChanged(). 486 // For Drive, file watching is done via OnDirectoryChanged().
467 base::MessageLoopProxy::current()->PostTask(FROM_HERE, 487 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
468 base::Bind(callback, true)); 488 base::Bind(callback, true));
469 } else { 489 } else {
470 // For local files, start watching using FileWatcher. 490 // For local files, start watching using FileWatcher.
471 watcher->WatchLocalFile( 491 watcher->WatchLocalFile(
472 watch_path, 492 watch_path,
473 base::Bind(&EventRouter::HandleFileWatchNotification, 493 base::Bind(&EventRouter::HandleFileWatchNotification,
474 weak_factory_.GetWeakPtr()), 494 weak_factory_.GetWeakPtr(),
495 static_cast<drive::FileChange*>(NULL)),
475 callback); 496 callback);
476 } 497 }
477 498
478 file_watchers_[watch_path] = watcher.release(); 499 file_watchers_[watch_path] = watcher.release();
479 } else { 500 } else {
480 iter->second->AddExtension(extension_id); 501 iter->second->AddExtension(extension_id);
481 base::MessageLoopProxy::current()->PostTask(FROM_HERE, 502 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
482 base::Bind(callback, true)); 503 base::Bind(callback, true));
483 } 504 }
484 } 505 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 status.get()); 667 status.get());
647 status_list.push_back(status); 668 status_list.push_back(status);
648 } 669 }
649 BroadcastEvent( 670 BroadcastEvent(
650 profile_, 671 profile_,
651 file_browser_private::OnFileTransfersUpdated::kEventName, 672 file_browser_private::OnFileTransfersUpdated::kEventName,
652 file_browser_private::OnFileTransfersUpdated::Create(status_list)); 673 file_browser_private::OnFileTransfersUpdated::Create(status_list));
653 } 674 }
654 675
655 void EventRouter::OnDirectoryChanged(const base::FilePath& drive_path) { 676 void EventRouter::OnDirectoryChanged(const base::FilePath& drive_path) {
656 HandleFileWatchNotification(drive_path, false); 677 HandleFileWatchNotification(NULL, drive_path, false);
678 }
679
680 void EventRouter::OnFileChanged(const drive::FileChange& changed_files) {
681 typedef std::map<base::FilePath, drive::FileChange> FileChangeMap;
682
683 FileChangeMap map;
684 const drive::FileChange::Map& changed_file_map = changed_files.map();
685 for (drive::FileChange::Map::const_iterator it = changed_file_map.begin();
686 it != changed_file_map.end();
687 it++) {
688 const base::FilePath& path = it->first;
689 map[path.DirName()].Update(path, it->second);
690 }
691
692 for (FileChangeMap::const_iterator it = map.begin(); it != map.end(); it++) {
693 HandleFileWatchNotification(&(it->second), it->first, false);
694 }
657 } 695 }
658 696
659 void EventRouter::OnDriveSyncError(drive::file_system::DriveSyncErrorType type, 697 void EventRouter::OnDriveSyncError(drive::file_system::DriveSyncErrorType type,
660 const base::FilePath& drive_path) { 698 const base::FilePath& drive_path) {
661 file_browser_private::DriveSyncErrorEvent event; 699 file_browser_private::DriveSyncErrorEvent event;
662 switch (type) { 700 switch (type) {
663 case drive::file_system::DRIVE_SYNC_ERROR_DELETE_WITHOUT_PERMISSION: 701 case drive::file_system::DRIVE_SYNC_ERROR_DELETE_WITHOUT_PERMISSION:
664 event.type = 702 event.type =
665 file_browser_private::DRIVE_SYNC_ERROR_TYPE_DELETE_WITHOUT_PERMISSION; 703 file_browser_private::DRIVE_SYNC_ERROR_TYPE_DELETE_WITHOUT_PERMISSION;
666 break; 704 break;
(...skipping 17 matching lines...) Expand all
684 void EventRouter::OnRefreshTokenInvalid() { 722 void EventRouter::OnRefreshTokenInvalid() {
685 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
686 724
687 // Raise a DriveConnectionStatusChanged event to notify the status offline. 725 // Raise a DriveConnectionStatusChanged event to notify the status offline.
688 BroadcastEvent( 726 BroadcastEvent(
689 profile_, 727 profile_,
690 file_browser_private::OnDriveConnectionStatusChanged::kEventName, 728 file_browser_private::OnDriveConnectionStatusChanged::kEventName,
691 file_browser_private::OnDriveConnectionStatusChanged::Create()); 729 file_browser_private::OnDriveConnectionStatusChanged::Create());
692 } 730 }
693 731
694 void EventRouter::HandleFileWatchNotification(const base::FilePath& local_path, 732 void EventRouter::HandleFileWatchNotification(const drive::FileChange* list,
733 const base::FilePath& local_path,
695 bool got_error) { 734 bool got_error) {
696 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
697 736
698 WatcherMap::const_iterator iter = file_watchers_.find(local_path); 737 WatcherMap::const_iterator iter = file_watchers_.find(local_path);
699 if (iter == file_watchers_.end()) { 738 if (iter == file_watchers_.end()) {
700 return; 739 return;
701 } 740 }
702 DispatchDirectoryChangeEvent(iter->second->virtual_path(), got_error, 741
742 if (list && list->size() > kDirectoryChangeEventMaxDetailInfoSize) {
743 // Removes the detailed information, if the list size is more than
744 // kDirectoryChangeEventMaxDetailInfoSize, since passing large list
745 // and processing it may cause more itme.
746 // This will be invoked full-refresh in Files.app.
747 list = NULL;
748 }
749
750 DispatchDirectoryChangeEvent(iter->second->virtual_path(),
751 list,
752 got_error,
703 iter->second->GetExtensionIds()); 753 iter->second->GetExtensionIds());
704 } 754 }
705 755
706 void EventRouter::DispatchDirectoryChangeEvent( 756 void EventRouter::DispatchDirectoryChangeEvent(
707 const base::FilePath& virtual_path, 757 const base::FilePath& virtual_path,
758 const drive::FileChange* list,
708 bool got_error, 759 bool got_error,
709 const std::vector<std::string>& extension_ids) { 760 const std::vector<std::string>& extension_ids) {
710 if (!profile_) { 761 if (!profile_) {
711 NOTREACHED(); 762 NOTREACHED();
712 return; 763 return;
713 } 764 }
765 linked_ptr<drive::FileChange> changes;
766 if (list)
767 changes.reset(new drive::FileChange(*list)); // Copy
714 768
715 for (size_t i = 0; i < extension_ids.size(); ++i) { 769 for (size_t i = 0; i < extension_ids.size(); ++i) {
716 const std::string& extension_id = extension_ids[i]; 770 std::string* extension_id = new std::string(extension_ids[i]);
717 771
718 FileDefinition file_definition; 772 FileDefinition file_definition;
719 file_definition.virtual_path = virtual_path; 773 file_definition.virtual_path = virtual_path;
720 file_definition.is_directory = true; 774 file_definition.is_directory = true;
721 775
722 file_manager::util::ConvertFileDefinitionToEntryDefinition( 776 file_manager::util::ConvertFileDefinitionToEntryDefinition(
723 profile_, 777 profile_,
724 extension_id, 778 *extension_id,
725 file_definition, 779 file_definition,
726 base::Bind( 780 base::Bind(
727 &EventRouter::DispatchDirectoryChangeEventWithEntryDefinition, 781 &EventRouter::DispatchDirectoryChangeEventWithEntryDefinition,
728 weak_factory_.GetWeakPtr(), 782 weak_factory_.GetWeakPtr(),
783 changes,
784 base::Owned(extension_id),
729 got_error)); 785 got_error));
730 } 786 }
731 } 787 }
732 788
733 void EventRouter::DispatchDirectoryChangeEventWithEntryDefinition( 789 void EventRouter::DispatchDirectoryChangeEventWithEntryDefinition(
790 const linked_ptr<drive::FileChange> list,
791 const std::string* extension_id,
734 bool watcher_error, 792 bool watcher_error,
735 const EntryDefinition& entry_definition) { 793 const EntryDefinition& entry_definition) {
794 typedef std::map<base::FilePath, drive::FileChange::ChangeList> ChangeListMap;
795
736 if (entry_definition.error != base::File::FILE_OK || 796 if (entry_definition.error != base::File::FILE_OK ||
737 !entry_definition.is_directory) { 797 !entry_definition.is_directory) {
738 DVLOG(1) << "Unable to dispatch event because resolving the directory " 798 DVLOG(1) << "Unable to dispatch event because resolving the directory "
739 << "entry definition failed."; 799 << "entry definition failed.";
740 return; 800 return;
741 } 801 }
742 802
743 file_browser_private::FileWatchEvent event; 803 file_browser_private::FileWatchEvent event;
744 event.event_type = watcher_error 804 event.event_type = watcher_error
745 ? file_browser_private::FILE_WATCH_EVENT_TYPE_ERROR 805 ? file_browser_private::FILE_WATCH_EVENT_TYPE_ERROR
746 : file_browser_private::FILE_WATCH_EVENT_TYPE_CHANGED; 806 : file_browser_private::FILE_WATCH_EVENT_TYPE_CHANGED;
747 807
808 // Detailed information is available.
809 if (list.get()) {
810 event.changed_files.reset(
811 new std::vector<linked_ptr<file_browser_private::FileChange> >);
812
813 if (list->map().empty())
814 return;
815
816 for (drive::FileChange::Map::const_iterator it = list->map().begin();
817 it != list->map().end();
818 it++) {
819 linked_ptr<file_browser_private::FileChange> change_list(
820 new file_browser_private::FileChange);
821
822 GURL url = util::ConvertDrivePathToFileSystemUrl(
823 profile_, it->first, *extension_id);
824 change_list->url = url.spec();
825
826 for (drive::FileChange::ChangeList::List::const_iterator change =
827 it->second.list().begin();
828 change != it->second.list().end();
829 change++) {
830 change_list->changes.push_back(
831 ConvertChangeTypeFromDriveToApi(change->change()));
832 }
833
834 event.changed_files->push_back(change_list);
835 }
836 }
837
748 event.entry.additional_properties.SetString( 838 event.entry.additional_properties.SetString(
749 "fileSystemName", entry_definition.file_system_name); 839 "fileSystemName", entry_definition.file_system_name);
750 event.entry.additional_properties.SetString( 840 event.entry.additional_properties.SetString(
751 "fileSystemRoot", entry_definition.file_system_root_url); 841 "fileSystemRoot", entry_definition.file_system_root_url);
752 event.entry.additional_properties.SetString( 842 event.entry.additional_properties.SetString(
753 "fileFullPath", "/" + entry_definition.full_path.value()); 843 "fileFullPath", "/" + entry_definition.full_path.value());
754 event.entry.additional_properties.SetBoolean("fileIsDirectory", 844 event.entry.additional_properties.SetBoolean("fileIsDirectory",
755 entry_definition.is_directory); 845 entry_definition.is_directory);
756 846
757 BroadcastEvent(profile_, 847 BroadcastEvent(profile_,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 } 882 }
793 } 883 }
794 884
795 util::OpenRemovableDrive(profile_, mount_path); 885 util::OpenRemovableDrive(profile_, mount_path);
796 } 886 }
797 887
798 void EventRouter::DispatchDeviceEvent( 888 void EventRouter::DispatchDeviceEvent(
799 file_browser_private::DeviceEventType type, 889 file_browser_private::DeviceEventType type,
800 const std::string& device_path) { 890 const std::string& device_path) {
801 file_browser_private::DeviceEvent event; 891 file_browser_private::DeviceEvent event;
892
802 event.type = type; 893 event.type = type;
803 event.device_path = device_path; 894 event.device_path = device_path;
804 BroadcastEvent(profile_, 895 BroadcastEvent(profile_,
805 file_browser_private::OnDeviceChanged::kEventName, 896 file_browser_private::OnDeviceChanged::kEventName,
806 file_browser_private::OnDeviceChanged::Create(event)); 897 file_browser_private::OnDeviceChanged::Create(event));
807 } 898 }
808 899
809 void EventRouter::OnDiskAdded( 900 void EventRouter::OnDiskAdded(
810 const DiskMountManager::Disk& disk, bool mounting) { 901 const DiskMountManager::Disk& disk, bool mounting) {
811 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 902 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 } 1033 }
943 } 1034 }
944 1035
945 void EventRouter::OnOwnerEntryChanged(aura::Window* window) { 1036 void EventRouter::OnOwnerEntryChanged(aura::Window* window) {
946 BroadcastEvent(profile_, 1037 BroadcastEvent(profile_,
947 file_browser_private::OnDesktopChanged::kEventName, 1038 file_browser_private::OnDesktopChanged::kEventName,
948 file_browser_private::OnDesktopChanged::Create()); 1039 file_browser_private::OnDesktopChanged::Create());
949 } 1040 }
950 1041
951 } // namespace file_manager 1042 } // namespace file_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698