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 "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