chromium/ash/system/night_light/night_light_feature_pod_controller.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/night_light/night_light_feature_pod_controller.h"
#include <string>

#include "ash/constants/quick_settings_catalogs.h"
#include "ash/public/cpp/schedule_enums.h"
#include "ash/public/cpp/system_tray_client.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/model/clock_model.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/night_light/night_light_controller_impl.h"
#include "ash/system/tray/tray_popup_utils.h"
#include "ash/system/unified/feature_tile.h"
#include "ash/system/unified/quick_settings_metrics_util.h"
#include "ash/system/unified/unified_system_tray_controller.h"
#include "base/i18n/time_formatting.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "ui/base/l10n/l10n_util.h"

namespace ash {

NightLightFeaturePodController::NightLightFeaturePodController(
    UnifiedSystemTrayController* tray_controller)
    : tray_controller_(tray_controller) {
  Shell::Get()->system_tray_model()->clock()->AddObserver(this);
}

NightLightFeaturePodController::~NightLightFeaturePodController() {
  Shell::Get()->system_tray_model()->clock()->RemoveObserver(this);
}

std::unique_ptr<FeatureTile> NightLightFeaturePodController::CreateTile(
    bool compact) {
  DCHECK(!tile_);
  auto tile = std::make_unique<FeatureTile>(
      base::BindRepeating(&NightLightFeaturePodController::OnIconPressed,
                          weak_factory_.GetWeakPtr()),
      /*is_togglable=*/true);
  tile_ = tile.get();
  const bool visible = TrayPopupUtils::CanShowNightLightFeatureTile();
  tile_->SetVisible(visible);
  if (visible) {
    TrackVisibilityUMA();
  }

  tile_->SetLabel(
      l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_BUTTON_LABEL));
  UpdateTile();
  return tile;
}

QsFeatureCatalogName NightLightFeaturePodController::GetCatalogName() {
  return QsFeatureCatalogName::kNightLight;
}

void NightLightFeaturePodController::OnIconPressed() {
  TrackToggleUMA(/*target_toggle_state=*/!Shell::Get()
                     ->night_light_controller()
                     ->IsNightLightEnabled());

  Shell::Get()->night_light_controller()->Toggle();
  UpdateTile();

  if (Shell::Get()->night_light_controller()->IsNightLightEnabled()) {
    base::RecordAction(
        base::UserMetricsAction("StatusArea_NightLight_Enabled"));
  } else {
    base::RecordAction(
        base::UserMetricsAction("StatusArea_NightLight_Disabled"));
  }
}

void NightLightFeaturePodController::OnLabelPressed() {
  return;
}

void NightLightFeaturePodController::OnDateFormatChanged() {
  UpdateTile();
}

void NightLightFeaturePodController::OnSystemClockTimeUpdated() {
  UpdateTile();
}

void NightLightFeaturePodController::OnSystemClockCanSetTimeChanged(
    bool can_set_time) {
  UpdateTile();
}

void NightLightFeaturePodController::Refresh() {
  UpdateTile();
}

const std::u16string NightLightFeaturePodController::GetPodSubLabel() {
  auto* controller = Shell::Get()->night_light_controller();
  const bool is_enabled = controller->IsNightLightEnabled();
  const ScheduleType schedule_type = controller->GetScheduleType();
  std::u16string sublabel;
  switch (schedule_type) {
    case ScheduleType::kNone:
      return l10n_util::GetStringUTF16(
          is_enabled ? IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_ON_STATE
                     : IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_OFF_STATE);
    case ScheduleType::kSunsetToSunrise:
      return l10n_util::GetStringUTF16(
          is_enabled
              ? IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_ON_STATE_SUNSET_TO_SUNRISE_SCHEDULED
              : IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_OFF_STATE_SUNSET_TO_SUNRISE_SCHEDULED);
    case ScheduleType::kCustom:
      const TimeOfDay time_of_day = is_enabled
                                        ? controller->GetCustomEndTime()
                                        : controller->GetCustomStartTime();
      const std::optional<base::Time> time = time_of_day.ToTimeToday();
      if (!time) {
        return std::u16string();
      }
      const std::u16string time_str =
          base::TimeFormatTimeOfDayWithHourClockType(
              *time,
              Shell::Get()->system_tray_model()->clock()->hour_clock_type(),
              base::kKeepAmPm);
      return is_enabled
                 ? l10n_util::GetStringFUTF16(
                       IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_ON_STATE_CUSTOM_SCHEDULED,
                       time_str)
                 : l10n_util::GetStringFUTF16(
                       IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_OFF_STATE_CUSTOM_SCHEDULED,
                       time_str);
  }
}

void NightLightFeaturePodController::UpdateTile() {
  auto* controller = Shell::Get()->night_light_controller();
  const bool is_enabled = controller->IsNightLightEnabled();
  tile_->SetToggled(is_enabled);
  tile_->SetSubLabel(GetPodSubLabel());

  std::u16string tooltip_state = l10n_util::GetStringUTF16(
      is_enabled ? IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_ENABLED_STATE_TOOLTIP
                 : IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_DISABLED_STATE_TOOLTIP);
  tile_->SetTooltipText(l10n_util::GetStringFUTF16(
      IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_TOGGLE_TOOLTIP, tooltip_state));
  tile_->SetVectorIcon(is_enabled ? kUnifiedMenuNightLightIcon
                                  : kUnifiedMenuNightLightOffIcon);
}

}  // namespace ash