Home | History | Annotate | Download | only in system_storage
      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