Skip to content

Commit

Permalink
[eche] Grouping tray icons for Eche and Phone Hub.
Browse files Browse the repository at this point in the history
I had a plan to do a larger refactoring to add a new icon group concept
to the status area widget. However, it turned out to be a large surgery
to be done correctly and nicely. So, I decided to follow another
alternative in the interim time and do not block the Eche progress.

Here, I added an icon to the phone hub tray for Eche. And hence, I
converted the icons to Buttons to be clickable indicvidually.
I tried to minimize the intervention of Eche code into the phone hub
code as much as I could.

Caveat: The icons might be too close to each other to be clicked on
individually, I am working with UX to adjust/address this.

Side note: As it turned out that keeping #eche-swa-in-background
would make the code complicated unnecessarily, the flag usages are
removed from the code (we have already decided to set it to
default = true). The flag definition itself is going to be removed
in the next CL.

Change-Id: I4da120ff7f4b56b52acbeba4ff6454e51b7424e2
TEST=manual testing with/without #eche-custom-widget enabled.
The Eche and phone hub behavior was briefly tested by clicking on
different buttons in the phone hub and sending/receiving messages
in Eche.

Bug: b/222509310
Change-Id: I4da120ff7f4b56b52acbeba4ff6454e51b7424e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3527258
Reviewed-by: Daniel Nishi <dhnishi@chromium.org>
Reviewed-by: Jon Mann <jonmann@chromium.org>
Reviewed-by: Alex Newcomer <newcomer@chromium.org>
Commit-Queue: Abbas Nayebi <nayebi@google.com>
Cr-Commit-Position: refs/heads/main@{#984544}
  • Loading branch information
nayebia authored and Chromium LUCI CQ committed Mar 23, 2022
1 parent 2b89491 commit 03e52d1
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 85 deletions.
20 changes: 11 additions & 9 deletions ash/system/eche/eche_icon_loading_indicator_view.cc
Expand Up @@ -14,6 +14,7 @@
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/paint_throbber.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/view.h"
Expand All @@ -27,8 +28,7 @@ constexpr int kThrobberStrokeWidth = 2;

} // namespace

EcheIconLoadingIndicatorView::EcheIconLoadingIndicatorView(
views::ImageView* parent)
EcheIconLoadingIndicatorView::EcheIconLoadingIndicatorView(views::View* parent)
: parent_(parent) {
observed_session_.Observe(parent_);

Expand Down Expand Up @@ -59,12 +59,14 @@ void EcheIconLoadingIndicatorView::OnPaint(gfx::Canvas* canvas) {
if (!throbber_start_time_)
return;

const SkColor color =
TrayIconColor(Shell::Get()->session_controller()->GetSessionState());

gfx::PaintThrobberSpinning(canvas, GetLocalBounds(), color,
base::TimeTicks::Now() - *throbber_start_time_,
kThrobberStrokeWidth);
// The image covers the container horizontally and is centered vertically.
gfx::Rect bounds = GetLocalBounds();
bounds.ClampToCenteredSize(
gfx::Size(GetLocalBounds().width(), GetLocalBounds().width()));
gfx::PaintThrobberSpinning(
canvas, bounds,
TrayIconColor(Shell::Get()->session_controller()->GetSessionState()),
base::TimeTicks::Now() - *throbber_start_time_, kThrobberStrokeWidth);
}

void EcheIconLoadingIndicatorView::OnViewBoundsChanged(
Expand All @@ -79,4 +81,4 @@ void EcheIconLoadingIndicatorView::AnimationProgressed(
SchedulePaint();
}

} // namespace ash
} // namespace ash
8 changes: 2 additions & 6 deletions ash/system/eche/eche_icon_loading_indicator_view.h
Expand Up @@ -13,10 +13,6 @@
#include "ui/views/view.h"
#include "ui/views/view_observer.h"

namespace views {
class ImageView;
} // namespace views

namespace gfx {
class Canvas;
class Animation;
Expand All @@ -29,7 +25,7 @@ class ASH_EXPORT EcheIconLoadingIndicatorView : public views::View,
public views::ViewObserver,
public gfx::AnimationDelegate {
public:
explicit EcheIconLoadingIndicatorView(views::ImageView* parent);
explicit EcheIconLoadingIndicatorView(views::View* parent);
EcheIconLoadingIndicatorView(const EcheIconLoadingIndicatorView&) = delete;
EcheIconLoadingIndicatorView& operator=(const EcheIconLoadingIndicatorView&) =
delete;
Expand All @@ -50,7 +46,7 @@ class ASH_EXPORT EcheIconLoadingIndicatorView : public views::View,
private:
absl::optional<base::TimeTicks> throbber_start_time_;

views::ImageView* parent_ = nullptr;
views::View* parent_ = nullptr; // Unowned.

base::ScopedObservation<views::View, views::ViewObserver> observed_session_{
this};
Expand Down
116 changes: 84 additions & 32 deletions ash/system/eche/eche_tray.cc
Expand Up @@ -12,19 +12,23 @@
#include "ash/public/cpp/ash_web_view_factory.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/icon_button.h"
#include "ash/system/eche/eche_icon_loading_indicator_view.h"
#include "ash/system/phonehub/phone_hub_tray.h"
#include "ash/system/phonehub/ui_constants.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/tray/tray_bubble_wrapper.h"
#include "ash/system/tray/tray_container.h"
#include "ash/system/tray/tray_popup_utils.h"
#include "ash/system/tray/tray_utils.h"
#include "base/bind.h"
#include "base/callback_forward.h"
#include "components/account_id/account_id.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
Expand All @@ -41,6 +45,7 @@
#include "ui/gfx/vector_icon_types.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/image_view.h"
Expand Down Expand Up @@ -101,12 +106,6 @@ EcheTray::EcheTray(Shelf* shelf)
views::CreateEmptyBorder(gfx::Insets(icon_padding, icon_padding)));

icon_->SetTooltipText(GetAccessibleNameForTray());

if (features::IsEcheSWAInBackgroundEnabled()) {
loading_indicator_ = icon_->AddChildView(
std::make_unique<EcheIconLoadingIndicatorView>(icon_));
loading_indicator_->SetVisible(false);
}
}

EcheTray::~EcheTray() {
Expand Down Expand Up @@ -155,24 +154,15 @@ void EcheTray::CloseBubble() {
}

void EcheTray::ShowBubble() {
if (bubble_) {
bubble_->GetBubbleWidget()->Show();
bubble_->GetBubbleWidget()->Activate();
bubble_->bubble_view()->SetVisible(true);
SetIsActive(true);

// TODO(b/223297066): Observe the connection status and add/remove the
// loading indicator based on the connection status.
if (features::IsEcheSWAInBackgroundEnabled() &&
loading_indicator_->GetAnimating()) {
loading_indicator_->SetAnimating(false);
}
if (!bubble_)
return;
}
SetIconVisibility(true);
StopLoadingAnimation();

InitBubble();

// TODO(nayebi): Add metric updates.
bubble_->GetBubbleWidget()->Show();
bubble_->GetBubbleWidget()->Activate();
bubble_->bubble_view()->SetVisible(true);
SetIsActive(true);
}

bool EcheTray::PerformAction(const ui::Event& event) {
Expand Down Expand Up @@ -217,16 +207,40 @@ void EcheTray::SetUrl(const GURL& url) {
}

void EcheTray::SetIcon(const gfx::Image& icon) {
icon_->SetImage(gfx::ImageSkiaOperations::CreateResizedImage(
icon.AsImageSkia(), skia::ImageOperations::RESIZE_BEST,
gfx::Size(kIconSize, kIconSize)));
views::ImageButton* icon_view = GetIcon();
if (icon_view) {
icon_view->SetImage(
views::ImageButton::STATE_NORMAL,
gfx::ImageSkiaOperations::CreateResizedImage(
icon.AsImageSkia(), skia::ImageOperations::RESIZE_BEST,
gfx::Size(kIconSize, kIconSize)));
SetIconVisibility(true);
}
}

void EcheTray::PurgeAndClose() {
if (features::IsEcheSWAInBackgroundEnabled() &&
loading_indicator_->GetAnimating()) {
loading_indicator_->SetAnimating(false);
void EcheTray::LoadBubble(const GURL& url, const gfx::Image& icon) {
SetUrl(url);
SetIcon(icon);
// If the bubble is already initialized, setting the icon and url was enough
// to navigate the bubble to the new address.
if (IsInitialized()) {
ShowBubble();
return;
}
InitBubble();
StartLoadingAnimation();
auto* phone_hub_tray = GetPhoneHubTray();
if (phone_hub_tray) {
phone_hub_tray->SetEcheIconActivationCallback(
base::BindRepeating(&EcheTray::PerformAction, base::Unretained(this)));
}
// Hide bubble first until the streaming is ready.
HideBubble();
}

void EcheTray::PurgeAndClose() {
StopLoadingAnimation();
SetIconVisibility(false);

if (!bubble_)
return;
Expand All @@ -238,6 +252,7 @@ void EcheTray::PurgeAndClose() {
bubble_.reset();
SetIsActive(false);
SetVisiblePreferred(false);
web_view_ = nullptr;
}

void EcheTray::HideBubble() {
Expand Down Expand Up @@ -289,9 +304,6 @@ void EcheTray::InitBubble() {

SetIsActive(true);
bubble_->GetBubbleView()->UpdateBubble();

if (features::IsEcheSWAInBackgroundEnabled())
loading_indicator_->SetAnimating(true);
}

gfx::Size EcheTray::GetSizeForEche() const {
Expand Down Expand Up @@ -356,6 +368,46 @@ std::unique_ptr<views::View> EcheTray::CreateBubbleHeaderView() {
return header;
}

views::ImageButton* EcheTray::GetIcon() {
PhoneHubTray* phone_hub_tray = GetPhoneHubTray();
if (!phone_hub_tray)
return nullptr;
return phone_hub_tray->eche_icon_view();
}

void EcheTray::StopLoadingAnimation() {
auto* loading_indicator = GetLoadingIndicator();
if (loading_indicator && loading_indicator->GetAnimating()) {
loading_indicator->SetAnimating(false);
}
}

void EcheTray::StartLoadingAnimation() {
auto* loading_indicator = GetLoadingIndicator();
if (loading_indicator) {
loading_indicator->SetAnimating(true);
}
}

void EcheTray::SetIconVisibility(bool visibility) {
auto* icon = GetIcon();
if (!icon)
return;
icon->SetVisible(visibility);
GetPhoneHubTray()->tray_container()->UpdateLayout();
}

PhoneHubTray* EcheTray::GetPhoneHubTray() {
return shelf()->GetStatusAreaWidget()->phone_hub_tray();
}

EcheIconLoadingIndicatorView* EcheTray::GetLoadingIndicator() {
PhoneHubTray* phone_hub_tray = GetPhoneHubTray();
if (!phone_hub_tray)
return nullptr;
return phone_hub_tray->eche_loading_indicator();
}

BEGIN_METADATA(EcheTray, TrayBackgroundView)
END_METADATA

Expand Down
19 changes: 17 additions & 2 deletions ash/system/eche/eche_tray.h
Expand Up @@ -20,6 +20,7 @@
namespace views {

class ImageView;
class ImageButton;
class View;
class Widget;

Expand All @@ -40,6 +41,7 @@ class Shelf;
class TrayBubbleView;
class TrayBubbleWrapper;
class AshWebView;
class PhoneHubTray;

// This class represents the Eche tray button in the status area and
// controls the bubble that is shown when the tray button is clicked.
Expand Down Expand Up @@ -82,6 +84,13 @@ class ASH_EXPORT EcheTray : public TrayBackgroundView, public SessionObserver {
// Sets the icon that will be used on the tray.
void SetIcon(const gfx::Image& icon);

// Initializes the bubble with given parameters. If there is any previous
// bubble already shown with a different URL it is going to be closed. The
// bubble is not shown initially until `ShowBubble` is called. The `url`
// parameter is used to load the `WebView` inside the bubble. The `icon` is
// used to update the tray icon for `EcheTray`.
void LoadBubble(const GURL& url, const gfx::Image& icon);

// Destroys the view inclusing the web view.
// Note: `CloseBubble` only hides the view.
void PurgeAndClose();
Expand Down Expand Up @@ -110,6 +119,14 @@ class ASH_EXPORT EcheTray : public TrayBackgroundView, public SessionObserver {
// close, and minimize buttons.
std::unique_ptr<views::View> CreateBubbleHeaderView();

views::ImageButton* GetIcon();
void StopLoadingAnimation();
void StartLoadingAnimation();
void SetIconVisibility(bool visibility);

PhoneHubTray* GetPhoneHubTray();
EcheIconLoadingIndicatorView* GetLoadingIndicator();

// The url that is transferred to the web view.
// In the current implementation, this is supposed to be
// Eche window URL. However, the bubble does not interpret,
Expand All @@ -128,8 +145,6 @@ class ASH_EXPORT EcheTray : public TrayBackgroundView, public SessionObserver {

base::ScopedObservation<SessionControllerImpl, SessionObserver>
observed_session_{this};
// The loading indicator, showing a throbber animation on top of the icon.
EcheIconLoadingIndicatorView* loading_indicator_ = nullptr;

base::WeakPtrFactory<EcheTray> weak_factory_{this};
};
Expand Down

0 comments on commit 03e52d1

Please sign in to comment.