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 "chrome/browser/extensions/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 "chrome/browser/storage_monitor/storage_monitor.h" 12 #include "content/public/browser/browser_thread.h" 13 14 namespace extensions { 15 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; 20 21 namespace systeminfo { 22 23 void BuildStorageUnitInfo(const StorageInfo& info, 24 StorageUnitInfo* unit) { 25 unit->id = StorageMonitor::GetInstance()->GetTransientIdForDeviceId( 26 info.device_id()); 27 unit->name = 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()); 32 } 33 34 } // namespace systeminfo 35 36 // Static member intialization. 37 base::LazyInstance<scoped_refptr<StorageInfoProvider> > 38 StorageInfoProvider::provider_ = LAZY_INSTANCE_INITIALIZER; 39 40 StorageInfoProvider::StorageInfoProvider() { 41 } 42 43 StorageInfoProvider::~StorageInfoProvider() { 44 } 45 46 const StorageUnitInfoList& StorageInfoProvider::storage_unit_info_list() const { 47 return info_; 48 } 49 50 void StorageInfoProvider::InitializeForTesting( 51 scoped_refptr<StorageInfoProvider> provider) { 52 DCHECK(provider.get() != NULL); 53 provider_.Get() = provider; 54 } 55 56 void StorageInfoProvider::PrepareQueryOnUIThread() { 57 // Get all available storage devices before invoking |QueryInfo()|. 58 GetAllStoragesIntoInfoList(); 59 } 60 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 66 // callback gets run. 67 StorageMonitor::GetInstance()->EnsureInitialized(do_query_info_callback); 68 } 69 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()|. 74 return true; 75 } 76 77 void StorageInfoProvider::GetAllStoragesIntoInfoList() { 78 info_.clear(); 79 std::vector<StorageInfo> storage_list = 80 StorageMonitor::GetInstance()->GetAllAvailableStorages(); 81 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); 87 } 88 } 89 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(); 95 96 std::string device_id = 97 StorageMonitor::GetInstance()->GetDeviceIdForTransientId( 98 transient_id); 99 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()))); 107 } 108 109 return -1; 110 } 111 112 // static 113 StorageInfoProvider* StorageInfoProvider::Get() { 114 if (provider_.Get().get() == NULL) 115 provider_.Get() = new StorageInfoProvider(); 116 return provider_.Get(); 117 } 118 119 } // namespace extensions 120