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

Unified Diff: chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc

Issue 10836341: Add the basic code skeleton for system info event router (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Refine the implementations for storage event. Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc
index 66a3ebb9dd4cbc5559d31af78cbe3f0f2acf7150..abc2f75621b10e572e0faa61b5e794f71f04b179 100644
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc
+++ b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
+#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
#include <windows.h>
-namespace extensions {
+#include "base/memory/linked_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/media_gallery/media_storage_util.h"
-namespace {
+namespace extensions {
using api::experimental_system_info_storage::StorageInfo;
using api::experimental_system_info_storage::StorageUnitInfo;
@@ -19,18 +19,15 @@ using api::experimental_system_info_storage::StorageUnitInfo;
// L":", L"\" and a terminating null character.
const unsigned long kMaxLogicalDriveString = 4 * 26;
-// StorageInfoProvider implementation on Windows platform.
-class StorageInfoProviderWin : public StorageInfoProvider {
- public:
- StorageInfoProviderWin() {}
- virtual ~StorageInfoProviderWin() {}
+StorageInfoProviderWin::StorageInfoProviderWin() {
+}
- virtual bool QueryInfo(StorageInfo* info) OVERRIDE;
- virtual bool QueryUnitInfo(const std::string& id,
- StorageUnitInfo* info) OVERRIDE;
-};
+StorageInfoProviderWin::~StorageInfoProviderWin() {
+}
bool StorageInfoProviderWin::QueryInfo(StorageInfo* info) {
+ if (info == NULL) return false;
+
info->units.clear();
WCHAR logical_drive_strings[kMaxLogicalDriveString];
@@ -44,23 +41,21 @@ bool StorageInfoProviderWin::QueryInfo(StorageInfo* info) {
if (string_length == 0)
return false;
- // Iterate the drive string by 4 wchars each step
for (unsigned int i = 0; i < string_length; i += 4) {
linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
- if (QueryUnitInfo(WideToUTF8(&logical_drive_strings[i]), unit.get())) {
+ if (QueryUnitInfo(&logical_drive_strings[i], unit.get())) {
info->units.push_back(unit);
}
}
return true;
}
-bool StorageInfoProviderWin::QueryUnitInfo(const std::string& id,
+bool StorageInfoProviderWin::QueryUnitInfo(const FilePath::StringType& path,
StorageUnitInfo* info) {
- DCHECK(info);
- string16 drive = UTF8ToUTF16(id);
+ if (info == NULL) return false;
std::string type;
- DWORD ret = GetDriveType(drive.c_str());
+ DWORD ret = GetDriveType(path.c_str());
switch (ret) {
case DRIVE_FIXED:
type = systeminfo::kStorageTypeHardDisk;
@@ -82,9 +77,14 @@ bool StorageInfoProviderWin::QueryUnitInfo(const std::string& id,
ULARGE_INTEGER total_bytes;
ULARGE_INTEGER free_bytes;
- if (GetDiskFreeSpaceEx(drive.c_str(), NULL, &total_bytes, &free_bytes)) {
- info->id = id;
+ if (GetDiskFreeSpaceEx(path.c_str(), &free_bytes, &total_bytes, NULL)) {
+ // TODO(hongbo) We need to look up the real device id instead of using
+ // path as a fallback name. Here we call MakeDeviceId to align with the
+ // id conventions used in media_gallery.
+ info->id = chrome::MediaStorageUtil::MakeDeviceId(
+ chrome::MediaStorageUtil::OTHER_MASS_STORAGE, UTF16ToUTF8(path));
info->type = type;
+ info->path = UTF16ToUTF8(path);
info->capacity = static_cast<double>(total_bytes.QuadPart);
info->available_capacity = static_cast<double>(free_bytes.QuadPart);
return true;
@@ -92,7 +92,82 @@ bool StorageInfoProviderWin::QueryUnitInfo(const std::string& id,
return false;
}
-} // namespace
+// TODO(hongbo): Need to consider storage device arrival/removal scenario
+// for PlatformStartWatching and PlatformStopWatching implementations.
+bool StorageInfoProviderWin::PlatformStartWatching(
+ StorageInfoProvider::Delegate* delegate) {
+ if (is_watching_) {
+ NOTREACHED() << "Already watching the storage info provider!";
+ return false;
+ }
+
+ StorageInfo info;
+ if (QueryInfo(&info)) {
+ std::vector<linked_ptr<StorageUnitInfo> >::const_iterator iter;
+ for (iter = info.units.begin(); iter != info.units.end(); ++iter) {
+ string16 drive = UTF8ToUTF16((*iter)->path);
+ HANDLE handle = FindFirstChangeNotification(drive.c_str(),
+ TRUE,
+ FILE_NOTIFY_CHANGE_SIZE);
+ linked_ptr<StorageWatcherEntry> entry(new StorageWatcherEntry);
+
+ if (entry->watcher.StartWatching(handle, this)) {
+ DLOG(INFO) << "Start watching: " << drive;
+ entry->path = drive;
+ storage_watchers_.insert(
+ std::pair<HANDLE, linked_ptr<StorageWatcherEntry> >(handle,
+ entry));
+ }
+ }
+ delegate_ = delegate;
+ is_watching_ = true;
+
+ base::SystemMonitor::Get()->AddDevicesChangedObserver(this);
+ return true;
+ }
+ return false;
+}
+
+bool StorageInfoProviderWin::PlatformStopWatching() {
+ if (!is_watching_) return false;
+
+ is_watching_ = false;
+ delegate_ = NULL;
+
+ for (StorageWatcherMap::iterator iter = storage_watchers_.begin();
+ iter != storage_watchers_.end();
+ ++iter) {
+ linked_ptr<StorageWatcherEntry> entry = iter->second;
+ entry->watcher.StopWatching();
+ }
+ storage_watchers_.clear();
+ base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this);
+
+ return true;
+}
+
+// TODO(hongbo): Since the OnObjectSignaled may be called frequently, e.g.
+// in case of unzip a package, we need to introduce an mechanism to control
+// its frequency, for example, using a timer to poll and wait to be signaled.
+void StorageInfoProviderWin::OnObjectSignaled(HANDLE object) {
+ StorageWatcherMap::iterator iter = storage_watchers_.find(object);
+ DCHECK(iter != storage_watchers_.end());
+
+ linked_ptr<StorageWatcherEntry> entry = iter->second;
+
+ StorageUnitInfo info;
+ if (QueryUnitInfo(entry->path, &info)) {
+ delegate_->OnStorageDeviceAvailableCapacityChanged(info.id,
+ info.available_capacity);
+ }
+ if (!FindNextChangeNotification(object)) {
+ NOTREACHED() << "FindNextChangeNotification failed: " << GetLastError();
+ return;
+ }
+
+ // Continue to watch the object.
+ entry->watcher.StartWatching(object, this);
+}
// static
StorageInfoProvider* StorageInfoProvider::Get() {

Powered by Google App Engine
This is Rietveld 408576698