1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151

ash / system / phonehub / phone_hub_ui_controller.h [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_UI_CONTROLLER_H_
#define ASH_SYSTEM_PHONEHUB_PHONE_HUB_UI_CONTROLLER_H_

#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/system/phonehub/onboarding_view.h"
#include "ash/system/phonehub/phone_hub_content_view.h"
#include "ash/system/phonehub/phone_status_view.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/timer/timer.h"
#include "chromeos/ash/components/phonehub/app_stream_launcher_data_model.h"
#include "chromeos/ash/components/phonehub/feature_status_provider.h"
#include "chromeos/ash/components/phonehub/onboarding_ui_tracker.h"
#include "chromeos/ash/components/phonehub/phone_model.h"

namespace views {
class View;
}  // namespace views

namespace ash {

namespace phonehub {
class PhoneHubManager;
}

// This controller translates the state received from PhoneHubManager into the
// corresponding main content view to be displayed in the tray bubble.
class ASH_EXPORT PhoneHubUiController
    : public phonehub::FeatureStatusProvider::Observer,
      public phonehub::OnboardingUiTracker::Observer,
      public phonehub::PhoneModel::Observer,
      public phonehub::AppStreamLauncherDataModel::Observer,
      public SessionObserver {
 public:
  class Observer : public base::CheckedObserver {
   public:
    ~Observer() override = default;

    virtual void OnPhoneHubUiStateChanged() = 0;
  };

  // All the possible states that the main content view can be in. Each state
  // has a corresponding view class.
  enum class UiState {
    kHidden = 0,
    kOnboardingWithoutPhone,
    kOnboardingWithPhone,
    kBluetoothDisabled,
    kPhoneConnecting,
    kPhoneDisconnected,
    kPhoneConnected,
    kTetherConnectionPending,
    kMiniLauncher,
    kMaxValue = kMiniLauncher
  };

  PhoneHubUiController();
  PhoneHubUiController(const PhoneHubUiController&) = delete;
  ~PhoneHubUiController() override;
  PhoneHubUiController& operator=(const PhoneHubUiController&) = delete;

  // Sets the PhoneHubManager that provides the data to drive the UI.
  void SetPhoneHubManager(phonehub::PhoneHubManager* phone_hub_manager);

  // Creates the corresponding content view for the current UI state.
  // |bubble_view| will be the parent the created content view.
  std::unique_ptr<PhoneHubContentView> CreateContentView(
      OnboardingView::Delegate* delegate);

  // Creates the header view displaying the phone status.
  std::unique_ptr<views::View> CreateStatusHeaderView(
      PhoneStatusView::Delegate* delegate);

  // Handler for when the bubble is opened. Requests a connection to the phone
  // if there is no current connection, and records metrics.
  void HandleBubbleOpened();

  // Observer functions.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  UiState ui_state() const { return ui_state_; }

 private:
  // phonehub::FeatureStatusProvider::Observer:
  void OnFeatureStatusChanged() override;

  // phonehub::OnboardingUiTracker::Observer:
  void OnShouldShowOnboardingUiChanged() override;

  // phonehub::AppStreamLauncherDataModel::Observer:
  void OnShouldShowMiniLauncherChanged() override;

  // phonehub::PhoneModel::Observer:
  void OnModelChanged() override;

  // SessionObserver:
  void OnActiveUserSessionChanged(const AccountId& account_id) override;

  // Updates the current UI state and notifies observers.
  void UpdateUiState(PhoneHubUiController::UiState new_state);

  // Returns the UiState from the PhoneHubManager.
  UiState GetUiStateFromPhoneHubManager();

  // Returns the UiState from the PhoneHubManager.
  UiState GetUiStateFromPhoneHubManagerInternal();

  // Cleans up |phone_hub_manager_| by removing all observers.
  void CleanUpPhoneHubManager();

  // When |connecting_view_grace_period_timer_| ends, triggers a change in
  // the content view to show a disconnected view.
  void OnConnectingViewTimerEnd();

  void RecordStatusOnBubbleOpened();
  void OnGetHostLastSeenTimestamp(UiState ui_state_when_opened,
                                  std::optional<base::Time> timestamp);

  // The PhoneHubManager that provides data for the UI.
  raw_ptr<phonehub::PhoneHubManager> phone_hub_manager_ = nullptr;

  // The current UI state.
  UiState ui_state_ = UiState::kHidden;

  // This value becomes true the first time the user opens the PhoneHub UI
  // when the feature is in the enabled state, and a tether scan request is
  // made.
  bool has_requested_tether_scan_during_session_ = false;

  // Registered observers.
  base::ObserverList<Observer> observer_list_;

  // The timer that dictates how long to show |kConnecting| after disconnect
  // so when the connection fails on the first attempt and retries, it is not
  // confusing to users when it shows disconnecting view, rather, it will show
  // connecting view on this occasion.
  base::OneShotTimer connecting_view_grace_period_timer_;

  base::WeakPtrFactory<PhoneHubUiController> weak_ptr_factory_{this};
};

}  // namespace ash

#endif  // ASH_SYSTEM_PHONEHUB_PHONE_HUB_UI_CONTROLLER_H_