1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/system_storage/storage_info_provider.h"
7 #include "base/stl_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/sys_info.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "components/storage_monitor/storage_monitor.h"
12 #include "content/public/browser/browser_thread.h"
14 namespace extensions {
16 using content::BrowserThread;
17 using api::system_storage::StorageUnitInfo;
18 using api::system_storage::STORAGE_UNIT_TYPE_FIXED;
19 using api::system_storage::STORAGE_UNIT_TYPE_REMOVABLE;
21 namespace systeminfo {
23 void BuildStorageUnitInfo(const StorageInfo& info,
24 StorageUnitInfo* unit) {
25 unit->id = StorageMonitor::GetInstance()->GetTransientIdForDeviceId(
27 unit->name = base::UTF16ToUTF8(info.name());
28 // TODO(hmin): Might need to take MTP device into consideration.
29 unit->type = StorageInfo::IsRemovableDevice(info.device_id()) ?
30 STORAGE_UNIT_TYPE_REMOVABLE : STORAGE_UNIT_TYPE_FIXED;
31 unit->capacity = static_cast<double>(info.total_size_in_bytes());
34 } // namespace systeminfo
36 // Static member intialization.
37 base::LazyInstance<scoped_refptr<StorageInfoProvider> >
38 StorageInfoProvider::provider_ = LAZY_INSTANCE_INITIALIZER;
40 StorageInfoProvider::StorageInfoProvider() {
43 StorageInfoProvider::~StorageInfoProvider() {
46 const StorageUnitInfoList& StorageInfoProvider::storage_unit_info_list() const {
50 void StorageInfoProvider::InitializeForTesting(
51 scoped_refptr<StorageInfoProvider> provider) {
52 DCHECK(provider.get() != NULL);
53 provider_.Get() = provider;
56 void StorageInfoProvider::PrepareQueryOnUIThread() {
57 // Get all available storage devices before invoking |QueryInfo()|.
58 GetAllStoragesIntoInfoList();
61 void StorageInfoProvider::InitializeProvider(
62 const base::Closure& do_query_info_callback) {
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
64 // Register the |do_query_info_callback| callback to StorageMonitor.
65 // See the comments of StorageMonitor::EnsureInitialized about when the
67 StorageMonitor::GetInstance()->EnsureInitialized(do_query_info_callback);
70 bool StorageInfoProvider::QueryInfo() {
71 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
72 // No info to query since we get all available storage devices' info in
73 // |PrepareQueryOnUIThread()|.
77 void StorageInfoProvider::GetAllStoragesIntoInfoList() {
79 std::vector<StorageInfo> storage_list =
80 StorageMonitor::GetInstance()->GetAllAvailableStorages();
82 for (std::vector<StorageInfo>::const_iterator it = storage_list.begin();
83 it != storage_list.end(); ++it) {
84 linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
85 systeminfo::BuildStorageUnitInfo(*it, unit.get());
86 info_.push_back(unit);
90 double StorageInfoProvider::GetStorageFreeSpaceFromTransientIdOnFileThread(
91 const std::string& transient_id) {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
93 std::vector<StorageInfo> storage_list =
94 StorageMonitor::GetInstance()->GetAllAvailableStorages();
96 std::string device_id =
97 StorageMonitor::GetInstance()->GetDeviceIdForTransientId(
100 // Lookup the matched storage info by |device_id|.
101 for (std::vector<StorageInfo>::const_iterator it =
102 storage_list.begin();
103 it != storage_list.end(); ++it) {
104 if (device_id == it->device_id())
105 return static_cast<double>(base::SysInfo::AmountOfFreeDiskSpace(
106 base::FilePath(it->location())));
113 StorageInfoProvider* StorageInfoProvider::Get() {
114 if (provider_.Get().get() == NULL)
115 provider_.Get() = new StorageInfoProvider();
116 return provider_.Get();
119 } // namespace extensions