Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 | 86 |
| 87 // Frequency of sending onFileTransferUpdated. | 87 // Frequency of sending onFileTransferUpdated. |
| 88 const int64 kFileTransferEventFrequencyInMilliseconds = 1000; | 88 const int64 kFileTransferEventFrequencyInMilliseconds = 1000; |
| 89 | 89 |
| 90 // Utility function to check if |job_info| is a file uploading job. | 90 // Utility function to check if |job_info| is a file uploading job. |
| 91 bool IsUploadJob(drive::JobType type) { | 91 bool IsUploadJob(drive::JobType type) { |
| 92 return (type == drive::TYPE_UPLOAD_NEW_FILE || | 92 return (type == drive::TYPE_UPLOAD_NEW_FILE || |
| 93 type == drive::TYPE_UPLOAD_EXISTING_FILE); | 93 type == drive::TYPE_UPLOAD_EXISTING_FILE); |
| 94 } | 94 } |
| 95 | 95 |
| 96 // Converts the job info to its JSON (Value) form. | 96 // Converts the job info to its JSON (Value) form. |
|
mtomasz
2013/12/25 01:19:56
nit: Please update the comment.
hirono
2013/12/25 02:06:55
Done.
| |
| 97 scoped_ptr<base::DictionaryValue> JobInfoToDictionaryValue( | 97 void JobInfoToDictionaryValue( |
| 98 const std::string& extension_id, | 98 const std::string& extension_id, |
| 99 const std::string& job_status, | 99 const std::string& job_status, |
| 100 const drive::JobInfo& job_info) { | 100 const drive::JobInfo& job_info, |
| 101 file_browser_private::FileTransferStatus* status) { | |
| 101 DCHECK(IsActiveFileTransferJobInfo(job_info)); | 102 DCHECK(IsActiveFileTransferJobInfo(job_info)); |
| 102 | 103 |
| 103 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); | 104 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); |
| 104 GURL url = util::ConvertRelativeFilePathToFileSystemUrl( | 105 GURL url = util::ConvertRelativeFilePathToFileSystemUrl( |
| 105 job_info.file_path, extension_id); | 106 job_info.file_path, extension_id); |
| 106 result->SetString("fileUrl", url.spec()); | 107 status->file_url = url.spec(); |
| 107 result->SetString("transferState", job_status); | 108 status->transfer_state = file_browser_private::ParseTransferState(job_status); |
| 108 result->SetString("transferType", | 109 status->transfer_type = |
| 109 IsUploadJob(job_info.job_type) ? "upload" : "download"); | 110 IsUploadJob(job_info.job_type) ? |
| 111 file_browser_private::TRANSFER_TYPE_UPLOAD : | |
| 112 file_browser_private::TRANSFER_TYPE_DOWNLOAD; | |
| 110 // JavaScript does not have 64-bit integers. Instead we use double, which | 113 // JavaScript does not have 64-bit integers. Instead we use double, which |
| 111 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice | 114 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice |
| 112 // in C++. Larger values are rounded. | 115 // in C++. Larger values are rounded. |
| 113 result->SetDouble("processed", | 116 status->processed.reset( |
| 114 static_cast<double>(job_info.num_completed_bytes)); | 117 new double(static_cast<double>(job_info.num_completed_bytes))); |
| 115 result->SetDouble("total", static_cast<double>(job_info.num_total_bytes)); | 118 status->total.reset( |
| 116 return result.Pass(); | 119 new double(static_cast<double>(job_info.num_total_bytes))); |
| 117 } | 120 } |
| 118 | 121 |
| 119 // Checks for availability of the Google+ Photos app. | 122 // Checks for availability of the Google+ Photos app. |
| 120 bool IsGooglePhotosInstalled(Profile *profile) { | 123 bool IsGooglePhotosInstalled(Profile *profile) { |
| 121 ExtensionService* service = | 124 ExtensionService* service = |
| 122 extensions::ExtensionSystem::Get(profile)->extension_service(); | 125 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 123 if (!service) | 126 if (!service) |
| 124 return false; | 127 return false; |
| 125 | 128 |
| 126 // Google+ Photos uses several ids for different channels. Therefore, all of | 129 // Google+ Photos uses several ids for different channels. Therefore, all of |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 profile, volume_info, &event.volume_metadata); | 222 profile, volume_info, &event.volume_metadata); |
| 220 | 223 |
| 221 if (!volume_info.mount_path.empty() && | 224 if (!volume_info.mount_path.empty() && |
| 222 event.volume_metadata.mount_path.empty()) { | 225 event.volume_metadata.mount_path.empty()) { |
| 223 event.status = | 226 event.status = |
| 224 file_browser_private::MOUNT_COMPLETED_STATUS_ERROR_PATH_UNMOUNTED; | 227 file_browser_private::MOUNT_COMPLETED_STATUS_ERROR_PATH_UNMOUNTED; |
| 225 } | 228 } |
| 226 | 229 |
| 227 BroadcastEvent( | 230 BroadcastEvent( |
| 228 profile, | 231 profile, |
| 229 extensions::event_names::kOnFileBrowserMountCompleted, | 232 file_browser_private::OnMountCompleted::kEventName, |
| 230 file_browser_private::OnMountCompleted::Create(event)); | 233 file_browser_private::OnMountCompleted::Create(event)); |
| 231 } | 234 } |
| 232 | 235 |
| 233 file_browser_private::CopyProgressStatusType | 236 file_browser_private::CopyProgressStatusType |
| 234 CopyProgressTypeToCopyProgressStatusType( | 237 CopyProgressTypeToCopyProgressStatusType( |
| 235 fileapi::FileSystemOperation::CopyProgressType type) { | 238 fileapi::FileSystemOperation::CopyProgressType type) { |
| 236 switch (type) { | 239 switch (type) { |
| 237 case fileapi::FileSystemOperation::BEGIN_COPY_ENTRY: | 240 case fileapi::FileSystemOperation::BEGIN_COPY_ENTRY: |
| 238 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_BEGIN_COPY_ENTRY; | 241 return file_browser_private::COPY_PROGRESS_STATUS_TYPE_BEGIN_COPY_ENTRY; |
| 239 case fileapi::FileSystemOperation::END_COPY_ENTRY: | 242 case fileapi::FileSystemOperation::END_COPY_ENTRY: |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 422 status.destination_url.reset(new std::string(destination_url.spec())); | 425 status.destination_url.reset(new std::string(destination_url.spec())); |
| 423 } else { | 426 } else { |
| 424 // Send error event. | 427 // Send error event. |
| 425 status.type = file_browser_private::COPY_PROGRESS_STATUS_TYPE_ERROR; | 428 status.type = file_browser_private::COPY_PROGRESS_STATUS_TYPE_ERROR; |
| 426 status.error.reset( | 429 status.error.reset( |
| 427 new int(fileapi::PlatformFileErrorToWebFileError(error))); | 430 new int(fileapi::PlatformFileErrorToWebFileError(error))); |
| 428 } | 431 } |
| 429 | 432 |
| 430 BroadcastEvent( | 433 BroadcastEvent( |
| 431 profile_, | 434 profile_, |
| 432 extensions::event_names::kOnFileBrowserCopyProgress, | 435 file_browser_private::OnCopyProgress::kEventName, |
| 433 file_browser_private::OnCopyProgress::Create(copy_id, status)); | 436 file_browser_private::OnCopyProgress::Create(copy_id, status)); |
| 434 } | 437 } |
| 435 | 438 |
| 436 void EventRouter::OnCopyProgress( | 439 void EventRouter::OnCopyProgress( |
| 437 int copy_id, | 440 int copy_id, |
| 438 fileapi::FileSystemOperation::CopyProgressType type, | 441 fileapi::FileSystemOperation::CopyProgressType type, |
| 439 const GURL& source_url, | 442 const GURL& source_url, |
| 440 const GURL& destination_url, | 443 const GURL& destination_url, |
| 441 int64 size) { | 444 int64 size) { |
| 442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 443 | 446 |
| 444 file_browser_private::CopyProgressStatus status; | 447 file_browser_private::CopyProgressStatus status; |
| 445 status.type = CopyProgressTypeToCopyProgressStatusType(type); | 448 status.type = CopyProgressTypeToCopyProgressStatusType(type); |
| 446 status.source_url.reset(new std::string(source_url.spec())); | 449 status.source_url.reset(new std::string(source_url.spec())); |
| 447 if (type == fileapi::FileSystemOperation::END_COPY_ENTRY) | 450 if (type == fileapi::FileSystemOperation::END_COPY_ENTRY) |
| 448 status.destination_url.reset(new std::string(destination_url.spec())); | 451 status.destination_url.reset(new std::string(destination_url.spec())); |
| 449 if (type == fileapi::FileSystemOperation::PROGRESS) | 452 if (type == fileapi::FileSystemOperation::PROGRESS) |
| 450 status.size.reset(new double(size)); | 453 status.size.reset(new double(size)); |
| 451 | 454 |
| 452 BroadcastEvent( | 455 BroadcastEvent( |
| 453 profile_, | 456 profile_, |
| 454 extensions::event_names::kOnFileBrowserCopyProgress, | 457 file_browser_private::OnCopyProgress::kEventName, |
| 455 file_browser_private::OnCopyProgress::Create(copy_id, status)); | 458 file_browser_private::OnCopyProgress::Create(copy_id, status)); |
| 456 } | 459 } |
| 457 | 460 |
| 458 void EventRouter::DefaultNetworkChanged(const chromeos::NetworkState* network) { | 461 void EventRouter::DefaultNetworkChanged(const chromeos::NetworkState* network) { |
| 459 if (!profile_ || | 462 if (!profile_ || |
| 460 !extensions::ExtensionSystem::Get(profile_)->event_router()) { | 463 !extensions::ExtensionSystem::Get(profile_)->event_router()) { |
| 461 NOTREACHED(); | 464 NOTREACHED(); |
| 462 return; | 465 return; |
| 463 } | 466 } |
| 464 | 467 |
| 465 BroadcastEvent( | 468 BroadcastEvent( |
| 466 profile_, | 469 profile_, |
| 467 extensions::event_names::kOnFileBrowserDriveConnectionStatusChanged, | 470 file_browser_private::OnDriveConnectionStatusChanged::kEventName, |
| 468 make_scoped_ptr(new base::ListValue)); | 471 file_browser_private::OnDriveConnectionStatusChanged::Create()); |
| 469 } | 472 } |
| 470 | 473 |
| 471 void EventRouter::OnFileManagerPrefsChanged() { | 474 void EventRouter::OnFileManagerPrefsChanged() { |
| 472 if (!profile_ || | 475 if (!profile_ || |
| 473 !extensions::ExtensionSystem::Get(profile_)->event_router()) { | 476 !extensions::ExtensionSystem::Get(profile_)->event_router()) { |
| 474 NOTREACHED(); | 477 NOTREACHED(); |
| 475 return; | 478 return; |
| 476 } | 479 } |
| 477 | 480 |
| 478 BroadcastEvent( | 481 BroadcastEvent( |
| 479 profile_, | 482 profile_, |
| 480 extensions::event_names::kOnFileBrowserPreferencesChanged, | 483 file_browser_private::OnPreferencesChanged::kEventName, |
| 481 make_scoped_ptr(new base::ListValue)); | 484 file_browser_private::OnPreferencesChanged::Create()); |
| 482 } | 485 } |
| 483 | 486 |
| 484 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { | 487 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { |
| 485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 488 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 486 OnJobUpdated(job_info); | 489 OnJobUpdated(job_info); |
| 487 } | 490 } |
| 488 | 491 |
| 489 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { | 492 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { |
| 490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 491 if (!drive::IsActiveFileTransferJobInfo(job_info)) | 494 if (!drive::IsActiveFileTransferJobInfo(job_info)) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 // amount of time passes after the previous one. This is to avoid | 535 // amount of time passes after the previous one. This is to avoid |
| 533 // flooding the IPC between extensions by many onFileTransferUpdated events. | 536 // flooding the IPC between extensions by many onFileTransferUpdated events. |
| 534 if (!always) { | 537 if (!always) { |
| 535 const int64 delta = (now - last_file_transfer_event_).InMilliseconds(); | 538 const int64 delta = (now - last_file_transfer_event_).InMilliseconds(); |
| 536 // delta < 0 may rarely happen if system clock is synced and rewinded. | 539 // delta < 0 may rarely happen if system clock is synced and rewinded. |
| 537 // To be conservative, we don't skip in that case. | 540 // To be conservative, we don't skip in that case. |
| 538 if (0 <= delta && delta < kFileTransferEventFrequencyInMilliseconds) | 541 if (0 <= delta && delta < kFileTransferEventFrequencyInMilliseconds) |
| 539 return; | 542 return; |
| 540 } | 543 } |
| 541 | 544 |
| 542 // Convert the current |drive_jobs_| to a JSON value. | 545 // Convert the current |drive_jobs_| to IDL type. |
| 543 scoped_ptr<base::ListValue> event_list(new base::ListValue); | 546 std::vector<linked_ptr<file_browser_private::FileTransferStatus> > |
|
mtomasz
2013/12/25 01:19:56
How about ScopedVector?
https://groups.google.com
hirono
2013/12/25 02:06:55
Because IDL generated methods takes std::vector<li
| |
| 547 status_list; | |
| 548 status_list.resize(drive_jobs_.size()); | |
| 549 size_t i = 0; | |
| 544 for (std::map<drive::JobID, DriveJobInfoWithStatus>::iterator | 550 for (std::map<drive::JobID, DriveJobInfoWithStatus>::iterator |
| 545 iter = drive_jobs_.begin(); iter != drive_jobs_.end(); ++iter) { | 551 iter = drive_jobs_.begin(); iter != drive_jobs_.end(); ++iter) { |
| 546 | 552 JobInfoToDictionaryValue(kFileManagerAppId, |
| 547 scoped_ptr<base::DictionaryValue> job_info_dict( | 553 iter->second.status, |
| 548 JobInfoToDictionaryValue(kFileManagerAppId, | 554 iter->second.job_info, |
| 549 iter->second.status, | 555 status_list[i++].get()); |
| 550 iter->second.job_info)); | |
| 551 event_list->Append(job_info_dict.release()); | |
| 552 } | 556 } |
| 553 | 557 |
| 554 scoped_ptr<base::ListValue> args(new base::ListValue()); | 558 BroadcastEvent( |
| 555 args->Append(event_list.release()); | 559 profile_, |
| 556 scoped_ptr<extensions::Event> event(new extensions::Event( | 560 file_browser_private::OnFileTransfersUpdated::kEventName, |
| 557 extensions::event_names::kOnFileTransfersUpdated, args.Pass())); | 561 file_browser_private::OnFileTransfersUpdated::Create(status_list)); |
| 558 extensions::ExtensionSystem::Get(profile_)->event_router()-> | |
| 559 DispatchEventToExtension(kFileManagerAppId, event.Pass()); | |
| 560 | |
| 561 last_file_transfer_event_ = now; | 562 last_file_transfer_event_ = now; |
| 562 } | 563 } |
| 563 | 564 |
| 564 void EventRouter::OnDirectoryChanged(const base::FilePath& directory_path) { | 565 void EventRouter::OnDirectoryChanged(const base::FilePath& directory_path) { |
| 565 HandleFileWatchNotification(directory_path, false); | 566 HandleFileWatchNotification(directory_path, false); |
| 566 } | 567 } |
| 567 | 568 |
| 568 void EventRouter::OnRefreshTokenInvalid() { | 569 void EventRouter::OnRefreshTokenInvalid() { |
| 569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 570 | 571 |
| 571 // Raise a DriveConnectionStatusChanged event to notify the status offline. | 572 // Raise a DriveConnectionStatusChanged event to notify the status offline. |
| 572 BroadcastEvent( | 573 BroadcastEvent( |
| 573 profile_, | 574 profile_, |
| 574 extensions::event_names::kOnFileBrowserDriveConnectionStatusChanged, | 575 file_browser_private::OnDriveConnectionStatusChanged::kEventName, |
| 575 make_scoped_ptr(new base::ListValue)); | 576 file_browser_private::OnDriveConnectionStatusChanged::Create()); |
| 576 } | 577 } |
| 577 | 578 |
| 578 void EventRouter::HandleFileWatchNotification(const base::FilePath& local_path, | 579 void EventRouter::HandleFileWatchNotification(const base::FilePath& local_path, |
| 579 bool got_error) { | 580 bool got_error) { |
| 580 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 581 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 581 | 582 |
| 582 WatcherMap::const_iterator iter = file_watchers_.find(local_path); | 583 WatcherMap::const_iterator iter = file_watchers_.find(local_path); |
| 583 if (iter == file_watchers_.end()) { | 584 if (iter == file_watchers_.end()) { |
| 584 return; | 585 return; |
| 585 } | 586 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 609 fileapi::FileSystemInfo info = | 610 fileapi::FileSystemInfo info = |
| 610 fileapi::GetFileSystemInfoForChromeOS(target_origin_url.GetOrigin()); | 611 fileapi::GetFileSystemInfoForChromeOS(target_origin_url.GetOrigin()); |
| 611 base::DictionaryValue* entry = new base::DictionaryValue(); | 612 base::DictionaryValue* entry = new base::DictionaryValue(); |
| 612 entry->SetString("fileSystemName", info.name); | 613 entry->SetString("fileSystemName", info.name); |
| 613 entry->SetString("fileSystemRoot", info.root_url.spec()); | 614 entry->SetString("fileSystemRoot", info.root_url.spec()); |
| 614 entry->SetString("fileFullPath", "/" + virtual_path.value()); | 615 entry->SetString("fileFullPath", "/" + virtual_path.value()); |
| 615 entry->SetBoolean("fileIsDirectory", true); | 616 entry->SetBoolean("fileIsDirectory", true); |
| 616 watch_info->Set("entry", entry); | 617 watch_info->Set("entry", entry); |
| 617 watch_info->SetString("eventType", | 618 watch_info->SetString("eventType", |
| 618 got_error ? kPathWatchError : kPathChanged); | 619 got_error ? kPathWatchError : kPathChanged); |
| 619 scoped_ptr<extensions::Event> event(new extensions::Event( | 620 BroadcastEvent( |
| 620 extensions::event_names::kOnDirectoryChanged, args.Pass())); | 621 profile_, |
| 621 extensions::ExtensionSystem::Get(profile_)->event_router()-> | 622 file_browser_private::OnDirectoryChanged::kEventName, |
| 622 DispatchEventToExtension(extension_id, event.Pass()); | 623 args.Pass()); |
| 623 } | 624 } |
| 624 } | 625 } |
| 625 | 626 |
| 626 void EventRouter::ShowRemovableDeviceInFileManager( | 627 void EventRouter::ShowRemovableDeviceInFileManager( |
| 627 const base::FilePath& mount_path) { | 628 const base::FilePath& mount_path) { |
| 628 // Do not attempt to open File Manager while the login is in progress or | 629 // Do not attempt to open File Manager while the login is in progress or |
| 629 // the screen is locked. | 630 // the screen is locked. |
| 630 if (chromeos::LoginDisplayHostImpl::default_host() || | 631 if (chromeos::LoginDisplayHostImpl::default_host() || |
| 631 chromeos::ScreenLocker::default_screen_locker()) | 632 chromeos::ScreenLocker::default_screen_locker()) |
| 632 return; | 633 return; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 761 base::TimeDelta::FromSeconds(4)); | 762 base::TimeDelta::FromSeconds(4)); |
| 762 } else { | 763 } else { |
| 763 notifications_->HideNotification(DesktopNotifications::FORMAT_START, | 764 notifications_->HideNotification(DesktopNotifications::FORMAT_START, |
| 764 device_path); | 765 device_path); |
| 765 notifications_->ShowNotification(DesktopNotifications::FORMAT_FAIL, | 766 notifications_->ShowNotification(DesktopNotifications::FORMAT_FAIL, |
| 766 device_path); | 767 device_path); |
| 767 } | 768 } |
| 768 } | 769 } |
| 769 | 770 |
| 770 } // namespace file_manager | 771 } // namespace file_manager |
| OLD | NEW |