0

Removed CalendarJelly flag

This CL removed the CalendarJelly flag and renamed classes and variables
to get rid of the Jelly name.

Bug: b:305062253
Change-Id: Ib6d0e04e5237cb7d70843e97d6793a5194ba3f80
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4973397
Reviewed-by: Jiaming Cheng <jiamingc@chromium.org>
Reviewed-by: Yulun Wu <yulunwu@chromium.org>
Commit-Queue: Sylvie Liu <sylvieliu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1216450}
This commit is contained in:
Sylvie Liu
2023-10-27 23:53:41 +00:00
committed by Chromium LUCI CQ
parent 1b11c5cd65
commit 2bfb6764f5
30 changed files with 510 additions and 1169 deletions

@ -2038,8 +2038,6 @@ component("ash") {
"system/time/calendar_event_fetch_types.h",
"system/time/calendar_event_list_item_view.cc",
"system/time/calendar_event_list_item_view.h",
"system/time/calendar_event_list_item_view_jelly.cc",
"system/time/calendar_event_list_item_view_jelly.h",
"system/time/calendar_event_list_view.cc",
"system/time/calendar_event_list_view.h",
"system/time/calendar_metrics.cc",
@ -3625,7 +3623,7 @@ test("ash_unittests") {
"system/status_area_animation_controller_unittest.cc",
"system/status_area_widget_unittest.cc",
"system/time/calendar_event_fetch_unittest.cc",
"system/time/calendar_event_list_item_view_jelly_unittest.cc",
"system/time/calendar_event_list_item_view_unittest.cc",
"system/time/calendar_event_list_view_unittest.cc",
"system/time/calendar_model_unittest.cc",
"system/time/calendar_month_view_unittest.cc",

@ -5264,7 +5264,7 @@ Some features are limited to increase battery life.
Event <ph name="event_position">$1<ex>1</ex></ph> of <ph name="event_total_count">$2<ex>2</ex></ph>
</message>
<message name="IDS_ASH_CALENDAR_EVENT_ENTRY_ACCESSIBLE_DESCRIPTION_JELLY" desc="The accessible label of a calendar event list item jelly entry.">
<message name="IDS_ASH_CALENDAR_EVENT_ENTRY_ACCESSIBLE_DESCRIPTION" desc="The accessible label of a calendar event list item entry.">
<ph name="event_position">$1<ex>Event 1 of 2</ex></ph>
<ph name="event_summary">$2<ex>Lunch break</ex></ph>,
<ph name="start_time">$3<ex>12 PM</ex></ph> to
@ -5272,13 +5272,6 @@ Some features are limited to increase battery life.
<ph name="time_zone">$5<ex>Pacific time</ex></ph>. Select for more details in Google Calendar.
</message>
<message name="IDS_ASH_CALENDAR_EVENT_ENTRY_ACCESSIBLE_DESCRIPTION" desc="The accessible label of a calendar event entry.">
<ph name="start_time">$1<ex>12 PM</ex></ph> to
<ph name="end_time">$2<ex>1 PM</ex></ph>,
<ph name="time_zone">$3<ex>Pacific time</ex></ph>,
<ph name="event_summary">$4<ex>Lunch break</ex></ph>. Select for more details in Google Calendar.
</message>
<message name="IDS_ASH_CALENDAR_EVENT_ENTRY_TOOL_TIP" desc="The tool tip label of a calendar event entry.">
<ph name="event_summary">$1<ex>Lunch break</ex></ph>, <ph name="time_range">$2<ex>1:00 - 1:30 PM</ex></ph>
</message>

@ -1 +1 @@
a686410b511900023a122b14f8766d570903d577
cddc7241d928b5f05cb4cdc770c31017fdfd4314

@ -1 +0,0 @@
cddc7241d928b5f05cb4cdc770c31017fdfd4314

@ -353,9 +353,6 @@ BASE_FEATURE(kBorealisWebUIInstaller,
"BorealisWebUIInstaller",
base::FEATURE_DISABLED_BY_DEFAULT);
// Enable or disable calendar jelly.
BASE_FEATURE(kCalendarJelly, "CalendarJelly", base::FEATURE_ENABLED_BY_DEFAULT);
// Controls whether the camera effects are supported by hardware.
// Note that this feature can be overridden by login_manager based on
// whether a per-board build sets the USE camera_feature_effects flag.
@ -3096,10 +3093,6 @@ bool IsBluetoothQualityReportEnabled() {
return base::FeatureList::IsEnabled(kBluetoothQualityReport);
}
bool IsCalendarJellyEnabled() {
return base::FeatureList::IsEnabled(kCalendarJelly);
}
bool IsCaptureModeAudioMixingEnabled() {
return base::FeatureList::IsEnabled(kCaptureModeAudioMixing);
}

@ -97,7 +97,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kBorealisPermitted);
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kBorealisProvision);
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kBorealisWebUIInstaller);
COMPONENT_EXPORT(ASH_CONSTANTS)
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCalendarJelly);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kCameraEffectsSupportedByHardware);
COMPONENT_EXPORT(ASH_CONSTANTS)
@ -887,7 +886,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBackgroundBlurEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBatterySaverAvailable();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBatterySaverAlwaysOn();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBluetoothQualityReportEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsCalendarJellyEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsCaptureModeAudioMixingEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsCaptureModeTourEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsCellularCarrierLockEnabled();

@ -1,90 +1,92 @@
// Copyright 2021 The Chromium Authors
// Copyright 2022 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/time/calendar_event_list_item_view.h"
#include <string>
#include <tuple>
#include "ash/public/cpp/ash_typography.h"
#include "ash/bubble/bubble_utils.h"
#include "ash/public/cpp/system_tray_client.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/model/clock_model.h"
#include "ash/style/pill_button.h"
#include "ash/style/style_util.h"
#include "ash/style/typography.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/time/calendar_metrics.h"
#include "ash/system/time/calendar_utils.h"
#include "ash/system/time/calendar_view_controller.h"
#include "ash/system/tray/tray_popup_utils.h"
#include "ash/system/tray/tri_view.h"
#include "ash/system/time/event_date_formatter_util.h"
#include "base/containers/fixed_flat_map.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "google_apis/calendar/calendar_api_response_types.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/compositor/layer.h"
#include "ui/events/event.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/background.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/vector_icons.h"
#include "ui/views/view.h"
namespace ash {
namespace {
// The paddings for `CalendarEventListViewItem`.
constexpr auto kEventListItemInsets = gfx::Insets::VH(0, 20);
// Paddings in this view.
constexpr int kEntryHorizontalPadding = 20;
// The paddings for `CalendarEventListItemView`.
constexpr auto kEventListItemInsets =
gfx::Insets::VH(8, calendar_utils::kEventListItemViewStartEndMargin);
constexpr auto kEventListItemHorizontalChildSpacing = 8;
constexpr int kEventListItemCornerRadius = 16;
constexpr int kEventListItemCornerDefaultRadius = 5;
constexpr int kUpNextViewEventListItemCornerRadius = 20;
constexpr float kEventListItemFocusCornerRadius = 3.0f;
// Radius of the event color dot.
constexpr int kColorDotRadius = 4;
// Dimension of the event color dot view.
constexpr int kColorDotViewSize = 8;
constexpr int kColorDotViewSize = kColorDotRadius * 2;
// Default Calendar API color ID to use when no event color is specifified.
constexpr char kDefaultColorId[] = "7";
// Map of Calendar API color ids and their respective hex color code.
std::map<std::string, std::string> event_hex_color_codes = {
{"1", "a4bdfc"}, {"2", "7ae7bf"}, {"3", "dbadff"}, {"4", "ff887c"},
{"5", "fbd75b"}, {"6", "ffb878"}, {"7", "46d6db"}, {"8", "e1e1e1"},
{"9", "5484ed"}, {"10", "51b749"}, {"11", "dc2127"}};
// Sets up the event label.
void SetUpLabel(views::Label* label,
gfx::ElideBehavior elide_behavior,
gfx::HorizontalAlignment horizontal_alignment) {
label->SetHorizontalAlignment(horizontal_alignment);
label->SetAutoColorReadabilityEnabled(false);
label->SetElideBehavior(elide_behavior);
label->SetSubpixelRenderingEnabled(false);
label->SetTextContext(CONTEXT_CALENDAR_DATE);
}
constexpr auto kEventHexColorCodes =
base::MakeFixedFlatMap<base::StringPiece, base::StringPiece>(
{{"1", "6994FF"},
{"2", "3CBD8E"},
{"3", "BB74F2"},
{"4", "FA827A"},
{"5", "C7C419"},
{"6", "F0A85F"},
{"7", "60BDBD"},
{"8", "BD9C9C"},
{"9", "7077DC"},
{"10", "5B9157"},
{"11", "D45D5D"}});
// Renders an Event color dot.
class CalendarEventListItemDot : public views::View {
public:
CalendarEventListItemDot(std::string color_id) {
DCHECK(color_id.empty() || event_hex_color_codes.count(color_id));
std::string hex_code =
event_hex_color_codes[color_id.empty() ? kDefaultColorId : color_id];
explicit CalendarEventListItemDot(std::string color_id) {
DCHECK(color_id.empty() || kEventHexColorCodes.count(color_id));
base::BasicStringPiece<char> hex_code = LookupColorId(color_id);
base::HexStringToInt(hex_code, &color_);
SetPreferredSize(gfx::Size(
kColorDotViewSize,
kColorDotViewSize + calendar_utils::kEventListItemViewStartEndMargin));
}
~CalendarEventListItemDot() override = default;
CalendarEventListItemDot(const CalendarEventListItemDot& other) = delete;
CalendarEventListItemDot& operator=(const CalendarEventListItemDot& other) =
delete;
// views::View:
gfx::Size CalculatePreferredSize() const override {
return gfx::Size(kColorDotViewSize, kColorDotViewSize);
}
~CalendarEventListItemDot() override = default;
// Draws the circle for the event color dot.
void OnPaint(gfx::Canvas* canvas) override {
@ -97,149 +99,254 @@ class CalendarEventListItemDot : public views::View {
}
private:
base::BasicStringPiece<char> LookupColorId(std::string color_id) {
const auto* iter = kEventHexColorCodes.find(color_id);
if (iter == kEventHexColorCodes.end()) {
return kEventHexColorCodes.at(kDefaultColorId);
}
return iter->second;
}
// The color value of the dot.
int color_;
};
// Gets the event start and end times accounting for timezone.
const std::tuple<base::Time, base::Time> GetStartAndEndTime(
const google_apis::calendar::CalendarEvent* event,
CalendarViewController* calendar_view_controller) {
const base::Time selected_midnight =
calendar_view_controller->selected_date_midnight();
const base::Time selected_midnight_utc =
calendar_view_controller->selected_date_midnight_utc();
const base::Time selected_last_minute =
calendar_utils::GetNextDayMidnight(selected_midnight) - base::Minutes(1);
const base::TimeDelta time_difference = calendar_utils::GetTimeDifference(
calendar_view_controller->selected_date().value());
const base::Time selected_last_minute_utc =
selected_last_minute - time_difference;
// If it's an "all day" event, then we want to display 00:00 - 23:59 for the
// event. The formatter we use will apply timezone changes to the given
// `base::Time` which are set to UTC midnight in the response, so we need to
// negate the timezone, so when the formatter formats, it will make the dates
// midnight in the local timezone.
if (event->all_day_event())
return std::make_tuple(selected_midnight_utc, selected_last_minute_utc);
base::Time start_time = calendar_utils::GetMaxTime(
event->start_time().date_time(), selected_midnight_utc);
base::Time end_time = calendar_utils::GetMinTime(
event->end_time().date_time(), selected_last_minute_utc);
return std::make_tuple(start_time, end_time);
// Creates and returns a label containing the event summary.
views::Builder<views::Label> CreateSummaryLabel(
const std::string& event_summary,
const std::u16string& tooltip_text,
const int& fixed_width) {
return views::Builder<views::Label>(
bubble_utils::CreateLabel(
TypographyToken::kCrosButton2,
event_summary.empty()
? l10n_util::GetStringUTF16(IDS_ASH_CALENDAR_NO_TITLE)
: base::UTF8ToUTF16(event_summary),
cros_tokens::kCrosSysOnSurface))
.SetID(kSummaryLabelID)
.SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT)
.SetAutoColorReadabilityEnabled(false)
.SetMultiLine(true)
.SetMaxLines(1)
.SizeToFit(fixed_width)
.SetElideBehavior(gfx::ElideBehavior::ELIDE_TAIL)
.SetSubpixelRenderingEnabled(false)
.SetTooltipText(tooltip_text);
}
bool Is12HourClock() {
return Shell::Get()->system_tray_model()->clock()->hour_clock_type() ==
base::k12HourClock;
// Creates and returns a label containing the event time.
views::Builder<views::Label> CreateTimeLabel(
const std::u16string& title,
const std::u16string& tooltip_text) {
return views::Builder<views::Label>(
bubble_utils::CreateLabel(TypographyToken::kCrosAnnotation1, title,
cros_tokens::kCrosSysOnSurfaceVariant))
.SetID(kTimeLabelID)
.SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT)
.SetAutoColorReadabilityEnabled(false)
.SetElideBehavior(gfx::ElideBehavior::NO_ELIDE)
.SetSubpixelRenderingEnabled(false)
.SetTooltipText(tooltip_text);
}
const std::tuple<std::u16string, std::u16string>
GetStartAndEndTimeAccessibleNames(base::Time start_time, base::Time end_time) {
return Is12HourClock()
? std::make_tuple(
calendar_utils::GetTwelveHourClockTime(start_time),
calendar_utils::GetTwelveHourClockTime(end_time))
: std::make_tuple(
calendar_utils::GetTwentyFourHourClockTime(start_time),
calendar_utils::GetTwentyFourHourClockTime(end_time));
}
// A `HighlightPathGenerator` that uses caller-supplied rounded rect corners.
class VIEWS_EXPORT RoundedCornerHighlightPathGenerator
: public views::HighlightPathGenerator {
public:
explicit RoundedCornerHighlightPathGenerator(
const gfx::RoundedCornersF& corners)
: corners_(corners) {}
// Returns a string containing the event start and end times "nn:nn - nn:nn".
const std::u16string GetFormattedInterval(base::Time start_time,
base::Time end_time) {
return Is12HourClock()
? calendar_utils::FormatTwelveHourClockTimeInterval(start_time,
end_time)
: calendar_utils::FormatTwentyFourHourClockTimeInterval(start_time,
end_time);
}
RoundedCornerHighlightPathGenerator(
const RoundedCornerHighlightPathGenerator&) = delete;
RoundedCornerHighlightPathGenerator& operator=(
const RoundedCornerHighlightPathGenerator&) = delete;
// views::HighlightPathGenerator:
absl::optional<gfx::RRectF> GetRoundRect(const gfx::RectF& rect) override {
return gfx::RRectF(rect, corners_);
}
private:
// The user-supplied rounded rect corners.
const gfx::RoundedCornersF corners_;
};
} // namespace
CalendarEventListItemView::CalendarEventListItemView(
CalendarViewController* calendar_view_controller,
google_apis::calendar::CalendarEvent event)
SelectedDateParams selected_date_params,
google_apis::calendar::CalendarEvent event,
UIParams ui_params,
EventListItemIndex event_list_item_index)
: calendar_view_controller_(calendar_view_controller),
summary_(new views::Label()),
time_range_(new views::Label()),
event_url_(event.html_link()) {
selected_date_params_(selected_date_params),
event_url_(event.html_link()),
video_conference_url_(event.conference_data_uri()) {
SetCallback(base::BindRepeating(&CalendarEventListItemView::PerformAction,
base::Unretained(this)));
SetLayoutManager(std::make_unique<views::FillLayout>());
DCHECK(calendar_view_controller_->selected_date().has_value());
auto [start_time, end_time] =
GetStartAndEndTime(&event, calendar_view_controller);
auto [start_time_accessible_name, end_time_accessible_name] =
GetStartAndEndTimeAccessibleNames(start_time, end_time);
SetLayoutManager(std::make_unique<views::FillLayout>());
const auto [start_time, end_time] = calendar_utils::GetStartAndEndTime(
&event, selected_date_params_.selected_date,
selected_date_params_.selected_date_midnight,
selected_date_params_.selected_date_midnight_utc);
const auto [start_time_accessible_name, end_time_accessible_name] =
event_date_formatter_util::GetStartAndEndTimeAccessibleNames(start_time,
end_time);
GetViewAccessibility().OverrideRole(ax::mojom::Role::kButton);
const std::u16string event_item_index_in_list_string =
l10n_util::GetStringFUTF16(
IDS_ASH_CALENDAR_EVENT_POSITION_ACCESSIBLE_DESCRIPTION,
base::NumberToString16(event_list_item_index.item_index),
base::NumberToString16(event_list_item_index.total_count_of_events));
SetAccessibleName(l10n_util::GetStringFUTF16(
IDS_ASH_CALENDAR_EVENT_ENTRY_ACCESSIBLE_DESCRIPTION,
event_item_index_in_list_string, base::UTF8ToUTF16(event.summary()),
start_time_accessible_name, end_time_accessible_name,
calendar_utils::GetTimeZone(start_time),
base::UTF8ToUTF16(event.summary())));
auto formatted_interval = GetFormattedInterval(start_time, end_time);
time_range_->SetText(formatted_interval);
calendar_utils::GetTimeZone(start_time)));
SetFocusBehavior(FocusBehavior::ALWAYS);
SetBorder(views::CreateEmptyBorder(kEventListItemInsets));
summary_->SetText(event.summary().empty()
? l10n_util::GetStringUTF16(IDS_ASH_CALENDAR_NO_TITLE)
: base::UTF8ToUTF16(event.summary()));
SetUpLabel(summary_, gfx::ElideBehavior::ELIDE_TAIL,
gfx::HorizontalAlignment::ALIGN_LEFT);
summary_->SetBorder(
views::CreateEmptyBorder(gfx::Insets::VH(0, kEntryHorizontalPadding)));
SetUpLabel(time_range_, gfx::NO_ELIDE,
gfx::HorizontalAlignment::ALIGN_CENTER);
// Conditionally round the items corners depending upon where it sits in the
// list and whether it is in the up next event list.
const int round_corner_radius = ui_params.is_up_next_event_list_item
? kUpNextViewEventListItemCornerRadius
: kEventListItemCornerRadius;
const int top_radius = ui_params.round_top_corners
? round_corner_radius
: kEventListItemCornerDefaultRadius;
const int bottom_radius = ui_params.round_bottom_corners
? round_corner_radius
: kEventListItemCornerDefaultRadius;
const gfx::RoundedCornersF item_corner_radius = gfx::RoundedCornersF(
top_radius, top_radius, bottom_radius, bottom_radius);
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
layer()->SetRoundedCornerRadius(item_corner_radius);
SetUpFocusHighlight(item_corner_radius);
// Creates a `TriView` which carries the `color_dot`, `summary_` and
// `time_range_`.
TriView* tri_view =
TrayPopupUtils::CreateDefaultRowView(/*use_wide_layout=*/false);
tri_view->SetMinSize(
TriView::Container::START,
gfx::Size(kColorDotViewSize,
tri_view->GetMinSize(TriView::Container::START).height()));
tri_view->AddView(TriView::Container::START,
AddChildView(std::make_unique<CalendarEventListItemDot>(
event.color_id())));
tri_view->AddView(TriView::Container::CENTER, summary_);
tri_view->AddView(TriView::Container::END, time_range_);
auto tooltip_text = l10n_util::GetStringFUTF16(
std::u16string formatted_time_text;
if (calendar_utils::IsMultiDayEvent(&event) || event.all_day_event()) {
formatted_time_text = event_date_formatter_util::GetMultiDayText(
&event, selected_date_params_.selected_date_midnight,
selected_date_params_.selected_date_midnight_utc);
} else {
formatted_time_text =
event_date_formatter_util::GetFormattedInterval(start_time, end_time);
is_current_or_next_event_ = end_time >= base::Time::NowFromSystemTime();
}
const auto tooltip_text = l10n_util::GetStringFUTF16(
IDS_ASH_CALENDAR_EVENT_ENTRY_TOOL_TIP, base::UTF8ToUTF16(event.summary()),
formatted_interval);
time_range_->SetTooltipText(tooltip_text);
summary_->SetTooltipText(tooltip_text);
formatted_time_text);
AddChildView(tri_view);
auto horizontal_layout_manager = std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, kEventListItemInsets,
kEventListItemHorizontalChildSpacing);
views::View* horizontal_container =
AddChildView(std::make_unique<views::View>());
auto* horizontal_container_layout_manager =
horizontal_container->SetLayoutManager(
std::move(horizontal_layout_manager));
// Event list dot.
if (ui_params.show_event_list_dot) {
views::View* event_list_dot_container =
horizontal_container->AddChildView(std::make_unique<views::View>());
auto* layout_vertical_start = event_list_dot_container->SetLayoutManager(
std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
layout_vertical_start->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kStart);
event_list_dot_container
->AddChildView(
std::make_unique<CalendarEventListItemDot>(event.color_id()))
->SetID(kEventListItemDotID);
}
// Labels.
views::View* vertical_container =
horizontal_container->AddChildView(std::make_unique<views::View>());
vertical_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
vertical_container->AddChildView(
CreateSummaryLabel(event.summary(), tooltip_text, ui_params.fixed_width)
.Build());
vertical_container->AddChildView(
CreateTimeLabel(formatted_time_text, tooltip_text).Build());
horizontal_container_layout_manager->SetFlexForView(vertical_container, 1);
// Join button.
if (!video_conference_url_.is_empty()) {
views::View* join_button_container =
horizontal_container->AddChildView(std::make_unique<views::View>());
auto* layout_vertical_center = join_button_container->SetLayoutManager(
std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
layout_vertical_center->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kCenter);
auto join_button = std::make_unique<PillButton>(
base::BindRepeating(
&CalendarEventListItemView::OnJoinMeetingButtonPressed,
weak_ptr_factory_.GetWeakPtr()),
l10n_util::GetStringUTF16(IDS_ASH_CALENDAR_JOIN_BUTTON),
PillButton::Type::kDefaultWithoutIcon);
join_button->SetAccessibleName(
l10n_util::GetStringFUTF16(IDS_ASH_CALENDAR_JOIN_BUTTON_ACCESSIBLE_NAME,
base::UTF8ToUTF16(event.summary())));
join_button->SetID(kJoinButtonID);
join_button_container->AddChildView(std::move(join_button));
}
}
CalendarEventListItemView::~CalendarEventListItemView() = default;
void CalendarEventListItemView::OnThemeChanged() {
views::View::OnThemeChanged();
summary_->SetEnabledColor(calendar_utils::GetPrimaryTextColor());
time_range_->SetEnabledColor(calendar_utils::GetPrimaryTextColor());
SetBackground(views::CreateSolidBackground(
GetColorProvider()->GetColor(cros_tokens::kCrosSysSurface5)));
}
void CalendarEventListItemView::PerformAction(const ui::Event& event) {
DCHECK(event_url_.is_empty() || event_url_.is_valid());
calendar_metrics::RecordEventListItemActivated(event);
calendar_view_controller_->RecordEventListItemActivated(event);
calendar_view_controller_->OnCalendarEventWillLaunch();
GURL finalized_url;
bool opened_pwa = false;
DCHECK(calendar_view_controller_->selected_date().has_value());
Shell::Get()->system_tray_model()->client()->ShowCalendarEvent(
event_url_, calendar_view_controller_->selected_date_midnight(),
opened_pwa, finalized_url);
event_url_, selected_date_params_.selected_date_midnight, opened_pwa,
finalized_url);
}
void CalendarEventListItemView::SetUpFocusHighlight(
const gfx::RoundedCornersF& item_corner_radius) {
StyleUtil::SetUpInkDropForButton(this, gfx::Insets(),
/*highlight_on_hover=*/false,
/*highlight_on_focus=*/false,
/*background_color=*/
gfx::kPlaceholderColor);
views::FocusRing::Get(this)->SetColorId(cros_tokens::kCrosSysFocusRing);
views::FocusRing::Get(this)->SetHaloThickness(
kEventListItemFocusCornerRadius);
views::HighlightPathGenerator::Install(
this, std::make_unique<RoundedCornerHighlightPathGenerator>(
item_corner_radius));
// Unset the focus painter set by `HoverHighlightView`.
SetFocusPainter(nullptr);
}
void CalendarEventListItemView::OnJoinMeetingButtonPressed(
const ui::Event& event) {
calendar_view_controller_->RecordJoinMeetingButtonPressed(event);
// The join button won't be shown if `video_conference_url_` doesn't have a
// value.
DCHECK(!video_conference_url_.is_empty());
Shell::Get()->system_tray_model()->client()->ShowVideoConference(
video_conference_url_);
}
BEGIN_METADATA(CalendarEventListItemView, views::View);

@ -1,4 +1,4 @@
// Copyright 2021 The Chromium Authors
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@ -8,32 +8,67 @@
#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "google_apis/calendar/calendar_api_response_types.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/controls/button/button.h"
#include "url/gurl.h"
namespace ui {
class Event;
} // namespace ui
namespace views {
class Label;
} // namespace views
namespace gfx {
class RoundedCornersF;
}
namespace ash {
// View ID's.
constexpr int kSummaryLabelID = 100;
constexpr int kTimeLabelID = 101;
constexpr int kEventListItemDotID = 102;
constexpr int kJoinButtonID = 103;
constexpr int kEventListMultiDayEventsContainer = 104;
constexpr int kEventListSameDayEventsContainer = 105;
class CalendarViewController;
struct SelectedDateParams {
base::Time selected_date;
base::Time selected_date_midnight;
base::Time selected_date_midnight_utc;
};
struct UIParams {
bool round_top_corners = false;
bool round_bottom_corners = false;
// If this view is for `CalendarUpNextView`. `CalendarUpNextView` event list
// item has a different focus ring rounded corner radius.
bool is_up_next_event_list_item = false;
// Show the calendar indicator dots which show the event colors. If
// false this piece of UI is not added to the view hierarchy.
bool show_event_list_dot = false;
// Used in `Label::SizeToFit()` to fix the width of this view. If 0, no
// fixed width is enforced.
int fixed_width = 0;
};
// The index of the event in the event list. Used for the accessibility
// description to show "Event n of n".
struct EventListItemIndex {
int item_index;
int total_count_of_events;
};
// This view displays a calendar event entry.
class ASH_EXPORT CalendarEventListItemView : public views::Button {
public:
METADATA_HEADER(CalendarEventListItemView);
CalendarEventListItemView(CalendarViewController* calendar_view_controller,
google_apis::calendar::CalendarEvent event);
SelectedDateParams selected_date_params,
google_apis::calendar::CalendarEvent event,
UIParams ui_params,
EventListItemIndex event_list_item_index);
CalendarEventListItemView(const CalendarEventListItemView& other) = delete;
CalendarEventListItemView& operator=(const CalendarEventListItemView& other) =
delete;
@ -44,21 +79,34 @@ class ASH_EXPORT CalendarEventListItemView : public views::Button {
void PerformAction(const ui::Event& event);
// Sets up a custom highlight path for when the
// `CalendarEventListItemView` view is focused. Conditionally follows the
// same corner rounding as the view.
void SetUpFocusHighlight(const gfx::RoundedCornersF& item_corner_radius);
void OnJoinMeetingButtonPressed(const ui::Event& event);
bool is_current_or_next_event() const { return is_current_or_next_event_; }
private:
friend class CalendarViewEventListViewTest;
// Unowned.
const raw_ptr<CalendarViewController, ExperimentalAsh>
const raw_ptr<CalendarViewController, DanglingUntriaged | ExperimentalAsh>
calendar_view_controller_;
// The summary (title) of the meeting event.
const raw_ptr<views::Label, ExperimentalAsh> summary_;
// The start time and end time of a meeting event.
const raw_ptr<views::Label, ExperimentalAsh> time_range_;
const SelectedDateParams selected_date_params_;
// The URL for the meeting event.
const GURL event_url_;
const GURL video_conference_url_;
// Whether this item which is not an all-day or multi-day event is the current
// or next event. Used for auto scroll in the `CalendarEventListView`.
bool is_current_or_next_event_ = false;
base::WeakPtrFactory<CalendarEventListItemView> weak_ptr_factory_{this};
};
} // namespace ash

@ -1,357 +0,0 @@
// Copyright 2022 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/time/calendar_event_list_item_view_jelly.h"
#include <string>
#include <tuple>
#include "ash/bubble/bubble_utils.h"
#include "ash/public/cpp/ash_typography.h"
#include "ash/public/cpp/system_tray_client.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/pill_button.h"
#include "ash/style/style_util.h"
#include "ash/style/typography.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/time/calendar_utils.h"
#include "ash/system/time/calendar_view_controller.h"
#include "ash/system/time/event_date_formatter_util.h"
#include "base/containers/fixed_flat_map.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "google_apis/calendar/calendar_api_response_types.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/compositor/layer.h"
#include "ui/events/event.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/background.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
namespace ash {
namespace {
// The paddings for `CalendarEventListViewItemJelly`.
constexpr auto kEventListItemInsets =
gfx::Insets::VH(8, calendar_utils::kEventListItemViewStartEndMargin);
constexpr auto kEventListItemHorizontalChildSpacing = 8;
constexpr int kEventListItemCornerRadius = 16;
constexpr int kEventListItemCornerDefaultRadius = 5;
constexpr int kUpNextViewEventListItemCornerRadius = 20;
constexpr float kEventListItemFocusCornerRadius = 3.0f;
// Radius of the event color dot.
constexpr int kColorDotRadius = 4;
// Dimension of the event color dot view.
constexpr int kColorDotViewSize = kColorDotRadius * 2;
// Default Calendar API color ID to use when no event color is specifified.
constexpr char kDefaultColorId[] = "7";
// Map of Calendar API color ids and their respective hex color code.
constexpr auto kEventHexColorCodes =
base::MakeFixedFlatMap<base::StringPiece, base::StringPiece>(
{{"1", "6994FF"},
{"2", "3CBD8E"},
{"3", "BB74F2"},
{"4", "FA827A"},
{"5", "C7C419"},
{"6", "F0A85F"},
{"7", "60BDBD"},
{"8", "BD9C9C"},
{"9", "7077DC"},
{"10", "5B9157"},
{"11", "D45D5D"}});
// Renders an Event color dot.
class CalendarEventListItemDot : public views::View {
public:
explicit CalendarEventListItemDot(std::string color_id) {
DCHECK(color_id.empty() || kEventHexColorCodes.count(color_id));
base::BasicStringPiece<char> hex_code = LookupColorId(color_id);
base::HexStringToInt(hex_code, &color_);
SetPreferredSize(gfx::Size(
kColorDotViewSize,
kColorDotViewSize + calendar_utils::kEventListItemViewStartEndMargin));
}
CalendarEventListItemDot(const CalendarEventListItemDot& other) = delete;
CalendarEventListItemDot& operator=(const CalendarEventListItemDot& other) =
delete;
~CalendarEventListItemDot() override = default;
// Draws the circle for the event color dot.
void OnPaint(gfx::Canvas* canvas) override {
cc::PaintFlags color_dot;
color_dot.setColor(SkColorSetA(color_, SK_AlphaOPAQUE));
color_dot.setStyle(cc::PaintFlags::kFill_Style);
color_dot.setAntiAlias(true);
canvas->DrawCircle(GetContentsBounds().CenterPoint(), kColorDotRadius,
color_dot);
}
private:
base::BasicStringPiece<char> LookupColorId(std::string color_id) {
const auto* iter = kEventHexColorCodes.find(color_id);
if (iter == kEventHexColorCodes.end()) {
return kEventHexColorCodes.at(kDefaultColorId);
}
return iter->second;
}
// The color value of the dot.
int color_;
};
// Creates and returns a label containing the event summary.
views::Builder<views::Label> CreateSummaryLabel(
const std::string& event_summary,
const std::u16string& tooltip_text,
const int& fixed_width) {
return views::Builder<views::Label>(
bubble_utils::CreateLabel(
TypographyToken::kCrosButton2,
event_summary.empty()
? l10n_util::GetStringUTF16(IDS_ASH_CALENDAR_NO_TITLE)
: base::UTF8ToUTF16(event_summary),
cros_tokens::kCrosSysOnSurface))
.SetID(kSummaryLabelID)
.SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT)
.SetAutoColorReadabilityEnabled(false)
.SetMultiLine(true)
.SetMaxLines(1)
.SizeToFit(fixed_width)
.SetElideBehavior(gfx::ElideBehavior::ELIDE_TAIL)
.SetSubpixelRenderingEnabled(false)
.SetTooltipText(tooltip_text);
}
// Creates and returns a label containing the event time.
views::Builder<views::Label> CreateTimeLabel(
const std::u16string& title,
const std::u16string& tooltip_text) {
return views::Builder<views::Label>(
bubble_utils::CreateLabel(TypographyToken::kCrosAnnotation1, title,
cros_tokens::kCrosSysOnSurfaceVariant))
.SetID(kTimeLabelID)
.SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT)
.SetAutoColorReadabilityEnabled(false)
.SetElideBehavior(gfx::ElideBehavior::NO_ELIDE)
.SetSubpixelRenderingEnabled(false)
.SetTooltipText(tooltip_text);
}
// A `HighlightPathGenerator` that uses caller-supplied rounded rect corners.
class VIEWS_EXPORT RoundedCornerHighlightPathGenerator
: public views::HighlightPathGenerator {
public:
explicit RoundedCornerHighlightPathGenerator(
const gfx::RoundedCornersF& corners)
: corners_(corners) {}
RoundedCornerHighlightPathGenerator(
const RoundedCornerHighlightPathGenerator&) = delete;
RoundedCornerHighlightPathGenerator& operator=(
const RoundedCornerHighlightPathGenerator&) = delete;
// views::HighlightPathGenerator:
absl::optional<gfx::RRectF> GetRoundRect(const gfx::RectF& rect) override {
return gfx::RRectF(rect, corners_);
}
private:
// The user-supplied rounded rect corners.
const gfx::RoundedCornersF corners_;
};
} // namespace
CalendarEventListItemViewJelly::CalendarEventListItemViewJelly(
CalendarViewController* calendar_view_controller,
SelectedDateParams selected_date_params,
google_apis::calendar::CalendarEvent event,
UIParams ui_params,
EventListItemIndex event_list_item_index)
: calendar_view_controller_(calendar_view_controller),
selected_date_params_(selected_date_params),
event_url_(event.html_link()),
video_conference_url_(event.conference_data_uri()) {
SetCallback(base::BindRepeating(
&CalendarEventListItemViewJelly::PerformAction, base::Unretained(this)));
SetLayoutManager(std::make_unique<views::FillLayout>());
const auto [start_time, end_time] = calendar_utils::GetStartAndEndTime(
&event, selected_date_params_.selected_date,
selected_date_params_.selected_date_midnight,
selected_date_params_.selected_date_midnight_utc);
const auto [start_time_accessible_name, end_time_accessible_name] =
event_date_formatter_util::GetStartAndEndTimeAccessibleNames(start_time,
end_time);
GetViewAccessibility().OverrideRole(ax::mojom::Role::kButton);
const std::u16string event_item_index_in_list_string =
l10n_util::GetStringFUTF16(
IDS_ASH_CALENDAR_EVENT_POSITION_ACCESSIBLE_DESCRIPTION,
base::NumberToString16(event_list_item_index.item_index),
base::NumberToString16(event_list_item_index.total_count_of_events));
SetAccessibleName(l10n_util::GetStringFUTF16(
IDS_ASH_CALENDAR_EVENT_ENTRY_ACCESSIBLE_DESCRIPTION_JELLY,
event_item_index_in_list_string, base::UTF8ToUTF16(event.summary()),
start_time_accessible_name, end_time_accessible_name,
calendar_utils::GetTimeZone(start_time)));
SetFocusBehavior(FocusBehavior::ALWAYS);
// Conditionally round the items corners depending upon where it sits in the
// list and whether it is in the up next event list.
const int round_corner_radius = ui_params.is_up_next_event_list_item
? kUpNextViewEventListItemCornerRadius
: kEventListItemCornerRadius;
const int top_radius = ui_params.round_top_corners
? round_corner_radius
: kEventListItemCornerDefaultRadius;
const int bottom_radius = ui_params.round_bottom_corners
? round_corner_radius
: kEventListItemCornerDefaultRadius;
const gfx::RoundedCornersF item_corner_radius = gfx::RoundedCornersF(
top_radius, top_radius, bottom_radius, bottom_radius);
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
layer()->SetRoundedCornerRadius(item_corner_radius);
SetUpFocusHighlight(item_corner_radius);
std::u16string formatted_time_text;
if (calendar_utils::IsMultiDayEvent(&event) || event.all_day_event()) {
formatted_time_text = event_date_formatter_util::GetMultiDayText(
&event, selected_date_params_.selected_date_midnight,
selected_date_params_.selected_date_midnight_utc);
} else {
formatted_time_text =
event_date_formatter_util::GetFormattedInterval(start_time, end_time);
is_current_or_next_event_ = end_time >= base::Time::NowFromSystemTime();
}
const auto tooltip_text = l10n_util::GetStringFUTF16(
IDS_ASH_CALENDAR_EVENT_ENTRY_TOOL_TIP, base::UTF8ToUTF16(event.summary()),
formatted_time_text);
auto horizontal_layout_manager = std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, kEventListItemInsets,
kEventListItemHorizontalChildSpacing);
views::View* horizontal_container =
AddChildView(std::make_unique<views::View>());
auto* horizontal_container_layout_manager =
horizontal_container->SetLayoutManager(
std::move(horizontal_layout_manager));
// Event list dot.
if (ui_params.show_event_list_dot) {
views::View* event_list_dot_container =
horizontal_container->AddChildView(std::make_unique<views::View>());
auto* layout_vertical_start = event_list_dot_container->SetLayoutManager(
std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
layout_vertical_start->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kStart);
event_list_dot_container
->AddChildView(
std::make_unique<CalendarEventListItemDot>(event.color_id()))
->SetID(kEventListItemDotID);
}
// Labels.
views::View* vertical_container =
horizontal_container->AddChildView(std::make_unique<views::View>());
vertical_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
vertical_container->AddChildView(
CreateSummaryLabel(event.summary(), tooltip_text, ui_params.fixed_width)
.Build());
vertical_container->AddChildView(
CreateTimeLabel(formatted_time_text, tooltip_text).Build());
horizontal_container_layout_manager->SetFlexForView(vertical_container, 1);
// Join button.
if (!video_conference_url_.is_empty()) {
views::View* join_button_container =
horizontal_container->AddChildView(std::make_unique<views::View>());
auto* layout_vertical_center = join_button_container->SetLayoutManager(
std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
layout_vertical_center->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kCenter);
auto join_button = std::make_unique<PillButton>(
base::BindRepeating(
&CalendarEventListItemViewJelly::OnJoinMeetingButtonPressed,
weak_ptr_factory_.GetWeakPtr()),
l10n_util::GetStringUTF16(IDS_ASH_CALENDAR_JOIN_BUTTON),
PillButton::Type::kDefaultWithoutIcon);
join_button->SetAccessibleName(
l10n_util::GetStringFUTF16(IDS_ASH_CALENDAR_JOIN_BUTTON_ACCESSIBLE_NAME,
base::UTF8ToUTF16(event.summary())));
join_button->SetID(kJoinButtonID);
join_button_container->AddChildView(std::move(join_button));
}
}
CalendarEventListItemViewJelly::~CalendarEventListItemViewJelly() = default;
void CalendarEventListItemViewJelly::OnThemeChanged() {
views::View::OnThemeChanged();
SetBackground(views::CreateSolidBackground(
GetColorProvider()->GetColor(cros_tokens::kCrosSysSurface5)));
}
void CalendarEventListItemViewJelly::PerformAction(const ui::Event& event) {
DCHECK(event_url_.is_empty() || event_url_.is_valid());
calendar_view_controller_->RecordEventListItemActivated(event);
calendar_view_controller_->OnCalendarEventWillLaunch();
GURL finalized_url;
bool opened_pwa = false;
Shell::Get()->system_tray_model()->client()->ShowCalendarEvent(
event_url_, selected_date_params_.selected_date_midnight, opened_pwa,
finalized_url);
}
void CalendarEventListItemViewJelly::SetUpFocusHighlight(
const gfx::RoundedCornersF& item_corner_radius) {
StyleUtil::SetUpInkDropForButton(this, gfx::Insets(),
/*highlight_on_hover=*/false,
/*highlight_on_focus=*/false,
/*background_color=*/
gfx::kPlaceholderColor);
views::FocusRing::Get(this)->SetColorId(cros_tokens::kCrosSysFocusRing);
views::FocusRing::Get(this)->SetHaloThickness(
kEventListItemFocusCornerRadius);
views::HighlightPathGenerator::Install(
this, std::make_unique<RoundedCornerHighlightPathGenerator>(
item_corner_radius));
// Unset the focus painter set by `HoverHighlightView`.
SetFocusPainter(nullptr);
}
void CalendarEventListItemViewJelly::OnJoinMeetingButtonPressed(
const ui::Event& event) {
calendar_view_controller_->RecordJoinMeetingButtonPressed(event);
// The join button won't be shown if `video_conference_url_` doesn't have a
// value.
DCHECK(!video_conference_url_.is_empty());
Shell::Get()->system_tray_model()->client()->ShowVideoConference(
video_conference_url_);
}
BEGIN_METADATA(CalendarEventListItemViewJelly, views::View);
END_METADATA
} // namespace ash

@ -1,116 +0,0 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_TIME_CALENDAR_EVENT_LIST_ITEM_VIEW_JELLY_H_
#define ASH_SYSTEM_TIME_CALENDAR_EVENT_LIST_ITEM_VIEW_JELLY_H_
#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "google_apis/calendar/calendar_api_response_types.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/controls/button/button.h"
#include "url/gurl.h"
namespace ui {
class Event;
} // namespace ui
namespace gfx {
class RoundedCornersF;
}
namespace ash {
// View ID's.
constexpr int kSummaryLabelID = 100;
constexpr int kTimeLabelID = 101;
constexpr int kEventListItemDotID = 102;
constexpr int kJoinButtonID = 103;
constexpr int kEventListMultiDayEventsContainer = 104;
constexpr int kEventListSameDayEventsContainer = 105;
class CalendarViewController;
struct SelectedDateParams {
base::Time selected_date;
base::Time selected_date_midnight;
base::Time selected_date_midnight_utc;
};
struct UIParams {
bool round_top_corners = false;
bool round_bottom_corners = false;
// If this view is for `CalendarUpNextView`. `CalendarUpNextView` event list
// item has a different focus ring rounded corner radius.
bool is_up_next_event_list_item = false;
// Show the calendar indicator dots which show the event colors. If
// false this piece of UI is not added to the view hierarchy.
bool show_event_list_dot = false;
// Used in `Label::SizeToFit()` to fix the width of this view. If 0, no
// fixed width is enforced.
int fixed_width = 0;
};
// The index of the event in the event list. Used for the accessibility
// description to show "Event n of n".
struct EventListItemIndex {
int item_index;
int total_count_of_events;
};
// This view displays a jelly version of a calendar event entry.
class ASH_EXPORT CalendarEventListItemViewJelly : public views::Button {
public:
METADATA_HEADER(CalendarEventListItemViewJelly);
CalendarEventListItemViewJelly(
CalendarViewController* calendar_view_controller,
SelectedDateParams selected_date_params,
google_apis::calendar::CalendarEvent event,
UIParams ui_params,
EventListItemIndex event_list_item_index);
CalendarEventListItemViewJelly(const CalendarEventListItemViewJelly& other) =
delete;
CalendarEventListItemViewJelly& operator=(
const CalendarEventListItemViewJelly& other) = delete;
~CalendarEventListItemViewJelly() override;
// views::View:
void OnThemeChanged() override;
void PerformAction(const ui::Event& event);
// Sets up a custom highlight path for when the
// `CalendarEventListItemViewJelly` view is focused. Conditionally follows the
// same corner rounding as the view.
void SetUpFocusHighlight(const gfx::RoundedCornersF& item_corner_radius);
void OnJoinMeetingButtonPressed(const ui::Event& event);
bool is_current_or_next_event() const { return is_current_or_next_event_; }
private:
friend class CalendarViewEventListViewTest;
// Unowned.
const raw_ptr<CalendarViewController, DanglingUntriaged | ExperimentalAsh>
calendar_view_controller_;
const SelectedDateParams selected_date_params_;
// The URL for the meeting event.
const GURL event_url_;
const GURL video_conference_url_;
// Whether this item which is not an all-day or multi-day event is the current
// or next event. Used for auto scroll in the `CalendarEventListView`.
bool is_current_or_next_event_ = false;
base::WeakPtrFactory<CalendarEventListItemViewJelly> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_SYSTEM_TIME_CALENDAR_EVENT_LIST_ITEM_VIEW_JELLY_H_

@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/time/calendar_event_list_item_view_jelly.h"
#include "ash/system/time/calendar_event_list_item_view.h"
#include "ash/system/time/calendar_unittest_utils.h"
#include "ash/system/time/calendar_view_controller.h"
#include "ash/test/ash_test_base.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "chromeos/ash/components/settings/scoped_timezone_settings.h"
#include "ui/compositor/layer.h"
@ -31,14 +30,14 @@ std::unique_ptr<google_apis::calendar::CalendarEvent> CreateEvent(
} // namespace
class CalendarViewEventListItemViewJellyTest : public AshTestBase {
class CalendarViewEventListItemViewTest : public AshTestBase {
public:
CalendarViewEventListItemViewJellyTest() = default;
CalendarViewEventListItemViewJellyTest(
const CalendarViewEventListItemViewJellyTest&) = delete;
CalendarViewEventListItemViewJellyTest& operator=(
const CalendarViewEventListItemViewJellyTest&) = delete;
~CalendarViewEventListItemViewJellyTest() override = default;
CalendarViewEventListItemViewTest() = default;
CalendarViewEventListItemViewTest(
const CalendarViewEventListItemViewTest&) = delete;
CalendarViewEventListItemViewTest& operator=(
const CalendarViewEventListItemViewTest&) = delete;
~CalendarViewEventListItemViewTest() override = default;
void SetUp() override {
AshTestBase::SetUp();
@ -46,7 +45,7 @@ class CalendarViewEventListItemViewJellyTest : public AshTestBase {
}
void TearDown() override {
event_list_item_view_jelly_.reset();
event_list_item_view_.reset();
controller_.reset();
AshTestBase::TearDown();
}
@ -54,11 +53,11 @@ class CalendarViewEventListItemViewJellyTest : public AshTestBase {
void CreateEventListItemView(base::Time date,
google_apis::calendar::CalendarEvent* event,
UIParams ui_params = {}) {
event_list_item_view_jelly_.reset();
event_list_item_view_.reset();
controller_->UpdateMonth(date);
controller_->selected_date_ = date;
event_list_item_view_jelly_ =
std::make_unique<CalendarEventListItemViewJelly>(
event_list_item_view_ =
std::make_unique<CalendarEventListItemView>(
controller_.get(),
SelectedDateParams{controller_->selected_date().value(),
controller_->selected_date_midnight(),
@ -75,37 +74,36 @@ class CalendarViewEventListItemViewJellyTest : public AshTestBase {
const views::Label* GetSummaryLabel() {
return static_cast<views::Label*>(
event_list_item_view_jelly_->GetViewByID(kSummaryLabelID));
event_list_item_view_->GetViewByID(kSummaryLabelID));
}
const views::Label* GetTimeLabel() {
return static_cast<views::Label*>(
event_list_item_view_jelly_->GetViewByID(kTimeLabelID));
event_list_item_view_->GetViewByID(kTimeLabelID));
}
const views::View* GetEventListItemDot() {
return static_cast<views::View*>(
event_list_item_view_jelly_->GetViewByID(kEventListItemDotID));
event_list_item_view_->GetViewByID(kEventListItemDotID));
}
const views::Button* GetJoinButton() {
return static_cast<views::Button*>(
event_list_item_view_jelly_->GetViewByID(kJoinButtonID));
event_list_item_view_->GetViewByID(kJoinButtonID));
}
CalendarViewController* controller() { return controller_.get(); }
CalendarEventListItemViewJelly* event_list_item_view() {
return event_list_item_view_jelly_.get();
CalendarEventListItemView* event_list_item_view() {
return event_list_item_view_.get();
}
private:
std::unique_ptr<CalendarEventListItemViewJelly> event_list_item_view_jelly_;
std::unique_ptr<CalendarEventListItemView> event_list_item_view_;
std::unique_ptr<CalendarViewController> controller_;
base::test::ScopedFeatureList features_;
};
TEST_F(CalendarViewEventListItemViewJellyTest,
TEST_F(CalendarViewEventListItemViewTest,
ShouldShowCorrectLabels_GivenAOneHourEvent) {
ash::system::ScopedTimezoneSettings timezone_settings(u"GMT+2");
calendar_test_utils::ScopedLibcTimeZone scoped_libc_timezone("GMT+2");
@ -134,7 +132,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest,
event_list_item_view()->GetAccessibleName());
}
TEST_F(CalendarViewEventListItemViewJellyTest,
TEST_F(CalendarViewEventListItemViewTest,
EventListViewItemTopRoundedCorners) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));
@ -152,7 +150,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest,
background_layer->rounded_corner_radii());
}
TEST_F(CalendarViewEventListItemViewJellyTest,
TEST_F(CalendarViewEventListItemViewTest,
EventListViewItemBottomRoundedCorners) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));
@ -171,7 +169,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest,
background_layer->rounded_corner_radii());
}
TEST_F(CalendarViewEventListItemViewJellyTest,
TEST_F(CalendarViewEventListItemViewTest,
EventListViewItemAllRoundedCorners) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));
@ -190,7 +188,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest,
background_layer->rounded_corner_radii());
}
TEST_F(CalendarViewEventListItemViewJellyTest, UpNextViewItemRoundedCorners) {
TEST_F(CalendarViewEventListItemViewTest, UpNextViewItemRoundedCorners) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));
SetSelectedDateInController(date);
@ -209,7 +207,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest, UpNextViewItemRoundedCorners) {
background_layer->rounded_corner_radii());
}
TEST_F(CalendarViewEventListItemViewJellyTest, FixedLabelWidth) {
TEST_F(CalendarViewEventListItemViewTest, FixedLabelWidth) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));
SetSelectedDateInController(date);
@ -236,7 +234,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest, FixedLabelWidth) {
EXPECT_EQ(fixed_width, GetSummaryLabel()->width());
}
TEST_F(CalendarViewEventListItemViewJellyTest,
TEST_F(CalendarViewEventListItemViewTest,
ShouldShowAndHideEventListItemDot) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));
@ -266,7 +264,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest,
EXPECT_TRUE(GetEventListItemDot());
}
TEST_F(CalendarViewEventListItemViewJellyTest,
TEST_F(CalendarViewEventListItemViewTest,
ShouldShowJoinMeetingButton_WhenConferenceDataUrlExists) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));
@ -281,7 +279,7 @@ TEST_F(CalendarViewEventListItemViewJellyTest,
EXPECT_TRUE(GetJoinButton());
}
TEST_F(CalendarViewEventListItemViewJellyTest,
TEST_F(CalendarViewEventListItemViewTest,
ShouldHideJoinMeetingButton_WhenConferenceDataUrlDoesNotExist) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("22 Nov 2021 00:00 UTC", &date));

@ -6,18 +6,15 @@
#include <memory>
#include "ash/bubble/bubble_constants.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/ash_typography.h"
#include "ash/public/cpp/system_tray_client.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_id.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/icon_button.h"
#include "ash/style/pill_button.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/time/calendar_event_list_item_view.h"
#include "ash/system/time/calendar_event_list_item_view_jelly.h"
#include "ash/system/time/calendar_metrics.h"
#include "ash/system/time/calendar_utils.h"
#include "ash/system/time/calendar_view_controller.h"
@ -28,12 +25,9 @@
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/vector_icons.h"
@ -43,12 +37,10 @@ namespace ash {
namespace {
// The paddings in `close_button_container_`.
const auto kCloseButtonContainerInsets = gfx::Insets(15);
const auto kCloseButtonContainerInsetsJelly = gfx::Insets::VH(8, 16);
const auto kCloseButtonContainerInsets = gfx::Insets::VH(8, 16);
// The paddings in `CalendarEventListView`.
constexpr auto kContentInsets = gfx::Insets::TLBR(0, 0, 20, 0);
constexpr auto kContentInsetsJelly = gfx::Insets::TLBR(0, 16, 16, 16);
constexpr auto kContentInsets = gfx::Insets::TLBR(0, 16, 16, 16);
// The insets for `CalendarEmptyEventListView`.
constexpr auto kOpenGoogleCalendarContainerInsets = gfx::Insets::VH(20, 60);
@ -57,20 +49,15 @@ constexpr auto kOpenGoogleCalendarContainerInsets = gfx::Insets::VH(20, 60);
constexpr int kOpenGoogleCalendarBorderThickness = 1;
constexpr auto kEventListViewCornerRadius =
gfx::RoundedCornersF(0, 0, kBubbleCornerRadius, kBubbleCornerRadius);
constexpr auto kEventListViewCornerRadiusJelly =
gfx::RoundedCornersF(24, 24, kBubbleCornerRadius, kBubbleCornerRadius);
constexpr int kScrollViewGradientSize = 16;
// The spacing between the child lists. Only applicable to Jelly, where we
// separate multi-day and non multi-day events into two separate child list
// views.
constexpr int kEventListViewBetweenChildSpacing = 0;
constexpr int kEventListViewBetweenChildSpacingJelly = 8;
// The spacing between the child lists where we separate multi-day and non
// multi-day events into two separate child list views.
constexpr int kEventListViewBetweenChildSpacing = 8;
// The between child spacing within the child event lists. Only applicable to
// Jelly.
// The between child spacing within the child event lists.
constexpr int kChildEventListBetweenChildSpacing = 2;
} // namespace
@ -140,18 +127,15 @@ CalendarEventListView::CalendarEventListView(
layer()->SetFillsBoundsOpaquely(false);
// Set the bottom corners to be rounded so that `CalendarEventListView` is
// contained in `CalendarView`.
layer()->SetRoundedCornerRadius(features::IsCalendarJellyEnabled()
? kEventListViewCornerRadiusJelly
: kEventListViewCornerRadius);
layer()->SetRoundedCornerRadius(kEventListViewCornerRadius);
views::BoxLayout* button_layout = close_button_container_->SetLayoutManager(
std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
button_layout->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kEnd);
close_button_container_->SetBorder(views::CreateEmptyBorder(
features::IsCalendarJellyEnabled() ? kCloseButtonContainerInsetsJelly
: kCloseButtonContainerInsets));
close_button_container_->SetBorder(
views::CreateEmptyBorder(kCloseButtonContainerInsets));
close_button_ =
close_button_container_->AddChildView(std::make_unique<IconButton>(
@ -171,21 +155,15 @@ CalendarEventListView::CalendarEventListView(
scroll_view_->SetVerticalScrollBarMode(
views::ScrollView::ScrollBarMode::kHiddenButEnabled);
if (features::IsCalendarJellyEnabled()) {
// Set up fade in/fade out gradients at top/bottom of scroll view.
scroll_view_->SetPaintToLayer(ui::LAYER_NOT_DRAWN);
gradient_helper_ = std::make_unique<ScrollViewGradientHelper>(
scroll_view_, kScrollViewGradientSize);
}
// Set up fade in/fade out gradients at top/bottom of scroll view.
scroll_view_->SetPaintToLayer(ui::LAYER_NOT_DRAWN);
gradient_helper_ = std::make_unique<ScrollViewGradientHelper>(
scroll_view_, kScrollViewGradientSize);
content_view_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, gfx::Insets(),
features::IsCalendarJellyEnabled()
? kEventListViewBetweenChildSpacingJelly
: kEventListViewBetweenChildSpacing));
content_view_->SetBorder(views::CreateEmptyBorder(
features::IsCalendarJellyEnabled() ? kContentInsetsJelly
: kContentInsets));
kEventListViewBetweenChildSpacing));
content_view_->SetBorder(views::CreateEmptyBorder(kContentInsets));
UpdateListItems();
@ -199,12 +177,8 @@ CalendarEventListView::~CalendarEventListView() = default;
void CalendarEventListView::OnThemeChanged() {
views::View::OnThemeChanged();
auto color =
features::IsCalendarJellyEnabled() && chromeos::features::IsJellyEnabled()
? GetColorProvider()->GetColor(
(cros_tokens::kCrosSysSystemOnBaseOpaque))
: GetColorProvider()->GetColor(kColorAshShieldAndBaseOpaque);
SetBackground(views::CreateSolidBackground(color));
SetBackground(views::CreateSolidBackground(
GetColorProvider()->GetColor(cros_tokens::kCrosSysSystemOnBaseOpaque)));
}
void CalendarEventListView::Layout() {
@ -214,10 +188,6 @@ void CalendarEventListView::Layout() {
gradient_helper_->UpdateGradientMask();
}
if (!features::IsCalendarJellyEnabled()) {
return;
}
const absl::optional<base::Time> selected_date =
calendar_view_controller_->selected_date();
@ -238,7 +208,7 @@ void CalendarEventListView::Layout() {
scroll_view_->vertical_scroll_bar(),
(multi_day_events_container
? multi_day_events_container->GetPreferredSize().height() +
kEventListViewBetweenChildSpacingJelly
kEventListViewBetweenChildSpacing
: 0) +
(current_or_next_event_view_->GetPreferredSize().height() +
kChildEventListBetweenChildSpacing) *
@ -249,7 +219,7 @@ void CalendarEventListView::Layout() {
// selected date is today.
scroll_view_->ScrollToPosition(
scroll_view_->vertical_scroll_bar(),
scroll_view_->GetVisibleRect().bottom() + kContentInsetsJelly.bottom());
scroll_view_->GetVisibleRect().bottom() + kContentInsets.bottom());
}
}
@ -285,8 +255,8 @@ std::unique_ptr<views::View> CalendarEventListView::CreateChildEventListView(
for (SingleDayEventList::iterator it = events.begin(); it != events.end();
++it) {
const int event_index = std::distance(events.begin(), it) + 1;
auto* event_list_item_view = container->AddChildView(
std::make_unique<CalendarEventListItemViewJelly>(
auto* event_list_item_view =
container->AddChildView(std::make_unique<CalendarEventListItemView>(
/*calendar_view_controller=*/calendar_view_controller_,
/*selected_date_params=*/
SelectedDateParams{
@ -325,49 +295,28 @@ void CalendarEventListView::UpdateListItems() {
current_or_next_event_view_ = nullptr;
current_or_next_event_index_ = 0;
if (features::IsCalendarJellyEnabled()) {
const auto [multi_day_events, all_other_events] =
calendar_view_controller_
->SelectedDateEventsSplitByMultiDayAndSameDay();
const auto [multi_day_events, all_other_events] =
calendar_view_controller_->SelectedDateEventsSplitByMultiDayAndSameDay();
// If we have some events to display, then add them to the `content_view_`
// and early return (the following methods in `UpdateListItems` handle empty
// state etc).
if (!multi_day_events.empty()) {
content_view_->AddChildView(CreateChildEventListView(
multi_day_events, kEventListMultiDayEventsContainer));
}
if (!all_other_events.empty()) {
content_view_->AddChildView(CreateChildEventListView(
all_other_events, kEventListSameDayEventsContainer));
}
// If we have some events to display, then add them to the `content_view_`
// and early return (the following methods in `UpdateListItems` handle empty
// state etc).
if (!multi_day_events.empty()) {
content_view_->AddChildView(CreateChildEventListView(
multi_day_events, kEventListMultiDayEventsContainer));
}
if (!all_other_events.empty()) {
content_view_->AddChildView(CreateChildEventListView(
all_other_events, kEventListSameDayEventsContainer));
}
content_view_->InvalidateLayout();
content_view_->InvalidateLayout();
calendar_metrics::RecordEventListEventCount(multi_day_events.size() +
all_other_events.size());
calendar_metrics::RecordEventListEventCount(multi_day_events.size() +
all_other_events.size());
if (!multi_day_events.empty() || !all_other_events.empty()) {
return;
}
} else {
std::list<google_apis::calendar::CalendarEvent> events =
calendar_view_controller_->SelectedDateEvents();
calendar_metrics::RecordEventListEventCount(events.size());
if (events.size() > 0) {
for (auto& event : events) {
auto* event_entry = content_view_->AddChildView(
std::make_unique<CalendarEventListItemView>(
/*calendar_view_controller=*/calendar_view_controller_,
/*event=*/event));
// Needs to repaint the `content_view_`'s children.
event_entry->InvalidateLayout();
}
return;
}
if (!multi_day_events.empty() || !all_other_events.empty()) {
return;
}
// Show "Open in Google calendar"

@ -4,18 +4,15 @@
#include "ash/system/time/calendar_event_list_view.h"
#include "ash/constants/ash_features.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/time/calendar_event_list_item_view.h"
#include "ash/system/time/calendar_event_list_item_view_jelly.h"
#include "ash/system/time/calendar_unittest_utils.h"
#include "ash/system/time/calendar_utils.h"
#include "ash/system/time/calendar_view_controller.h"
#include "ash/test/ash_test_base.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "chromeos/ash/components/settings/scoped_timezone_settings.h"
#include "google_apis/common/api_error_codes.h"
@ -86,8 +83,6 @@ class CalendarViewEventListViewTest : public AshTestBase,
~CalendarViewEventListViewTest() override = default;
void SetUp() override {
scoped_feature_list_.InitWithFeatureState(features::kCalendarJelly,
IsCalendarJellyEnabled());
AshTestBase::SetUp();
controller_ = std::make_unique<CalendarViewController>();
widget_ = CreateFramelessTestWidget();
@ -150,15 +145,10 @@ class CalendarViewEventListViewTest : public AshTestBase,
}
views::Label* GetSummary(int child_index) {
return features::IsCalendarJellyEnabled()
? static_cast<views::Label*>(
static_cast<CalendarEventListItemViewJelly*>(
GetSameDayEventsContainer()->children()[child_index])
->GetViewByID(kSummaryLabelID))
: static_cast<views::Label*>(
static_cast<CalendarEventListItemView*>(
content_view()->children()[child_index])
->summary_);
return static_cast<views::Label*>(
static_cast<CalendarEventListItemView*>(
GetSameDayEventsContainer()->children()[child_index])
->GetViewByID(kSummaryLabelID));
}
std::u16string GetEmptyLabel() {
@ -168,21 +158,15 @@ class CalendarViewEventListViewTest : public AshTestBase,
}
views::View* GetHighlightView(int child_index) {
return features::IsCalendarJellyEnabled()
? GetSameDayEventsContainer()->children()[child_index]
: content_view()->children()[child_index];
return GetSameDayEventsContainer()->children()[child_index];
}
size_t GetContentViewSize() {
return features::IsCalendarJellyEnabled()
? GetSameDayEventsContainer()->children().size()
: content_view()->children().size();
return GetSameDayEventsContainer()->children().size();
}
size_t GetEmptyContentViewSize() { return content_view()->children().size(); }
bool IsCalendarJellyEnabled() { return GetParam(); }
static base::Time FakeTimeNow() { return fake_time_; }
static void SetFakeNow(base::Time fake_now) { fake_time_ = fake_now; }
@ -191,7 +175,6 @@ class CalendarViewEventListViewTest : public AshTestBase,
std::unique_ptr<CalendarEventListView> event_list_view_;
std::unique_ptr<CalendarViewController> controller_;
static base::Time fake_time_;
base::test::ScopedFeatureList scoped_feature_list_;
};
base::Time CalendarViewEventListViewTest::fake_time_;
@ -256,7 +239,7 @@ TEST_P(CalendarViewEventListViewTest, LaunchEmptyList) {
histogram_tester.ExpectTotalCount(
"Ash.Calendar.UserJourneyTime.EventLaunched", 1);
EXPECT_EQ(histogram_tester.GetTotalSum(
"Ash.Calendar.EventListView.EventDisplayedCount"),
"Ash.Calendar.EventListViewJelly.EventDisplayedCount"),
0);
}
@ -265,9 +248,7 @@ TEST_P(CalendarViewEventListViewTest, LaunchItem) {
base::Time date;
ASSERT_TRUE(base::Time::FromString("18 Nov 2021 10:00 GMT", &date));
CreateEventListView(date);
if (features::IsCalendarJellyEnabled()) {
SetEventListIsShowingForMetrics();
}
SetEventListIsShowingForMetrics();
EXPECT_EQ(3u, GetContentViewSize());
// Launch the first item.
@ -279,9 +260,7 @@ TEST_P(CalendarViewEventListViewTest, LaunchItem) {
"Ash.Calendar.UserJourneyTime.EventLaunched", 1);
histogram_tester.ExpectTotalCount("Ash.Calendar.EventListItem.Activated", 1);
EXPECT_EQ(histogram_tester.GetTotalSum(
features::IsCalendarJellyEnabled()
? "Ash.Calendar.EventListViewJelly.EventDisplayedCount"
: "Ash.Calendar.EventListView.EventDisplayedCount"),
"Ash.Calendar.EventListViewJelly.EventDisplayedCount"),
3);
}
@ -321,10 +300,6 @@ TEST_P(CalendarViewEventListViewTest, RefreshEvents) {
}
TEST_P(CalendarViewEventListViewTest, ScrollToCurrentOrNextEvent) {
if (!features::IsCalendarJellyEnabled()) {
return;
}
// Sets the timezone to GMT. Otherwise in other timezones events can become
// multi-day events that will be ignored when calculating index.
ash::system::ScopedTimezoneSettings timezone_settings(u"GMT");
@ -361,10 +336,6 @@ TEST_P(CalendarViewEventListViewTest, ScrollToCurrentOrNextEvent) {
TEST_P(CalendarViewEventListViewTest,
ScrollToCurrentOrNextEvent_WithMultiDayEvents) {
if (!features::IsCalendarJellyEnabled()) {
return;
}
// Sets the timezone to HST. The first two events become multi-day events, and
// will be ignored when calculating index.
ash::system::ScopedTimezoneSettings timezone_settings(u"Pacific/Honolulu");
@ -400,10 +371,6 @@ TEST_P(CalendarViewEventListViewTest,
TEST_P(CalendarViewEventListViewTest,
ScrollToCurrentOrNextEvent_PassedDatesStayAtTop) {
if (!features::IsCalendarJellyEnabled()) {
return;
}
// Sets the timezone to GMT. Otherwise in other timezones events can become
// multi-day events that will be ignored when calculating index.
ash::system::ScopedTimezoneSettings timezone_settings(u"GMT");
@ -437,10 +404,6 @@ TEST_P(CalendarViewEventListViewTest,
TEST_P(CalendarViewEventListViewTest,
ScrollToCurrentOrNextEvent_FutureDatesStaysAtTop) {
if (!features::IsCalendarJellyEnabled()) {
return;
}
// Sets the timezone to GMT. Otherwise in other timezones events can become
// multi-day events that will be ignored when calculating index.
ash::system::ScopedTimezoneSettings timezone_settings(u"GMT");

@ -4,9 +4,7 @@
#include "ash/system/time/calendar_metrics.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/metrics_util.h"
#include "base/check_op.h"
#include "base/metrics/histogram_functions.h"
#include "base/notreached.h"
#include "base/time/time.h"
@ -43,8 +41,6 @@ constexpr char kCalendarEventListItemJoinButtonPressed[] =
constexpr char kCalendarUpNextJoinButtonPressed[] =
"Ash.Calendar.UpNextView.JoinMeetingButton.Pressed";
constexpr char kCalendarEventListEventDisplayedCount[] =
"Ash.Calendar.EventListView.EventDisplayedCount";
constexpr char kCalendarEventListJellyEventDisplayedCount[] =
"Ash.Calendar.EventListViewJelly.EventDisplayedCount";
constexpr char kCalendarEventsDisplayedToUser[] =
"Ash.Calendar.EventsDisplayedToUser";
@ -149,12 +145,6 @@ void RecordJoinButtonPressedFromUpNextView(const ui::Event& event) {
}
void RecordEventListEventCount(const int event_count) {
if (features::IsCalendarJellyEnabled()) {
base::UmaHistogramCounts100(kCalendarEventListJellyEventDisplayedCount,
event_count);
return;
}
base::UmaHistogramCounts100(kCalendarEventListEventDisplayedCount,
event_count);
}

@ -4,11 +4,9 @@
#include "ash/system/time/calendar_month_view.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/ash_typography.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_id.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/typography.h"
#include "ash/system/model/system_tray_model.h"
@ -17,16 +15,13 @@
#include "ash/system/time/calendar_utils.h"
#include "ash/system/time/calendar_view_controller.h"
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chromeos/constants/chromeos_features.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/color/color_id.h"
#include "ui/color/color_provider.h"
#include "ui/compositor/layer.h"
#include "ui/events/event.h"
@ -46,24 +41,16 @@ constexpr int kBorderLineThickness = 2;
// The radius used to draw the border.
constexpr float kBorderRadius = 21.f;
// The default radius used to draw rounded today's circle.
constexpr float kTodayRoundedRadius = 22.f;
// The radius used to draw "today's" date cell view border and background .
constexpr float kTodayBorderRadius = 100.f;
// The radius used to draw rounded today's circle when focused.
constexpr float kTodayFocusedRoundedRadius = 18.f;
// The radius used to draw "today's" date cell view border and background with
// `kCalendarJelly` enabled.
constexpr float kTodayBorderRadiusJelly = 100.f;
// The insets used to draw "today's" date cell view with `kCalendarJelly`
// enabled.
constexpr float kTodayRoundedBackgroundHorizontalInsetJelly = 8.f;
constexpr float kTodayRoundedBackgroundVerticalInsetJelly = 0.f;
constexpr float kTodayRoundedBackgroundHorizontalFocusedInsetJelly =
kTodayRoundedBackgroundHorizontalInsetJelly + kBorderLineThickness + 2.f;
constexpr float kTodayRoundedBackgroundVerticalFocusedInsetJelly =
kTodayRoundedBackgroundVerticalInsetJelly + kBorderLineThickness + 2.f;
// The insets used to draw "today's" date cell view.
constexpr float kTodayRoundedBackgroundHorizontalInset = 8.f;
constexpr float kTodayRoundedBackgroundVerticalInset = 0.f;
constexpr float kTodayRoundedBackgroundHorizontalFocusedInset =
kTodayRoundedBackgroundHorizontalInset + kBorderLineThickness + 2.f;
constexpr float kTodayRoundedBackgroundVerticalFocusedInset =
kTodayRoundedBackgroundVerticalInset + kBorderLineThickness + 2.f;
// Radius of the small dot displayed on a CalendarDateCellView if events are
// present for that day.
@ -114,19 +101,15 @@ CalendarDateCellView::CalendarDateCellView(
time_difference_(time_difference),
calendar_view_controller_(calendar_view_controller) {
SetHorizontalAlignment(gfx::ALIGN_CENTER);
SetBorder(views::CreateEmptyBorder(features::IsCalendarJellyEnabled()
? calendar_utils::kDateCellInsetsJelly
: calendar_utils::kDateCellInsets));
SetBorder(views::CreateEmptyBorder(calendar_utils::kDateCellInsets));
label()->SetElideBehavior(gfx::NO_ELIDE);
label()->SetSubpixelRenderingEnabled(false);
if (features::IsCalendarJellyEnabled()) {
if (is_today_) {
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosButton1,
*label());
} else {
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1,
*label());
}
if (is_today_) {
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosButton1,
*label());
} else {
TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosBody1,
*label());
}
views::FocusRing::Remove(this);
@ -149,13 +132,8 @@ void CalendarDateCellView::OnThemeChanged() {
views::View::OnThemeChanged();
// Gray-out the date that is not in the current month.
if (features::IsCalendarJellyEnabled()) {
SetEnabledTextColorIds(grayed_out_ ? cros_tokens::kCrosSysOnSurfaceVariant
: cros_tokens::kCrosSysOnSurface);
} else {
SetEnabledTextColors(grayed_out_ ? calendar_utils::GetDisabledTextColor()
: calendar_utils::GetPrimaryTextColor());
}
SetEnabledTextColorIds(grayed_out_ ? cros_tokens::kCrosSysOnSurfaceVariant
: cros_tokens::kCrosSysOnSurface);
}
// Draws the background for this date. Note that this includes not only the
@ -170,99 +148,59 @@ void CalendarDateCellView::OnPaintBackground(gfx::Canvas* canvas) {
const gfx::Rect content = GetContentsBounds();
const gfx::SizeF local_bounds = gfx::SizeF(GetLocalBounds().size());
if (features::IsCalendarJellyEnabled()) {
const SkColor border_color =
GetColorProvider()->GetColor(cros_tokens::kCrosSysFocusRing);
cc::PaintFlags highlight_border;
highlight_border.setColor(border_color);
highlight_border.setAntiAlias(true);
highlight_border.setStyle(cc::PaintFlags::kStroke_Style);
highlight_border.setStrokeWidth(kBorderLineThickness);
if (is_today_) {
gfx::RectF background_rect(local_bounds);
const SkColor bg_color = GetColorProvider()->GetColor(
cros_tokens::kCrosSysSystemPrimaryContainer);
cc::PaintFlags highlight_background;
highlight_background.setColor(bg_color);
highlight_background.setStyle(cc::PaintFlags::kFill_Style);
highlight_background.setAntiAlias(true);
// If the today view is focused, we draw a border around the background
// and inset the background a couple of pixels to leave 2dp of space
// between.
// Else we just draw the background full size with no border.
if (views::View::HasFocus()) {
gfx::RectF border_rect(local_bounds);
const int half_stroke_thickness = kBorderLineThickness / 2;
border_rect.Inset(
gfx::InsetsF::VH(half_stroke_thickness,
kTodayRoundedBackgroundHorizontalInsetJelly));
canvas->DrawRoundRect(border_rect, kTodayBorderRadiusJelly,
highlight_border);
background_rect.Inset(gfx::InsetsF::VH(
kTodayRoundedBackgroundVerticalFocusedInsetJelly,
kTodayRoundedBackgroundHorizontalFocusedInsetJelly));
canvas->DrawRoundRect(background_rect, kTodayBorderRadiusJelly,
highlight_background);
return;
}
background_rect.Inset(
gfx::InsetsF::VH(kTodayRoundedBackgroundVerticalInsetJelly,
kTodayRoundedBackgroundHorizontalInsetJelly));
canvas->DrawRoundRect(background_rect, kTodayBorderRadiusJelly,
highlight_background);
return;
}
// If !today and view is focused or selected, draw a circle around the view.
if (views::View::HasFocus() || is_selected_) {
const gfx::Point center(
(content.width() + calendar_utils::kDateHorizontalPaddingJelly * 2) /
2,
(content.height() + calendar_utils::kDateVerticalPadding * 2) / 2);
canvas->DrawCircle(center, kBorderRadius, highlight_border);
}
return;
}
// Pre-jelly code.
const AshColorProvider* color_provider = AshColorProvider::Get();
const SkColor bg_color = color_provider->GetControlsLayerColor(
AshColorProvider::ControlsLayerType::kControlBackgroundColorActive);
const SkColor border_color = color_provider->GetControlsLayerColor(
AshColorProvider::ControlsLayerType::kFocusRingColor);
const gfx::Point center(
(content.width() + calendar_utils::kDateHorizontalPadding * 2) / 2,
(content.height() + calendar_utils::kDateVerticalPadding * 2) / 2);
if (views::View::HasFocus()) {
cc::PaintFlags highlight_border;
highlight_border.setColor(border_color);
highlight_border.setAntiAlias(true);
highlight_border.setStyle(cc::PaintFlags::kStroke_Style);
highlight_border.setStrokeWidth(kBorderLineThickness);
canvas->DrawCircle(center, kBorderRadius, highlight_border);
}
const SkColor border_color =
GetColorProvider()->GetColor(cros_tokens::kCrosSysFocusRing);
cc::PaintFlags highlight_border;
highlight_border.setColor(border_color);
highlight_border.setAntiAlias(true);
highlight_border.setStyle(cc::PaintFlags::kStroke_Style);
highlight_border.setStrokeWidth(kBorderLineThickness);
if (is_today_) {
gfx::RectF background_rect(local_bounds);
const SkColor bg_color = GetColorProvider()->GetColor(
cros_tokens::kCrosSysSystemPrimaryContainer);
cc::PaintFlags highlight_background;
highlight_background.setColor(bg_color);
highlight_background.setStyle(cc::PaintFlags::kFill_Style);
highlight_background.setAntiAlias(true);
canvas->DrawCircle(center,
views::View::HasFocus() ? kTodayFocusedRoundedRadius
: kTodayRoundedRadius,
highlight_background);
// If the today view is focused, we draw a border around the background
// and inset the background a couple of pixels to leave 2dp of space
// between.
// Else we just draw the background full size with no border.
if (views::View::HasFocus()) {
gfx::RectF border_rect(local_bounds);
const int half_stroke_thickness = kBorderLineThickness / 2;
border_rect.Inset(gfx::InsetsF::VH(
half_stroke_thickness, kTodayRoundedBackgroundHorizontalInset));
canvas->DrawRoundRect(border_rect, kTodayBorderRadius, highlight_border);
background_rect.Inset(
gfx::InsetsF::VH(kTodayRoundedBackgroundVerticalFocusedInset,
kTodayRoundedBackgroundHorizontalFocusedInset));
canvas->DrawRoundRect(background_rect, kTodayBorderRadius,
highlight_background);
return;
}
background_rect.Inset(
gfx::InsetsF::VH(kTodayRoundedBackgroundVerticalInset,
kTodayRoundedBackgroundHorizontalInset));
canvas->DrawRoundRect(background_rect, kTodayBorderRadius,
highlight_background);
return;
}
// If !today and view is focused or selected, draw a circle around the view.
if (views::View::HasFocus() || is_selected_) {
const gfx::Point center(
(content.width() + calendar_utils::kDateHorizontalPadding * 2) / 2,
(content.height() + calendar_utils::kDateVerticalPadding * 2) / 2);
canvas->DrawCircle(center, kBorderRadius, highlight_border);
}
}
@ -383,26 +321,9 @@ void CalendarDateCellView::PaintButtonContents(gfx::Canvas* canvas) {
return;
}
if (features::IsCalendarJellyEnabled()) {
SetEnabledTextColorIds(is_today_
? cros_tokens::kCrosSysSystemOnPrimaryContainer
: cros_tokens::kCrosSysOnSurface);
} else {
const AshColorProvider* color_provider = AshColorProvider::Get();
if (is_today_) {
const SkColor text_color = color_provider->GetContentLayerColor(
AshColorProvider::ContentLayerType::kButtonLabelColorPrimary);
SetEnabledTextColors(text_color);
} else if (is_selected_) {
SetEnabledTextColors(color_provider->GetContentLayerColor(
AshColorProvider::ContentLayerType::kIconColorProminent));
} else {
SkColor text_color = grayed_out_ ? calendar_utils::GetSecondaryTextColor()
: calendar_utils::GetPrimaryTextColor();
SetEnabledTextColors(text_color);
}
}
SetEnabledTextColorIds(is_today_
? cros_tokens::kCrosSysSystemOnPrimaryContainer
: cros_tokens::kCrosSysOnSurface);
MaybeDrawEventsIndicator(canvas);
}
@ -421,10 +342,7 @@ void CalendarDateCellView::OnDateCellActivated(const ui::Event& event) {
gfx::Point CalendarDateCellView::GetEventsPresentIndicatorCenterPosition() {
const gfx::Rect content = GetContentsBounds();
const int horizontal_padding =
(features::IsCalendarJellyEnabled()
? calendar_utils::kDateHorizontalPaddingJelly
: calendar_utils::kDateHorizontalPadding);
const int horizontal_padding = calendar_utils::kDateHorizontalPadding;
return gfx::Point((content.width() + horizontal_padding * 2) / 2,
content.height() + calendar_utils::kDateVerticalPadding +
kGapBetweenDateAndIndicator);
@ -442,13 +360,9 @@ void CalendarDateCellView::MaybeDrawEventsIndicator(gfx::Canvas* canvas) {
}
const auto* color_provider = GetColorProvider();
const SkColor jelly_color = color_provider->GetColor(
const SkColor indicator_color = color_provider->GetColor(
is_today_ ? cros_tokens::kCrosSysSystemOnPrimaryContainer
: cros_tokens::kCrosSysOnSurface);
const SkColor indicator_color =
features::IsCalendarJellyEnabled() ? jelly_color
: is_today_ ? color_provider->GetColor(kColorAshShieldAndBase90)
: color_provider->GetColor(ui::kColorAshFocusRing);
const float indicator_radius = is_selected_ ? kEventsPresentRoundedRadius * 2
: kEventsPresentRoundedRadius;

@ -13,9 +13,7 @@
#include "ash/test/pixel/ash_pixel_differ.h"
#include "ash/test/pixel/ash_pixel_test_init_params.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "chromeos/constants/chromeos_features.h"
#include "google_apis/calendar/calendar_api_response_types.h"
namespace ash {
@ -44,9 +42,6 @@ class CalendarUpNextViewPixelTest : public AshTestBase {
// AshTestBase:
void SetUp() override {
scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
scoped_feature_list_->InitWithFeatures(
{chromeos::features::kJelly, features::kCalendarJelly}, {});
AshTestBase::SetUp();
controller_ = std::make_unique<CalendarViewController>();
@ -114,7 +109,6 @@ class CalendarUpNextViewPixelTest : public AshTestBase {
raw_ptr<CalendarUpNextView, DanglingUntriaged | ExperimentalAsh>
up_next_view_ = nullptr;
std::unique_ptr<CalendarViewController> controller_;
std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
};
TEST_F(CalendarUpNextViewPixelTest,

@ -8,22 +8,19 @@
#include <memory>
#include "ash/bubble/bubble_utils.h"
#include "ash/public/cpp/ash_view_ids.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/icon_button.h"
#include "ash/style/typography.h"
#include "ash/system/time/calendar_event_list_item_view_jelly.h"
#include "ash/system/time/calendar_event_list_item_view.h"
#include "ash/system/time/calendar_metrics.h"
#include "ash/system/time/calendar_up_next_view_background_painter.h"
#include "ash/system/time/calendar_utils.h"
#include "ash/system/tray/tray_constants.h"
#include "base/i18n/rtl.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/compositor/layer.h"
#include "ui/events/types/event_type.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/background.h"
@ -305,8 +302,8 @@ void CalendarUpNextView::UpdateEvents(
// Single events are displayed filling the whole width of the tray.
if (events.size() == 1) {
const auto event = events.back();
auto* child_view = content_view_->AddChildView(
std::make_unique<CalendarEventListItemViewJelly>(
auto* child_view =
content_view_->AddChildView(std::make_unique<CalendarEventListItemView>(
calendar_view_controller_,
SelectedDateParams{now, selected_date_midnight,
selected_date_midnight_utc},
@ -337,20 +334,19 @@ void CalendarUpNextView::UpdateEvents(
const int events_size = events.size();
for (auto it = events.begin(); it != events.end(); ++it) {
const int event_index = std::distance(events.begin(), it) + 1;
content_view_->AddChildView(
std::make_unique<CalendarEventListItemViewJelly>(
calendar_view_controller_,
SelectedDateParams{now, selected_date_midnight,
selected_date_midnight_utc},
/*event=*/*it,
/*ui_params=*/
UIParams{/*round_top_corners=*/true, /*round_bottom_corners=*/true,
/*is_up_next_event_list_item=*/true,
/*show_event_list_dot=*/false,
/*fixed_width=*/kLabelCappedWidth},
/*event_list_item_index=*/
EventListItemIndex{/*item_index=*/event_index,
/*total_count_of_events=*/events_size}));
content_view_->AddChildView(std::make_unique<CalendarEventListItemView>(
calendar_view_controller_,
SelectedDateParams{now, selected_date_midnight,
selected_date_midnight_utc},
/*event=*/*it,
/*ui_params=*/
UIParams{/*round_top_corners=*/true, /*round_bottom_corners=*/true,
/*is_up_next_event_list_item=*/true,
/*show_event_list_dot=*/false,
/*fixed_width=*/kLabelCappedWidth},
/*event_list_item_index=*/
EventListItemIndex{/*item_index=*/event_index,
/*total_count_of_events=*/events_size}));
}
// Show scroll buttons if we have multiple events.

@ -7,7 +7,7 @@
#include "ash/public/cpp/test/test_system_tray_client.h"
#include "ash/shell.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/time/calendar_event_list_item_view_jelly.h"
#include "ash/system/time/calendar_event_list_item_view.h"
#include "ash/system/time/calendar_unittest_utils.h"
#include "ash/system/time/calendar_view_controller.h"
#include "ash/system/tray/tray_constants.h"
@ -555,7 +555,7 @@ TEST_F(CalendarUpNextViewTest, ShouldFocusViewsInCorrectOrder_WhenPressingTab) {
auto* first_item = GetContentsView()->children()[0];
ASSERT_TRUE(first_item);
EXPECT_EQ(first_item, focus_manager->GetFocusedView());
EXPECT_STREQ("CalendarEventListItemViewJelly",
EXPECT_STREQ("CalendarEventListItemView",
focus_manager->GetFocusedView()->GetClassName());
// Next, the "Join" button should be focused.
@ -568,7 +568,7 @@ TEST_F(CalendarUpNextViewTest, ShouldFocusViewsInCorrectOrder_WhenPressingTab) {
auto* second_item = GetContentsView()->children()[1];
ASSERT_TRUE(second_item);
EXPECT_EQ(second_item, focus_manager->GetFocusedView());
EXPECT_STREQ("CalendarEventListItemViewJelly",
EXPECT_STREQ("CalendarEventListItemView",
focus_manager->GetFocusedView()->GetClassName());
// Next, the second event list item view "Join" button should be focused.
@ -589,7 +589,7 @@ TEST_F(CalendarUpNextViewTest, ShouldFocusViewsInCorrectOrder_WhenPressingTab) {
// Going back again, the second event list item view should be focused.
PressShiftTab();
EXPECT_EQ(second_item, focus_manager->GetFocusedView());
EXPECT_STREQ("CalendarEventListItemViewJelly",
EXPECT_STREQ("CalendarEventListItemView",
focus_manager->GetFocusedView()->GetClassName());
}
@ -611,7 +611,7 @@ TEST_F(CalendarUpNextViewTest, ShouldPreserveFocusAfterRefreshEvent) {
auto* first_item = GetContentsView()->children()[0];
ASSERT_TRUE(first_item);
EXPECT_EQ(first_item, focus_manager->GetFocusedView());
EXPECT_STREQ("CalendarEventListItemViewJelly",
EXPECT_STREQ("CalendarEventListItemView",
focus_manager->GetFocusedView()->GetClassName());
up_next_view()->RefreshEvents();
@ -619,7 +619,7 @@ TEST_F(CalendarUpNextViewTest, ShouldPreserveFocusAfterRefreshEvent) {
// After refresh the events, the first event list item view should still be
// focused.
EXPECT_EQ(first_item, focus_manager->GetFocusedView());
EXPECT_STREQ("CalendarEventListItemViewJelly",
EXPECT_STREQ("CalendarEventListItemView",
focus_manager->GetFocusedView()->GetClassName());
}

@ -4,10 +4,8 @@
#include "ash/system/time/calendar_utils.h"
#include <map>
#include <string>
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
@ -17,11 +15,9 @@
#include "base/i18n/time_formatting.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chromeos/ash/components/settings/timezone_settings.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_type.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/icu/source/i18n/unicode/gregocal.h"
#include "ui/views/layout/table_layout.h"
namespace ash {
@ -176,17 +172,10 @@ std::u16string FormatTwentyFourHourClockTimeInterval(
}
void SetUpWeekColumns(views::TableLayout* layout) {
if (!features::IsCalendarJellyEnabled()) {
layout->AddPaddingColumn(views::TableLayout::kFixedSize, kColumnSetPadding);
}
for (int i = 0; i < calendar_utils::kDateInOneWeek; ++i) {
layout->AddColumn(views::LayoutAlignment::kStretch,
views::LayoutAlignment::kStretch, 1.0f,
views::TableLayout::ColumnSize::kFixed, 0, 0);
if (!features::IsCalendarJellyEnabled()) {
layout->AddPaddingColumn(views::TableLayout::kFixedSize,
kColumnSetPadding);
}
}
}

@ -32,8 +32,7 @@ constexpr int kMillisecondsPerMinute = 60000;
// The padding in each date cell view.
constexpr int kDateVerticalPadding = 13;
constexpr int kDateHorizontalPadding = 14;
constexpr int kDateHorizontalPaddingJelly = 16;
constexpr int kDateHorizontalPadding = 16;
constexpr int kColumnSetPadding = 5;
// The insets for the event list item view.
@ -42,8 +41,6 @@ constexpr int kEventListItemViewStartEndMargin = 12;
// The insets within a Date cell.
const auto kDateCellInsets =
gfx::Insets::VH(kDateVerticalPadding, kDateHorizontalPadding);
const auto kDateCellInsetsJelly =
gfx::Insets::VH(kDateVerticalPadding, kDateHorizontalPaddingJelly);
// Duration of opacity animation for visibility changes.
constexpr base::TimeDelta kAnimationDurationForVisibility =

@ -8,10 +8,7 @@
#include <string>
#include "ash/bubble/bubble_utils.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/ash_typography.h"
#include "ash/public/cpp/ash_view_ids.h"
#include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/system_tray_client.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/root_window_controller.h"
@ -37,10 +34,7 @@
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chromeos/constants/chromeos_features.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
@ -49,12 +43,8 @@
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/layer_type.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/compositor/presentation_time_recorder.h"
#include "ui/events/types/event_type.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/gfx/geometry/vector2d_f.h"
@ -68,8 +58,6 @@
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/table_layout.h"
#include "ui/views/style/typography.h"
#include "ui/views/style/typography_provider.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/view_utils.h"
@ -82,23 +70,19 @@ constexpr int kContentVerticalPadding = 20;
constexpr int kContentHorizontalPadding = 20;
constexpr int kMonthVerticalPadding = 10;
constexpr int kLabelVerticalPadding = 10;
constexpr int kLabelTextInBetweenPadding = 10;
constexpr int kLabelTextInBetweenPaddingJelly = 4;
constexpr int kWeekRowHorizontalPadding =
constexpr int kLabelTextInBetweenPadding = 4;
const int kWeekRowHorizontalPadding =
kContentHorizontalPadding - calendar_utils::kDateHorizontalPadding;
const int kWeekRowHorizontalPaddingJelly =
kContentHorizontalPadding - calendar_utils::kDateHorizontalPaddingJelly;
constexpr int kExpandedCalendarPadding = 11;
constexpr int kExpandedCalendarPaddingJelly = 10;
constexpr int kExpandedCalendarPadding = 10;
constexpr int kChevronPadding = calendar_utils::kColumnSetPadding - 1;
constexpr int kChevronPaddingJelly = 16;
constexpr int kChevronInBetweenPadding = 16;
constexpr int kMonthHeaderLabelTopPadding = 14;
constexpr int kMonthHeaderLabelBottomPadding = 2;
constexpr int kEventListViewHorizontalOffset = 1;
constexpr int kUpNextAnimationYOffset = 20;
// Adds a gap between the bottom visible row in the scrollview and the top of
// the event list view when open.
constexpr int kCalendarEventListViewOpenMarginJelly = 8;
constexpr int kCalendarEventListViewOpenMargin = 8;
// The offset for `month_label_` to make it align with `month_header`.
constexpr int kMonthLabelPaddingOffset = -1;
@ -209,9 +193,7 @@ std::unique_ptr<views::Label> CreateHeaderView(const std::u16string& month) {
}
std::unique_ptr<views::Label> CreateHeaderYearView(const std::u16string& year) {
const int label_padding = features::IsCalendarJellyEnabled()
? kLabelTextInBetweenPaddingJelly
: kLabelTextInBetweenPadding;
const int label_padding = kLabelTextInBetweenPadding;
return views::Builder<views::Label>(
bubble_utils::CreateLabel(TypographyToken::kCrosDisplay7, year,
@ -224,8 +206,7 @@ std::unique_ptr<views::Label> CreateHeaderYearView(const std::u16string& year) {
}
int GetExpandedCalendarPadding() {
return features::IsCalendarJellyEnabled() ? kExpandedCalendarPaddingJelly
: kExpandedCalendarPadding;
return kExpandedCalendarPadding;
}
// The overridden `Label` view used in `CalendarView`.
@ -257,22 +238,16 @@ class MonthHeaderView : public views::View {
for (const std::u16string& week_day :
DateHelper::GetInstance()->week_titles()) {
auto label = features::IsCalendarJellyEnabled()
? views::Builder<views::Label>(
bubble_utils::CreateLabel(
TypographyToken::kCrosButton1, week_day,
cros_tokens::kCrosSysOnSurface))
.Build()
: std::make_unique<CalendarLabel>(week_day);
auto label =
views::Builder<views::Label>(
bubble_utils::CreateLabel(TypographyToken::kCrosButton1, week_day,
cros_tokens::kCrosSysOnSurface))
.Build();
label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER);
label->SetBorder((views::CreateEmptyBorder(
gfx::Insets::VH(calendar_utils::kDateVerticalPadding, 0))));
label->SetElideBehavior(gfx::NO_ELIDE);
label->SetSubpixelRenderingEnabled(false);
if (!features::IsCalendarJellyEnabled()) {
label->SetFontList(views::TypographyProvider::Get().GetFont(
CONTEXT_CALENDAR_DATE, views::style::STYLE_EMPHASIZED));
}
AddChildView(std::move(label));
}
@ -328,15 +303,6 @@ class CalendarView::MonthHeaderLabelView : public views::View {
MonthHeaderLabelView& operator=(const MonthHeaderLabelView&) = delete;
~MonthHeaderLabelView() override = default;
// views::View:
void OnThemeChanged() override {
views::View::OnThemeChanged();
if (!features::IsCalendarJellyEnabled()) {
month_label_->SetEnabledColor(calendar_utils::GetPrimaryTextColor());
}
}
private:
// The name of the month.
std::u16string month_name_;
@ -420,15 +386,6 @@ CalendarHeaderView::CalendarHeaderView(const std::u16string& month,
CalendarHeaderView::~CalendarHeaderView() = default;
void CalendarHeaderView::OnThemeChanged() {
views::View::OnThemeChanged();
if (!features::IsCalendarJellyEnabled()) {
header_->SetEnabledColor(calendar_utils::GetPrimaryTextColor());
header_year_->SetEnabledColor(calendar_utils::GetSecondaryTextColor());
}
}
void CalendarHeaderView::UpdateHeaders(const std::u16string& month,
const std::u16string& year) {
header_->SetText(month);
@ -512,19 +469,14 @@ CalendarView::CalendarView(DetailedViewDelegate* delegate,
tri_view->AddView(TriView::Container::START, header_container);
auto* button_container = new views::View();
const int horizontal_padding = features::IsCalendarJellyEnabled()
? kWeekRowHorizontalPaddingJelly
: kWeekRowHorizontalPadding;
const int horizontal_padding = kWeekRowHorizontalPadding;
views::BoxLayout* button_container_layout =
button_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
button_container_layout->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kEnd);
// Aligns button with the calendar dates in the `TableLayout`.
button_container_layout->set_between_child_spacing(
features::IsCalendarJellyEnabled()
? kChevronPaddingJelly
: horizontal_padding + kChevronPadding);
button_container_layout->set_between_child_spacing(kChevronInBetweenPadding);
up_button_ = button_container->AddChildView(std::make_unique<IconButton>(
base::BindRepeating(&CalendarView::OnMonthArrowButtonActivated,
@ -2073,8 +2025,7 @@ void CalendarView::SetCalendarSlidingSurfaceBounds(bool event_list_view_open) {
}
void CalendarView::MaybeShowUpNextView() {
if (!features::IsCalendarJellyEnabled() ||
calendar_view_controller_->UpcomingEvents().empty()) {
if (calendar_view_controller_->UpcomingEvents().empty()) {
RemoveUpNextView();
return;
}
@ -2255,10 +2206,8 @@ void CalendarView::OnAnimateScrollByOffsetComplete(int offset) {
}
int CalendarView::GetSingleVisibleRowHeight() {
return features::IsCalendarJellyEnabled()
? calendar_view_controller_->row_height() +
kCalendarEventListViewOpenMarginJelly
: calendar_view_controller_->row_height();
return calendar_view_controller_->row_height() +
kCalendarEventListViewOpenMargin;
}
BEGIN_METADATA(CalendarView, GlanceableTrayChildBubble)

@ -9,7 +9,6 @@
#include "ash/ash_export.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/time/calendar_model.h"
#include "ash/system/time/calendar_up_next_view.h"
@ -22,9 +21,7 @@
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/compositor/compositor_animation_observer.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/view.h"
@ -55,9 +52,6 @@ class CalendarHeaderView : public views::View {
CalendarHeaderView& operator=(const CalendarHeaderView& other) = delete;
~CalendarHeaderView() override;
// views::View:
void OnThemeChanged() override;
// Updates the month and year labels.
void UpdateHeaders(const std::u16string& month, const std::u16string& year);

@ -205,7 +205,7 @@ class ASH_EXPORT CalendarViewController {
friend class CalendarViewAnimationTest;
friend class CalendarViewEventListViewTest;
friend class CalendarViewTest;
friend class CalendarViewEventListItemViewJellyTest;
friend class CalendarViewEventListItemViewTest;
// Adds the time difference and returns the adjusted time.
base::Time ApplyTimeDifference(base::Time date);

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/constants/ash_features.h"
#include "ash/shelf/shelf.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/time/calendar_event_list_view.h"
@ -11,13 +10,10 @@
#include "ash/system/unified/date_tray.h"
#include "ash/system/unified/unified_system_tray_bubble.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/ash_test_util.h"
#include "ash/test/pixel/ash_pixel_differ.h"
#include "ash/test/pixel/ash_pixel_test_init_params.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "chromeos/constants/chromeos_features.h"
#include "google_apis/calendar/calendar_api_response_types.h"
namespace ash {
@ -41,16 +37,6 @@ class CalendarViewPixelTest : public AshTestBase {
public:
CalendarViewPixelTest() = default;
// AshTestBase:
void SetUp() override {
scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
scoped_feature_list_->InitWithFeatures(
{chromeos::features::kJelly, features::kQsRevamp,
features::kCalendarJelly},
{});
AshTestBase::SetUp();
}
// AshTestBase:
absl::optional<pixel_test::InitParams> CreatePixelTestInitParams()
const override {
@ -92,7 +78,6 @@ class CalendarViewPixelTest : public AshTestBase {
private:
raw_ptr<CalendarView, DanglingUntriaged | ExperimentalAsh> calendar_view_ =
nullptr;
std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
static base::Time fake_time_;
};

@ -39,7 +39,6 @@
#include "base/time/time.h"
#include "base/time/time_override.h"
#include "chromeos/ash/components/settings/scoped_timezone_settings.h"
#include "chromeos/constants/chromeos_features.h"
#include "google_apis/common/api_error_codes.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/layer.h"
@ -2292,12 +2291,6 @@ class CalendarViewWithJellyEnabledTest : public CalendarViewTest {
const CalendarViewWithJellyEnabledTest&) = delete;
~CalendarViewWithJellyEnabledTest() override = default;
void SetUp() override {
scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
scoped_feature_list_->InitWithFeatures({features::kCalendarJelly}, {});
CalendarViewTest::SetUp();
}
// Assumes current time is "18 Nov 2021 10:00 GMT".
std::unique_ptr<google_apis::calendar::EventList>
CreateMockEventListWithEventStartTimeMoreThanTwoHoursAway() {
@ -2351,9 +2344,6 @@ class CalendarViewWithJellyEnabledTest : public CalendarViewTest {
calendar_utils::GetStartOfMonthUTC(date),
google_apis::ApiErrorCode::HTTP_SUCCESS, event_list.get());
}
private:
std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
};
TEST_F(CalendarViewWithJellyEnabledTest,
@ -2891,13 +2881,6 @@ class CalendarViewAnimationWithJellyEnabledTest
const CalendarViewAnimationWithJellyEnabledTest&) = delete;
~CalendarViewAnimationWithJellyEnabledTest() override = default;
void SetUp() override {
scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
scoped_feature_list_->InitWithFeatures(
{features::kCalendarJelly, chromeos::features::kJelly}, {});
CalendarViewAnimationTest::SetUp();
}
std::unique_ptr<google_apis::calendar::EventList> CreateUpcomingEvents(
base::Time date) {
const auto start_time = date + base::Minutes(5);
@ -2917,9 +2900,6 @@ class CalendarViewAnimationWithJellyEnabledTest
calendar_utils::GetStartOfMonthUTC(date),
google_apis::ApiErrorCode::HTTP_SUCCESS, event_list.get());
}
private:
std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
};
TEST_F(CalendarViewAnimationWithJellyEnabledTest,

@ -4338,9 +4338,6 @@ const FeatureEntry kFeatureEntries[] = {
{"bluetooth-use-llprivacy", flag_descriptions::kBluetoothUseLLPrivacyName,
flag_descriptions::kBluetoothUseLLPrivacyDescription, kOsCrOS,
FEATURE_VALUE_TYPE(bluez::features::kLinkLayerPrivacy)},
{"calendar-jelly", flag_descriptions::kCalendarJellyName,
flag_descriptions::kCalendarJellyDescription, kOsCrOS,
FEATURE_VALUE_TYPE(ash::features::kCalendarJelly)},
{"cellular-bypass-esim-installation-connectivity-check",
flag_descriptions::kCellularBypassESimInstallationConnectivityCheckName,
flag_descriptions::

@ -5689,10 +5689,6 @@ const char kBluetoothUseLLPrivacyDescription[] =
"Enable address resolution offloading to Bluetooth Controller if "
"supported. Modifying this flag will cause Bluetooth Controller to reset.";
const char kCalendarJellyName[] = "Enable Calendar Jelly features";
const char kCalendarJellyDescription[] =
"Enables Jelly changes for the sys tray Calendar views.";
const char kCaptureModeAudioMixingName[] =
"Enable screen capture advanced audio settings";
const char kCaptureModeAudioMixingDescription[] =

@ -3288,9 +3288,6 @@ extern const char kBluetoothFlossIsAvailabilityCheckNeededDescription[];
extern const char kBluetoothUseLLPrivacyName[];
extern const char kBluetoothUseLLPrivacyDescription[];
extern const char kCalendarJellyName[];
extern const char kCalendarJellyDescription[];
extern const char kCaptureModeAudioMixingName[];
extern const char kCaptureModeAudioMixingDescription[];

@ -3368,21 +3368,6 @@
]
}
],
"ChromeOSCalendarJellyExperiments": [
{
"platforms": [
"chromeos"
],
"experiments": [
{
"name": "Enabled",
"enable_features": [
"CalendarJelly"
]
}
]
}
],
"ChromeOSHWVBREncoding": [
{
"platforms": [

@ -1262,6 +1262,11 @@ chromium-metrics-reviews@google.com.
<histogram name="Ash.Calendar.EventListView.EventDisplayedCount" units="int"
expires_after="2024-09-04">
<obsolete>
This metric was originally recording pre CalendarJelly data. Replaced with
Ash.Calendar.EventListViewJelly.EventDisplayedCount after the CalendarJelly
launch.
</obsolete>
<owner>jiamingc@google.com</owner>
<owner>cros-status-area-eng@google.com</owner>
<summary>
@ -1289,10 +1294,10 @@ chromium-metrics-reviews@google.com.
<owner>newcomer@google.com</owner>
<owner>cros-status-area-eng@google.com</owner>
<summary>
(For Jelly Calendar) Records the number of currently visible events shown to
the user when the Calendar Event List view displays in one day. i.e. the
user opens the sys tray calendar, clicks on a date cell and sees 2 events,
this metric will track a count of 2.
Records the number of currently visible events shown to the user when the
Calendar Event List view displays in one day. i.e. the user opens the sys
tray calendar, clicks on a date cell and sees 2 events, this metric will
track a count of 2.
</summary>
</histogram>