text: // Copyright 2016 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
  #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
  
  #include <string>
  
  #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
  #include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h"
  #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
  #include "chromeos/disks/disk_mount_manager.h"
  #include "third_party/re2/src/re2/re2.h"
  
  class Profile;
  
  namespace content {
  class WebUIDataSource;
  }  // namespace content
  
  namespace crostini {
  enum class CrostiniResult;
  }  // namespace crostini
  
  namespace chromeos {
  namespace settings {
  
  // Enumeration for device state about remaining space. These values must be
  // kept in sync with settings.StorageSpaceState in JS code.
  enum class StorageSpaceState {
    kStorageSpaceNormal = 0,
    kStorageSpaceLow = 1,
    kStorageSpaceCriticallyLow = 2,
  };
  
  // Threshold to show a message indicating space is critically low (512 MB).
  const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024;
  
  // Threshold to show a message indicating space is low (1 GB).
  const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024;
  
  class StorageHandler : public ::settings::SettingsPageUIHandler,
                         public arc::ArcSessionManager::Observer,
                         public chromeos::disks::DiskMountManager::Observer,
                         public calculator::SizeCalculator::Observer {
   public:
    StorageHandler(Profile* profile, content::WebUIDataSource* html_source);
    ~StorageHandler() override;
  
    // ::settings::SettingsPageUIHandler:
    void RegisterMessages() override;
    void OnJavascriptAllowed() override;
    void OnJavascriptDisallowed() override;
  
    // arc::ArcSessionManager::Observer:
    void OnArcPlayStoreEnabledChanged(bool enabled) override;
  
    // chromeos::disks::DiskMountManager::Observer:
    void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event,
                      chromeos::MountError error_code,
                      const chromeos::disks::DiskMountManager::MountPointInfo&
                          mount_info) override;
  
    // chromeos::settings::calculator::SizeCalculator::Observer:
    void OnSizeCalculated(
        const calculator::SizeCalculator::CalculationType& calculation_type,
        int64_t total_bytes,
        const base::Optional<int64_t>& available_bytes = base::nullopt) override;
  
    // Remove the handler from the list of observers of every observed instances.
    void StopObservingEvents();
  
   protected:
    // Round a given number of bytes up to the next power of 2.
    // Ex: 14 => 16, 150 => 256.
    int64_t RoundByteSize(int64_t bytes);
  
   private:
    // Handlers of JS messages.
    void HandleUpdateAndroidEnabled(const base::ListValue* unused_args);
    void HandleUpdateStorageInfo(const base::ListValue* unused_args);
    void HandleOpenMyFiles(const base::ListValue* unused_args);
    void HandleOpenArcStorage(const base::ListValue* unused_args);
    void HandleUpdateExternalStorages(const base::ListValue* unused_args);
  
    // Update storage sizes on the UI.
    void UpdateStorageItem(
        const calculator::SizeCalculator::CalculationType& calculation_type,
        int64_t total_bytes);
    void UpdateSizeStat(
        const calculator::SizeCalculator::CalculationType& calculation_type,
        int64_t total_bytes,
        int64_t available_bytes);
  
    // Marks the size of |item| as calculated. When all storage items have been
    // calculated, then "System" size can be calculated.
    void UpdateSystemSize(
        const calculator::SizeCalculator::CalculationType& calculation_type,
        int64_t total_bytes);
  
    // Updates list of external storages.
    void UpdateExternalStorages();
  
    // Returns true if the volume from |source_path| can be used as Android
    // storage.
    bool IsEligibleForAndroidStorage(std::string source_path);
  
    // Instances calculating the size of each storage items.
    calculator::SizeStatCalculator size_stat_calculator_;
    calculator::MyFilesSizeCalculator my_files_size_calculator_;
    calculator::BrowsingDataSizeCalculator browsing_data_size_calculator_;
    calculator::AppsSizeCalculator apps_size_calculator_;
    calculator::CrostiniSizeCalculator crostini_size_calculator_;
    calculator::OtherUsersSizeCalculator other_users_size_calculator_;
  
    // Controls if the size of each storage item has been calculated.
    std::bitset<calculator::SizeCalculator::kCalculationTypeCount>
        calculation_state_;
  
    // Keeps track of the size of each storage item.
    int64_t storage_items_total_bytes_
        [calculator::SizeCalculator::kCalculationTypeCount] = {0};
  
    Profile* const profile_;
    const std::string source_name_;
    ScopedObserver<arc::ArcSessionManager, arc::ArcSessionManager::Observer>
        arc_observer_;
    const re2::RE2 special_volume_path_pattern_;
  
    base::WeakPtrFactory<StorageHandler> weak_ptr_factory_{this};
  
    DISALLOW_COPY_AND_ASSIGN(StorageHandler);
  };
  
  }  // namespace settings
  }  // namespace chromeos
  
  #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
  