Skip to content

Commit

Permalink
[Eche] Add new views for recent apps loading state
Browse files Browse the repository at this point in the history
This CL introduces new views for the recent apps view to represent a
loading state. A follow-up CL will include the logic for displaying the
loading view, error view, and transition to the normal recent apps
buttons view.

Screen capture showing the animation:
https://drive.google.com/file/d/1uEOnaXQUT7SY2aug-e663vu-yUeqPgsR/view?usp=sharing&resourcekey=0-bxDJXQsjU0IS7W3B61cqbg

Test: Manually verified that when setting loading_view_ to visible it
will show. Verified that the non-loading view and buttons still work
as intended.

Bug: b/271478560
Change-Id: Ifb1d1cb8830dadbd5164a774a9eaa116cb024754
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4307837
Reviewed-by: Jon Mann <jonmann@chromium.org>
Commit-Queue: Curt Clemens <cclem@google.com>
Reviewed-by: Pu Shi <pushi@google.com>
Cr-Commit-Position: refs/heads/main@{#1118447}
  • Loading branch information
Curt Clemens authored and Chromium LUCI CQ committed Mar 17, 2023
1 parent 7116a8e commit 971477f
Show file tree
Hide file tree
Showing 13 changed files with 280 additions and 123 deletions.
8 changes: 4 additions & 4 deletions ash/BUILD.gn
Expand Up @@ -1674,6 +1674,10 @@ component("ash") {
"system/phonehub/phone_disconnected_view.h",
"system/phonehub/phone_hub_app_count_icon.cc",
"system/phonehub/phone_hub_app_count_icon.h",
"system/phonehub/phone_hub_app_icon.cc",
"system/phonehub/phone_hub_app_icon.h",
"system/phonehub/phone_hub_app_loading_icon.cc",
"system/phonehub/phone_hub_app_loading_icon.h",
"system/phonehub/phone_hub_content_view.cc",
"system/phonehub/phone_hub_content_view.h",
"system/phonehub/phone_hub_interstitial_view.cc",
Expand All @@ -1692,10 +1696,6 @@ component("ash") {
"system/phonehub/phone_hub_recent_app_button.h",
"system/phonehub/phone_hub_recent_apps_view.cc",
"system/phonehub/phone_hub_recent_apps_view.h",
"system/phonehub/phone_hub_small_app_icon.cc",
"system/phonehub/phone_hub_small_app_icon.h",
"system/phonehub/phone_hub_small_app_loading_icon.cc",
"system/phonehub/phone_hub_small_app_loading_icon.h",
"system/phonehub/phone_hub_tray.cc",
"system/phonehub/phone_hub_tray.h",
"system/phonehub/phone_hub_ui_controller.cc",
Expand Down
19 changes: 13 additions & 6 deletions ash/system/phonehub/phone_hub_app_count_icon.cc
Expand Up @@ -14,10 +14,13 @@

namespace ash {

namespace {

class NumberIconImageSource : public gfx::CanvasImageSource {
public:
explicit NumberIconImageSource(size_t count)
: CanvasImageSource(gfx::Size(18, 18)), count_(count) {}
explicit NumberIconImageSource(size_t count, int size)
: CanvasImageSource(AppIcon::GetRecommendedImageSize(size)),
count_(count) {}

NumberIconImageSource(const NumberIconImageSource&) = delete;
NumberIconImageSource& operator=(const NumberIconImageSource&) = delete;
Expand Down Expand Up @@ -49,8 +52,12 @@ class NumberIconImageSource : public gfx::CanvasImageSource {
}
};

} // namespace

AppCountIcon::AppCountIcon(const int count)
: SmallAppIcon(gfx::Image(
gfx::CanvasImageSource::MakeImageSkia<NumberIconImageSource>(
count))) {}
} // namespace ash
: AppIcon(gfx::Image(
gfx::CanvasImageSource::MakeImageSkia<NumberIconImageSource>(
count,
AppIcon::kSizeSmall)),
AppIcon::kSizeSmall) {}
} // namespace ash
6 changes: 3 additions & 3 deletions ash/system/phonehub/phone_hub_app_count_icon.h
Expand Up @@ -5,14 +5,14 @@
#ifndef ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_COUNT_ICON_H_
#define ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_COUNT_ICON_H_
#include "ash/ash_export.h"
#include "ash/system/phonehub/phone_hub_small_app_icon.h"
#include "ash/system/phonehub/phone_hub_app_icon.h"

namespace ash {

class ASH_EXPORT AppCountIcon : public SmallAppIcon {
class ASH_EXPORT AppCountIcon : public AppIcon {
public:
explicit AppCountIcon(const int count);
};
} // namespace ash

#endif // ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_COUNT_ICON_H_
#endif // ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_COUNT_ICON_H_
Expand Up @@ -2,28 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/phonehub/phone_hub_small_app_icon.h"
#include "ash/system/phonehub/phone_hub_app_icon.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"

namespace {

// Appearance in DIPs.
constexpr int kSmallAppIconSize = 20;

} // namespace

namespace ash {

SmallAppIcon::SmallAppIcon(const gfx::Image& icon) {
AppIcon::AppIcon(const gfx::Image& icon, int size) {
SetImage(gfx::ImageSkiaOperations::CreateResizedImage(
icon.AsImageSkia(), skia::ImageOperations::RESIZE_BEST,
gfx::Size(kSmallAppIconSize, kSmallAppIconSize)));
gfx::Size(size, size)));
}

// views::View:
const char* SmallAppIcon::GetClassName() const {
return "SmallAppIcon";
const char* AppIcon::GetClassName() const {
return "AppIcon";
}

} // namespace ash
} // namespace ash
37 changes: 37 additions & 0 deletions ash/system/phonehub/phone_hub_app_icon.h
@@ -0,0 +1,37 @@
// 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_PHONEHUB_PHONE_HUB_APP_ICON_H_
#define ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_ICON_H_
#include "ash/ash_export.h"
#include "ui/views/controls/image_view.h"

namespace ash {

class ASH_EXPORT AppIcon : public views::ImageView {
public:
// Measured in DIPs.
static constexpr int kSizeSmall = 20;
static constexpr int kSizeNormal = 32;

static constexpr gfx::Size GetRecommendedImageSize(int icon_size) {
// Leave 1 DP of space around the image to avoid the appearance of clipping.
constexpr int kRecommendedImageInset = 1;

int length_minus_insets = icon_size - 2 * kRecommendedImageInset;
return gfx::Size(length_minus_insets, length_minus_insets);
}

AppIcon(const gfx::Image& icon, int size);
AppIcon(const AppIcon&) = delete;
AppIcon& operator=(const AppIcon&) = delete;

~AppIcon() override = default;

// views::View:
const char* GetClassName() const override;
};
} // namespace ash

#endif // ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_ICON_H_
Expand Up @@ -2,17 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "phone_hub_small_app_loading_icon.h"
#include "phone_hub_app_loading_icon.h"

#include "ash/style/ash_color_provider.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/canvas_image_source.h"

namespace ash {

namespace {

class LoadingCircle : public gfx::CanvasImageSource {
public:
explicit LoadingCircle() : CanvasImageSource(gfx::Size(18, 18)) {}
explicit LoadingCircle(int size)
: CanvasImageSource(AppIcon::GetRecommendedImageSize(size)) {}

LoadingCircle(const LoadingCircle&) = delete;
LoadingCircle& operator=(const LoadingCircle&) = delete;
Expand All @@ -28,11 +32,15 @@ class LoadingCircle : public gfx::CanvasImageSource {
}
};

SmallAppLoadingIcon::SmallAppLoadingIcon()
: SmallAppIcon(
gfx::Image(gfx::CanvasImageSource::MakeImageSkia<LoadingCircle>())) {
} // namespace

AppLoadingIcon::AppLoadingIcon(int size)
: AppIcon(gfx::Image(
gfx::CanvasImageSource::MakeImageSkia<LoadingCircle>(size)),
size) {
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
layer()->SetFillsBoundsCompletely(false);
}
} // namespace ash

} // namespace ash
20 changes: 20 additions & 0 deletions ash/system/phonehub/phone_hub_app_loading_icon.h
@@ -0,0 +1,20 @@
// Copyright 2023 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_PHONEHUB_PHONE_HUB_APP_LOADING_ICON_H_
#define ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_LOADING_ICON_H_

#include "ash/ash_export.h"
#include "ash/system/phonehub/phone_hub_app_icon.h"

namespace ash {

class ASH_EXPORT AppLoadingIcon : public AppIcon {
public:
explicit AppLoadingIcon(int size);
};

} // namespace ash

#endif // ASH_SYSTEM_PHONEHUB_PHONE_HUB_APP_LOADING_ICON_H_
37 changes: 27 additions & 10 deletions ash/system/phonehub/phone_hub_more_apps_button.cc
Expand Up @@ -8,9 +8,9 @@
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/system/phonehub/phone_hub_app_count_icon.h"
#include "ash/system/phonehub/phone_hub_app_icon.h"
#include "ash/system/phonehub/phone_hub_app_loading_icon.h"
#include "ash/system/phonehub/phone_hub_metrics.h"
#include "ash/system/phonehub/phone_hub_small_app_icon.h"
#include "ash/system/phonehub/phone_hub_small_app_loading_icon.h"
#include "base/metrics/histogram_functions.h"
#include "chromeos/ash/components/phonehub/app_stream_launcher_data_model.h"
#include "ui/base/l10n/l10n_util.h"
Expand Down Expand Up @@ -51,11 +51,16 @@ class MoreAppsButtonBackground : public views::Background {
}
};

PhoneHubMoreAppsButton::PhoneHubMoreAppsButton() {
InitLayout();
}

PhoneHubMoreAppsButton::PhoneHubMoreAppsButton(
phonehub::AppStreamLauncherDataModel* app_stream_launcher_data_model,
views::Button::PressedCallback callback)
: views::Button(std::move(callback)),
app_stream_launcher_data_model_(app_stream_launcher_data_model) {
CHECK(app_stream_launcher_data_model_);
SetFocusBehavior(FocusBehavior::ALWAYS);
SetAccessibleName(
l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_FULL_APPS_LIST_BUTTON_TITLE));
Expand All @@ -64,7 +69,9 @@ PhoneHubMoreAppsButton::PhoneHubMoreAppsButton(
}

PhoneHubMoreAppsButton::~PhoneHubMoreAppsButton() {
app_stream_launcher_data_model_->RemoveObserver(this);
if (app_stream_launcher_data_model_) {
app_stream_launcher_data_model_->RemoveObserver(this);
}
}

void PhoneHubMoreAppsButton::InitLayout() {
Expand All @@ -91,9 +98,15 @@ void PhoneHubMoreAppsButton::InitLayout() {
kMoreAppsButtonRowPadding);

SetEnabled(false);
SetBackground(std::make_unique<MoreAppsButtonBackground>());
if (!app_stream_launcher_data_model_) {
AddLoadingAppIcons(/*animate=*/false);
return;
}

if (app_stream_launcher_data_model_->GetAppsListSortedByName()->empty()) {
load_app_list_latency_ = base::TimeTicks::Now();
InitGlimmer();
AddLoadingAppIcons(/*animate=*/true);
SetEnabled(false);
phone_hub_metrics::LogMoreAppsButtonAnimationOnShow(
phone_hub_metrics::MoreAppsButtonLoadingState::kAnimationShown);
Expand All @@ -108,13 +121,16 @@ void PhoneHubMoreAppsButton::InitLayout() {
phone_hub_metrics::LogMoreAppsButtonAnimationOnShow(
phone_hub_metrics::MoreAppsButtonLoadingState::kMoreAppsButtonLoaded);
}

SetBackground(std::make_unique<MoreAppsButtonBackground>());
}

void PhoneHubMoreAppsButton::InitGlimmer() {
void PhoneHubMoreAppsButton::AddLoadingAppIcons(bool animate) {
for (auto i = 0; i < 4; i++) {
auto* app_loading_icon = new SmallAppLoadingIcon();
auto* app_loading_icon =
AddChildView(new AppLoadingIcon(AppIcon::kSizeSmall));
if (!animate) {
continue;
}

views::AnimationBuilder animation_builder;
animation_builder.Once().SetOpacity(app_loading_icon,
kAnimationLoadingCardOpacity);
Expand All @@ -131,7 +147,6 @@ void PhoneHubMoreAppsButton::InitGlimmer() {
base::Milliseconds(kAnimationLoadingCardTransitDurationInMs))
.SetOpacity(app_loading_icon, kAnimationLoadingCardOpacity,
gfx::Tween::LINEAR);
AddChildView(app_loading_icon);
}
}

Expand All @@ -148,13 +163,15 @@ void PhoneHubMoreAppsButton::OnAppListChanged() {
}

void PhoneHubMoreAppsButton::LoadAppList() {
CHECK(app_stream_launcher_data_model_);
RemoveAllChildViews();
const std::vector<phonehub::Notification::AppMetadata>* app_list =
app_stream_launcher_data_model_->GetAppsListSortedByName();
if (!app_list->empty()) {
auto app_count = std::min(app_list->size(), size_t{3});
for (size_t i = 0; i < app_count; i++) {
AddChildView(std::make_unique<SmallAppIcon>(app_list->at(i).icon));
AddChildView(
std::make_unique<AppIcon>(app_list->at(i).icon, AppIcon::kSizeSmall));
}
}

Expand Down
12 changes: 9 additions & 3 deletions ash/system/phonehub/phone_hub_more_apps_button.h
Expand Up @@ -20,9 +20,14 @@ class VIEWS_EXPORT PhoneHubMoreAppsButton
public:
METADATA_HEADER(PhoneHubMoreAppsButton);

explicit PhoneHubMoreAppsButton(
// Only use this constructor to create a skeleton view for the LoadingView.
// Does not process click events or load app icons.
PhoneHubMoreAppsButton();

PhoneHubMoreAppsButton(
phonehub::AppStreamLauncherDataModel* app_stream_launcher_data_model,
views::Button::PressedCallback callback);

PhoneHubMoreAppsButton(const PhoneHubMoreAppsButton&) = delete;
PhoneHubMoreAppsButton& operator=(const PhoneHubMoreAppsButton&) = delete;
~PhoneHubMoreAppsButton() override;
Expand All @@ -34,11 +39,12 @@ class VIEWS_EXPORT PhoneHubMoreAppsButton
private:
void InitLayout();
void LoadAppList();
void InitGlimmer();
void AddLoadingAppIcons(bool animate);

base::TimeTicks load_app_list_latency_ = base::TimeTicks();
views::TableLayout* table_layout_ = nullptr;
phonehub::AppStreamLauncherDataModel* app_stream_launcher_data_model_;
phonehub::AppStreamLauncherDataModel* app_stream_launcher_data_model_ =
nullptr;
};

} // namespace ash
Expand Down

0 comments on commit 971477f

Please sign in to comment.