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. 4 5 #include "extensions/browser/api/system_storage/storage_info_provider.h" 6 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_info.h" 12 #include "components/storage_monitor/storage_monitor.h" 13 #include "content/public/browser/browser_thread.h" 14 15 using storage_monitor::StorageInfo; 16 using storage_monitor::StorageMonitor; 17 18 namespace extensions { 19 20 using content::BrowserThread; 21 using core_api::system_storage::StorageUnitInfo; 22 using core_api::system_storage::STORAGE_UNIT_TYPE_FIXED; 23 using core_api::system_storage::STORAGE_UNIT_TYPE_REMOVABLE; 24 25 namespace systeminfo { 26 27 void BuildStorageUnitInfo(const StorageInfo& info, StorageUnitInfo* unit) { 28 unit->id = StorageMonitor::GetInstance()->GetTransientIdForDeviceId( 29 info.device_id()); 30 unit->name = base::UTF16ToUTF8(info.GetDisplayName(false)); 31 // TODO(hmin): Might need to take MTP device into consideration. 32 unit->type = StorageInfo::IsRemovableDevice(info.device_id()) 33 ? STORAGE_UNIT_TYPE_REMOVABLE 34 : STORAGE_UNIT_TYPE_FIXED; 35 unit->capacity = static_cast<double>(info.total_size_in_bytes()); 36 } 37 38 } // namespace systeminfo 39 40 // Static member intialization. 41 base::LazyInstance<scoped_refptr<StorageInfoProvider> > 42 StorageInfoProvider::provider_ = LAZY_INSTANCE_INITIALIZER; 43 44 StorageInfoProvider::StorageInfoProvider() { 45 } 46 47 StorageInfoProvider::~StorageInfoProvider() { 48 } 49 50 const StorageUnitInfoList& StorageInfoProvider::storage_unit_info_list() const { 51 return info_; 52 } 53 54 void StorageInfoProvider::InitializeForTesting( 55 scoped_refptr<StorageInfoProvider> provider) { 56 DCHECK(provider.get() != NULL); 57 provider_.Get() = provider; 58 } 59 60 void StorageInfoProvider::PrepareQueryOnUIThread() { 61 // Get all available storage devices before invoking |QueryInfo()|. 62 GetAllStoragesIntoInfoList(); 63 } 64 65 void StorageInfoProvider::InitializeProvider( 66 const base::Closure& do_query_info_callback) { 67 DCHECK_CURRENTLY_ON(BrowserThread::UI); 68 // Register the |do_query_info_callback| callback to StorageMonitor. 69 // See the comments of StorageMonitor::EnsureInitialized about when the 70 // callback gets run. 71 StorageMonitor::GetInstance()->EnsureInitialized(do_query_info_callback); 72 } 73 74 bool StorageInfoProvider::QueryInfo() { 75 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 76 // No info to query since we get all available storage devices' info in 77 // |PrepareQueryOnUIThread()|. 78 return true; 79 } 80 81 void StorageInfoProvider::GetAllStoragesIntoInfoList() { 82 info_.clear(); 83 std::vector<StorageInfo> storage_list = 84 StorageMonitor::GetInstance()->GetAllAvailableStorages(); 85 86 for (std::vector<StorageInfo>::const_iterator it = storage_list.begin(); 87 it != storage_list.end(); 88 ++it) { 89 linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo()); 90 systeminfo::BuildStorageUnitInfo(*it, unit.get()); 91 info_.push_back(unit); 92 } 93 } 94 95 double StorageInfoProvider::GetStorageFreeSpaceFromTransientIdOnFileThread( 96 const std::string& transient_id) { 97 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 98 std::vector<StorageInfo> storage_list = 99 StorageMonitor::GetInstance()->GetAllAvailableStorages(); 100 101 std::string device_id = 102 StorageMonitor::GetInstance()->GetDeviceIdForTransientId(transient_id); 103 104 // Lookup the matched storage info by |device_id|. 105 for (std::vector<StorageInfo>::const_iterator it = storage_list.begin(); 106 it != storage_list.end(); 107 ++it) { 108 if (device_id == it->device_id()) 109 return static_cast<double>( 110 base::SysInfo::AmountOfFreeDiskSpace(base::FilePath(it->location()))); 111 } 112 113 return -1; 114 } 115 116 // static 117 StorageInfoProvider* StorageInfoProvider::Get() { 118 if (provider_.Get().get() == NULL) 119 provider_.Get() = new StorageInfoProvider(); 120 return provider_.Get().get(); 121 } 122 123 } // namespace extensions 124