blob: 0895f693aaf2bc197aaa824b45b75beb2c198d78 [file] [log] [blame]
// Copyright 2020 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_TRAY_H_
#define ASH_SYSTEM_PHONEHUB_PHONE_HUB_TRAY_H_
#include "ash/ash_export.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/session/session_controller_impl.h"
#include "ash/system/phonehub/onboarding_view.h"
#include "ash/system/phonehub/phone_hub_content_view.h"
#include "ash/system/phonehub/phone_hub_nudge_controller.h"
#include "ash/system/phonehub/phone_hub_ui_controller.h"
#include "ash/system/phonehub/phone_status_view.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/tray/tray_background_view.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chromeos/ash/components/phonehub/app_stream_manager.h"
#include "chromeos/ash/components/phonehub/icon_decoder.h"
#include "chromeos/ash/components/phonehub/phone_hub_manager.h"
#include "ui/events/event.h"
#include "ui/views/controls/button/image_button.h"
namespace views {
class ImageButton;
}
namespace ash {
class EcheIconLoadingIndicatorView;
class PhoneHubContentView;
class TrayBubbleWrapper;
class SessionControllerImpl;
namespace phonehub {
namespace proto {
class AppStreamUpdate;
} // namespace proto
class PhoneHubManager;
}
// This class represents the Phone Hub tray button in the status area and
// controls the bubble that is shown when the tray button is clicked.
class ASH_EXPORT PhoneHubTray : public TrayBackgroundView,
public OnboardingView::Delegate,
public PhoneStatusView::Delegate,
public PhoneHubUiController::Observer,
public SessionObserver,
public WindowTreeHostManager::Observer,
public phonehub::AppStreamManager::Observer {
public:
explicit PhoneHubTray(Shelf* shelf);
PhoneHubTray(const PhoneHubTray&) = delete;
~PhoneHubTray() override;
PhoneHubTray& operator=(const PhoneHubTray&) = delete;
// Sets the PhoneHubManager that provides the data to drive the UI.
void SetPhoneHubManager(phonehub::PhoneHubManager* phone_hub_manager);
// TrayBackgroundView:
void ClickedOutsideBubble() override;
std::u16string GetAccessibleNameForTray() override;
void HandleLocaleChange() override;
void HideBubbleWithView(const TrayBubbleView* bubble_view) override;
void AnchorUpdated() override;
void Initialize() override;
void CloseBubble() override;
void ShowBubble() override;
TrayBubbleView* GetBubbleView() override;
views::Widget* GetBubbleWidget() const override;
const char* GetClassName() const override;
// PhoneStatusView::Delegate:
bool CanOpenConnectedDeviceSettings() override;
void OpenConnectedDevicesSettings() override;
// OnboardingView::Delegate:
void HideStatusHeaderView() override;
// WindowTreeHostManager::Observer
void OnDisplayConfigurationChanged() override;
// AppStreamManager::Observer:
void OnAppStreamUpdate(
const phonehub::proto::AppStreamUpdate app_stream_update) override;
void OnIconsDecoded(
std::string visible_name,
std::unique_ptr<std::vector<phonehub::IconDecoder::DecodingData>>
decoding_data_list);
// Provides the Eche icon and Eche loading indicator to
// `EcheTray` in order to let `EcheTray` control the visibiliity
// of them. Please note that these views are in control of 'EcheTray'
// and the phone hub area is "borrowed" by `EcheTray` for the
// purpose of grouping the icons together.
views::ImageButton* eche_icon_view() { return eche_icon_; }
EcheIconLoadingIndicatorView* eche_loading_indicator() {
return eche_loading_indicator_;
}
// Sets a callback that will be called when eche icon is activated.
void SetEcheIconActivationCallback(
base::RepeatingCallback<bool(const ui::Event&)> callback);
views::View* content_view_for_testing() { return content_view_; }
PhoneHubUiController* ui_controller_for_testing() {
return ui_controller_.get();
}
PhoneHubNudgeController* phone_hub_nudge_controller_for_testing() {
return phone_hub_nudge_controller_.get();
}
private:
FRIEND_TEST_ALL_PREFIXES(PhoneHubTrayTest, SafeAccessToHeaderView);
// TrayBubbleView::Delegate:
std::u16string GetAccessibleNameForBubble() override;
bool ShouldEnableExtraKeyboardAccessibility() override;
void HideBubble(const TrayBubbleView* bubble_view) override;
// PhoneHubUiController::Observer:
void OnPhoneHubUiStateChanged() override;
// SessionObserver:
void OnSessionStateChanged(session_manager::SessionState state) override;
void OnActiveUserSessionChanged(const AccountId& account_id) override;
// Updates the visibility of the tray in the shelf based on the feature is
// enabled.
void UpdateVisibility();
void UpdateHeaderVisibility();
// Disables the animation and enables it back after a 5s delay. This tray's
// visibility can be updated when the connection is complete. After a session
// has started (login/unlock/user-switch), a duration is added here to delay
// the animation being enabled, since it would take a few seconds to get
// connected.
void TemporarilyDisableAnimation();
// Button click/press handlers for main phone hub icon and secondary
// Eche icon.
void EcheIconActivated(const ui::Event& event);
void PhoneHubIconActivated(const ui::Event& event);
views::View* GetPhoneStatusView();
// Icon of the tray. Unowned.
raw_ptr<views::ImageButton, ExperimentalAsh> icon_;
// Icon for Eche. Unowned.
raw_ptr<views::ImageButton, ExperimentalAsh> eche_icon_ = nullptr;
// The loading indicator, showing a throbber animation on top of the icon.
raw_ptr<EcheIconLoadingIndicatorView, ExperimentalAsh>
eche_loading_indicator_ = nullptr;
// This callback is called when the Eche icon is activated.
base::RepeatingCallback<bool(const ui::Event&)> eche_icon_callback_ =
base::BindRepeating([](const ui::Event&) { return true; });
// Controls the main content view displayed in the bubble based on the current
// PhoneHub state.
std::unique_ptr<PhoneHubUiController> ui_controller_;
// Controls the behavior of a nudge shown to eligible users.
std::unique_ptr<PhoneHubNudgeController> phone_hub_nudge_controller_;
// The bubble that appears after clicking the tray button.
std::unique_ptr<TrayBubbleWrapper> bubble_;
// The header status view on top of the bubble.
// IMPORTANT: This is not owned, always access through GetPhoneStatusView
raw_ptr<views::View, ExperimentalAsh> phone_status_view_dont_use_ = nullptr;
// The main content view of the bubble, which changes depending on the state.
// Unowned.
raw_ptr<PhoneHubContentView, DanglingUntriaged | ExperimentalAsh>
content_view_ = nullptr;
raw_ptr<phonehub::PhoneHubManager, ExperimentalAsh> phone_hub_manager_ =
nullptr;
base::ScopedObservation<PhoneHubUiController, PhoneHubUiController::Observer>
observed_phone_hub_ui_controller_{this};
base::ScopedObservation<SessionControllerImpl, SessionObserver>
observed_session_{this};
base::WeakPtrFactory<PhoneHubTray> weak_factory_{this};
};
} // namespace ash
#endif // ASH_SYSTEM_PHONEHUB_PHONE_HUB_TRAY_H_