Add year to the month label

If the month view is not in the current year, a year label is added to
the month label.

Also fixed the color of the label text.

Bug: 1236276

Change-Id: Ic619fb85913101a1ce0817e865e8c723553ac61c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3169825
Commit-Queue: Jiaming Cheng <jiamingc@chromium.org>
Reviewed-by: Alex Newcomer <newcomer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#923031}
diff --git a/ash/system/time/calendar_view.cc b/ash/system/time/calendar_view.cc
index 7b458965..e69647f 100644
--- a/ash/system/time/calendar_view.cc
+++ b/ash/system/time/calendar_view.cc
@@ -67,6 +67,7 @@
  public:
   explicit CalendarLabel(const std::u16string& text) : views::Label(text) {
     views::Label::SetEnabledColor(calendar_utils::GetPrimaryTextColor());
+    views::Label::SetAutoColorReadabilityEnabled(false);
   }
   CalendarLabel(const CalendarLabel&) = delete;
   CalendarLabel& operator=(const CalendarLabel&) = delete;
@@ -111,6 +112,77 @@
 
 }  // namespace
 
+// The label for each month.
+class CalendarView::MonthYearHeaderView : public views::View {
+ public:
+  MonthYearHeaderView(LabelType type,
+                      CalendarViewController* calendar_view_controller)
+      : month_label_(AddChildView(std::make_unique<views::Label>())) {
+    switch (type) {
+      case PREVIOUS:
+        date_ = calendar_view_controller->GetPreviousMonthFirstDay();
+        month_name_ = calendar_view_controller->GetPreviousMonthName();
+        break;
+      case CURRENT:
+        date_ = calendar_view_controller->GetOnScreenMonthFirstDay();
+        month_name_ = calendar_view_controller->GetOnScreenMonthName();
+        break;
+      case NEXT:
+        date_ = calendar_view_controller->GetNextMonthFirstDay();
+        month_name_ = calendar_view_controller->GetNextMonthName();
+        break;
+    }
+    SetLayoutManager(std::make_unique<views::BoxLayout>(
+        views::BoxLayout::Orientation::kHorizontal));
+
+    month_label_->SetText(month_name_);
+    SetupLabel(month_label_);
+    month_label_->SetBorder(
+        views::CreateEmptyBorder(gfx::Insets(kLabelVerticalPadding, 0)));
+
+    if (calendar_utils::GetExploded(date_).year !=
+        calendar_utils::GetExploded(base::Time::Now()).year) {
+      year_label_ = AddChildView(std::make_unique<views::Label>());
+      year_label_->SetText(base::UTF8ToUTF16(
+          base::NumberToString(calendar_utils::GetExploded(date_).year)));
+      SetupLabel(year_label_);
+      year_label_->SetBorder(views::CreateEmptyBorder(
+          gfx::Insets(kLabelVerticalPadding, kLabelTextInBetweenPadding)));
+    }
+  }
+  MonthYearHeaderView(const MonthYearHeaderView&) = delete;
+  MonthYearHeaderView& operator=(const MonthYearHeaderView&) = delete;
+  ~MonthYearHeaderView() override = default;
+
+  // views::View:
+  void OnThemeChanged() override {
+    views::View::OnThemeChanged();
+
+    month_label_->SetEnabledColor(calendar_utils::GetPrimaryTextColor());
+    if (year_label_)
+      year_label_->SetEnabledColor(calendar_utils::GetSecondaryTextColor());
+  }
+
+  void SetupLabel(views::Label* label) {
+    label->SetTextContext(CONTEXT_CALENDAR_LABEL);
+    label->SetAutoColorReadabilityEnabled(false);
+    label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_TO_HEAD);
+  }
+
+ private:
+  // This `date_`'s month and year is used to create this view.
+  base::Time date_;
+
+  // The name of the `date_` month.
+  std::u16string month_name_;
+
+  // The month label in the view.
+  views::Label* const month_label_ = nullptr;
+
+  // The year label in the view.
+  views::Label* year_label_ = nullptr;
+};
+
 CalendarView::CalendarView(DetailedViewDelegate* delegate,
                            UnifiedSystemTrayController* controller,
                            CalendarViewController* calendar_view_controller)
@@ -123,6 +195,7 @@
   header_ = TrayPopupUtils::CreateDefaultLabel();
   header_->SetText(calendar_view_controller_->GetOnScreenMonthName());
   header_->SetTextContext(CONTEXT_CALENDAR_LABEL);
+  header_->SetAutoColorReadabilityEnabled(false);
   header_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_TO_HEAD);
 
   header_year_ = TrayPopupUtils::CreateDefaultLabel();
@@ -130,9 +203,10 @@
       calendar_utils::GetExploded(
           calendar_view_controller_->GetOnScreenMonthFirstDay())
           .year)));
-  header_year_->SetBorder(
-      views::CreateEmptyBorder(0, kLabelTextInBetweenPadding, 0, 0));
+  header_year_->SetBorder(views::CreateEmptyBorder(
+      0, kLabelTextInBetweenPadding, 0, kLabelTextInBetweenPadding));
   header_year_->SetTextContext(CONTEXT_CALENDAR_LABEL);
+  header_->SetAutoColorReadabilityEnabled(false);
   header_year_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_TO_HEAD);
 
   TriView* tri_view = TrayPopupUtils::CreateDefaultRowView();
@@ -213,17 +287,15 @@
 }
 
 void CalendarView::SetMonthViews() {
-  previous_label_ =
-      AddLabelWithId(calendar_view_controller_->GetPreviousMonthName());
+  previous_label_ = AddLabelWithId(LabelType::PREVIOUS);
   previous_month_ =
       AddMonth(calendar_view_controller_->GetPreviousMonthFirstDay());
 
-  current_label_ =
-      AddLabelWithId(calendar_view_controller_->GetOnScreenMonthName());
+  current_label_ = AddLabelWithId(LabelType::CURRENT);
   current_month_ =
       AddMonth(calendar_view_controller_->GetOnScreenMonthFirstDay());
 
-  next_label_ = AddLabelWithId(calendar_view_controller_->GetNextMonthName());
+  next_label_ = AddLabelWithId(LabelType::NEXT);
   next_month_ = AddMonth(calendar_view_controller_->GetNextMonthFirstDay());
 }
 
@@ -299,13 +371,9 @@
   ScrollToToday();
 }
 
-views::Label* CalendarView::AddLabelWithId(std::u16string label_string,
-                                           bool add_at_front) {
-  auto label = std::make_unique<CalendarLabel>(label_string);
-  label->SetBorder(views::CreateEmptyBorder(kLabelVerticalPadding, 0,
-                                            kLabelVerticalPadding, 0));
-  label->SetTextContext(CONTEXT_CALENDAR_LABEL);
-  label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_TO_HEAD);
+views::View* CalendarView::AddLabelWithId(LabelType type, bool add_at_front) {
+  auto label =
+      std::make_unique<MonthYearHeaderView>(type, calendar_view_controller_);
   if (add_at_front)
     return content_view_->AddChildViewAt(std::move(label), 0);
   return content_view_->AddChildView(std::move(label));
@@ -365,9 +433,8 @@
   previous_month_ =
       AddMonth(calendar_view_controller_->GetPreviousMonthFirstDay(),
                /*add_at_front=*/true);
-  previous_label_ =
-      AddLabelWithId(calendar_view_controller_->GetPreviousMonthName(),
-                     /*add_at_front=*/true);
+  previous_label_ = AddLabelWithId(LabelType::PREVIOUS,
+                                   /*add_at_front=*/true);
 
   // After adding a new month in the content, the current position stays the
   // same but below the added view the each view's position has changed to
@@ -399,7 +466,7 @@
   current_label_ = next_label_;
   current_month_ = next_month_;
 
-  next_label_ = AddLabelWithId(calendar_view_controller_->GetNextMonthName());
+  next_label_ = AddLabelWithId(LabelType::NEXT);
   next_month_ = AddMonth(calendar_view_controller_->GetNextMonthFirstDay());
 
   // Same as adding previous views. We need to remove the height of the
diff --git a/ash/system/time/calendar_view.h b/ash/system/time/calendar_view.h
index 6a377e0..fb3780f 100644
--- a/ash/system/time/calendar_view.h
+++ b/ash/system/time/calendar_view.h
@@ -11,6 +11,7 @@
 #include "ash/system/unified/unified_system_tray_controller.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/controls/scroll_view.h"
+#include "ui/views/view.h"
 
 namespace views {
 
@@ -55,6 +56,15 @@
                                   int info_accessible_name_id) override;
 
  private:
+  // The header of each month view which shows the month's name. If the year of
+  // this month is not the same as the current month, the year is also shown in
+  // this view.
+  class MonthYearHeaderView;
+
+  // The types to create the `MonthYearHeaderView` which are in corresponding to
+  // the 3 months: `previous_month_`, `current_month_` and `next_month_`.
+  enum LabelType { PREVIOUS, CURRENT, NEXT };
+
   friend class CalendarViewTest;
 
   // Assigns month views and labels based on the current date on screen.
@@ -67,8 +77,7 @@
   int PositionOfToday();
 
   // Adds a month label.
-  views::Label* AddLabelWithId(std::u16string label_string,
-                               bool add_at_front = false);
+  views::View* AddLabelWithId(LabelType type, bool add_at_front = false);
 
   // Adds a `CalendarMonthView`.
   CalendarMonthView* AddMonth(base::Time month_first_date,
@@ -107,9 +116,9 @@
 
   // The following is owned by `CalendarView`.
   views::ScrollView* scroll_view_ = nullptr;
-  views::Label* current_label_ = nullptr;
-  views::Label* previous_label_ = nullptr;
-  views::Label* next_label_ = nullptr;
+  views::View* current_label_ = nullptr;
+  views::View* previous_label_ = nullptr;
+  views::View* next_label_ = nullptr;
   CalendarMonthView* previous_month_ = nullptr;
   CalendarMonthView* current_month_ = nullptr;
   CalendarMonthView* next_month_ = nullptr;
diff --git a/ash/system/time/calendar_view_unittest.cc b/ash/system/time/calendar_view_unittest.cc
index a9a27b5..5bafd99 100644
--- a/ash/system/time/calendar_view_unittest.cc
+++ b/ash/system/time/calendar_view_unittest.cc
@@ -56,9 +56,37 @@
   CalendarView* calendar_view() { return calendar_view_.get(); }
   views::ScrollView* scroll_view_() { return calendar_view_->scroll_view_; }
 
-  views::Label* previous_label() { return calendar_view_->previous_label_; }
-  views::Label* current_label() { return calendar_view_->current_label_; }
-  views::Label* next_label() { return calendar_view_->next_label_; }
+  views::View* previous_label() { return calendar_view_->previous_label_; }
+  views::View* current_label() { return calendar_view_->current_label_; }
+  views::View* next_label() { return calendar_view_->next_label_; }
+
+  std::u16string GetPreviousLabelText() {
+    std::u16string month_text =
+        static_cast<views::Label*>(previous_label()->children()[0])->GetText();
+    if (previous_label()->children().size() > 1) {
+      month_text += static_cast<views::Label*>(previous_label()->children()[1])
+                        ->GetText();
+    }
+    return month_text;
+  }
+  std::u16string GetCurrentLabelText() {
+    std::u16string month_text =
+        static_cast<views::Label*>(current_label()->children()[0])->GetText();
+    if (current_label()->children().size() > 1) {
+      month_text +=
+          static_cast<views::Label*>(current_label()->children()[1])->GetText();
+    }
+    return month_text;
+  }
+  std::u16string GetNextLabelText() {
+    std::u16string month_text =
+        static_cast<views::Label*>(next_label()->children()[0])->GetText();
+    if (next_label()->children().size() > 1) {
+      month_text +=
+          static_cast<views::Label*>(next_label()->children()[1])->GetText();
+    }
+    return month_text;
+  }
   CalendarMonthView* previous_month() {
     return calendar_view_->previous_month_;
   }
@@ -94,9 +122,9 @@
   ASSERT_TRUE(base::Time::FromString("24 Aug 2021 10:00 GMT", &date));
   CreateCalendarView(date);
 
-  EXPECT_EQ(u"July", previous_label()->GetText());
-  EXPECT_EQ(u"August", current_label()->GetText());
-  EXPECT_EQ(u"September", next_label()->GetText());
+  EXPECT_EQ(u"July", GetPreviousLabelText());
+  EXPECT_EQ(u"August", GetCurrentLabelText());
+  EXPECT_EQ(u"September", GetNextLabelText());
   EXPECT_EQ(u"August", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
@@ -115,9 +143,9 @@
   ASSERT_TRUE(base::Time::FromString("24 Dec 2021 10:00 GMT", &dec_date));
   CreateCalendarView(dec_date);
 
-  EXPECT_EQ(u"November", previous_label()->GetText());
-  EXPECT_EQ(u"December", current_label()->GetText());
-  EXPECT_EQ(u"January", next_label()->GetText());
+  EXPECT_EQ(u"November", GetPreviousLabelText());
+  EXPECT_EQ(u"December", GetCurrentLabelText());
+  EXPECT_EQ(u"January2022", GetNextLabelText());
   EXPECT_EQ(u"December", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
@@ -138,9 +166,9 @@
 
   CreateCalendarView(date);
 
-  EXPECT_EQ(u"September", previous_label()->GetText());
-  EXPECT_EQ(u"October", current_label()->GetText());
-  EXPECT_EQ(u"November", next_label()->GetText());
+  EXPECT_EQ(u"September", GetPreviousLabelText());
+  EXPECT_EQ(u"October", GetCurrentLabelText());
+  EXPECT_EQ(u"November", GetNextLabelText());
   EXPECT_EQ(u"October", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
@@ -149,25 +177,25 @@
   // the target position.
   scroll_view_()->ScrollToPosition(scroll_view_()->vertical_scroll_bar(), 400);
 
-  EXPECT_EQ(u"October", previous_label()->GetText());
-  EXPECT_EQ(u"November", current_label()->GetText());
-  EXPECT_EQ(u"December", next_label()->GetText());
+  EXPECT_EQ(u"October", GetPreviousLabelText());
+  EXPECT_EQ(u"November", GetCurrentLabelText());
+  EXPECT_EQ(u"December", GetNextLabelText());
   EXPECT_EQ(u"November", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
   scroll_view_()->ScrollToPosition(scroll_view_()->vertical_scroll_bar(), 400);
 
-  EXPECT_EQ(u"November", previous_label()->GetText());
-  EXPECT_EQ(u"December", current_label()->GetText());
-  EXPECT_EQ(u"January", next_label()->GetText());
+  EXPECT_EQ(u"November", GetPreviousLabelText());
+  EXPECT_EQ(u"December", GetCurrentLabelText());
+  EXPECT_EQ(u"January2022", GetNextLabelText());
   EXPECT_EQ(u"December", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
   scroll_view_()->ScrollToPosition(scroll_view_()->vertical_scroll_bar(), 400);
 
-  EXPECT_EQ(u"December", previous_label()->GetText());
-  EXPECT_EQ(u"January", current_label()->GetText());
-  EXPECT_EQ(u"February", next_label()->GetText());
+  EXPECT_EQ(u"December", GetPreviousLabelText());
+  EXPECT_EQ(u"January2022", GetCurrentLabelText());
+  EXPECT_EQ(u"February2022", GetNextLabelText());
   EXPECT_EQ(u"January", header_()->GetText());
   EXPECT_EQ(u"2022", header_year_()->GetText());
 }
@@ -185,58 +213,58 @@
 
   CreateCalendarView(date);
 
-  EXPECT_EQ(u"September", previous_label()->GetText());
-  EXPECT_EQ(u"October", current_label()->GetText());
-  EXPECT_EQ(u"November", next_label()->GetText());
+  EXPECT_EQ(u"September", GetPreviousLabelText());
+  EXPECT_EQ(u"October", GetCurrentLabelText());
+  EXPECT_EQ(u"November", GetNextLabelText());
   EXPECT_EQ(u"October", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
   ScrollDownOneMonth();
 
-  EXPECT_EQ(u"October", previous_label()->GetText());
-  EXPECT_EQ(u"November", current_label()->GetText());
-  EXPECT_EQ(u"December", next_label()->GetText());
+  EXPECT_EQ(u"October", GetPreviousLabelText());
+  EXPECT_EQ(u"November", GetCurrentLabelText());
+  EXPECT_EQ(u"December", GetNextLabelText());
   EXPECT_EQ(u"November", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
   ScrollDownOneMonth();
 
-  EXPECT_EQ(u"November", previous_label()->GetText());
-  EXPECT_EQ(u"December", current_label()->GetText());
-  EXPECT_EQ(u"January", next_label()->GetText());
+  EXPECT_EQ(u"November", GetPreviousLabelText());
+  EXPECT_EQ(u"December", GetCurrentLabelText());
+  EXPECT_EQ(u"January2022", GetNextLabelText());
   EXPECT_EQ(u"December", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
   ScrollDownOneMonth();
 
-  EXPECT_EQ(u"December", previous_label()->GetText());
-  EXPECT_EQ(u"January", current_label()->GetText());
-  EXPECT_EQ(u"February", next_label()->GetText());
+  EXPECT_EQ(u"December", GetPreviousLabelText());
+  EXPECT_EQ(u"January2022", GetCurrentLabelText());
+  EXPECT_EQ(u"February2022", GetNextLabelText());
   EXPECT_EQ(u"January", header_()->GetText());
   EXPECT_EQ(u"2022", header_year_()->GetText());
 
   ScrollUpOneMonth();
 
-  EXPECT_EQ(u"November", previous_label()->GetText());
-  EXPECT_EQ(u"December", current_label()->GetText());
-  EXPECT_EQ(u"January", next_label()->GetText());
+  EXPECT_EQ(u"November", GetPreviousLabelText());
+  EXPECT_EQ(u"December", GetCurrentLabelText());
+  EXPECT_EQ(u"January2022", GetNextLabelText());
   EXPECT_EQ(u"December", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 
   ScrollDownOneMonth();
 
-  EXPECT_EQ(u"December", previous_label()->GetText());
-  EXPECT_EQ(u"January", current_label()->GetText());
-  EXPECT_EQ(u"February", next_label()->GetText());
+  EXPECT_EQ(u"December", GetPreviousLabelText());
+  EXPECT_EQ(u"January2022", GetCurrentLabelText());
+  EXPECT_EQ(u"February2022", GetNextLabelText());
   EXPECT_EQ(u"January", header_()->GetText());
   EXPECT_EQ(u"2022", header_year_()->GetText());
 
   // Goes back to the landing view.
   ResetToToday();
 
-  EXPECT_EQ(u"September", previous_label()->GetText());
-  EXPECT_EQ(u"October", current_label()->GetText());
-  EXPECT_EQ(u"November", next_label()->GetText());
+  EXPECT_EQ(u"September", GetPreviousLabelText());
+  EXPECT_EQ(u"October", GetCurrentLabelText());
+  EXPECT_EQ(u"November", GetNextLabelText());
   EXPECT_EQ(u"October", header_()->GetText());
   EXPECT_EQ(u"2021", header_year_()->GetText());
 }