chromium/ash/app_list/views/continue_section_view.h

// Copyright 2021 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_APP_LIST_VIEWS_CONTINUE_SECTION_VIEW_H_
#define ASH_APP_LIST_VIEWS_CONTINUE_SECTION_VIEW_H_

#include "ash/app_list/app_list_model_provider.h"
#include "ash/app_list/views/continue_task_container_view.h"
#include "ash/ash_export.h"
#include "ash/public/cpp/app_list/app_list_controller_observer.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/view.h"

namespace ash {

class AppListNudgeController;
class AppListViewDelegate;
class AppListToastView;
class ContinueTaskContainerView;
class ContinueTaskView;

// The "Continue" section of the bubble launcher. This view wraps around
// suggestions with tasks to continue.
class ASH_EXPORT ContinueSectionView : public views::View,
                                       public views::FocusChangeListener,
                                       public AppListModelProvider::Observer,
                                       public AppListControllerObserver {
  METADATA_HEADER(ContinueSectionView, views::View)

 public:
  ContinueSectionView(AppListViewDelegate* view_delegate,
                      int columns,
                      bool tablet_mode);
  ContinueSectionView(const ContinueSectionView&) = delete;
  ContinueSectionView& operator=(const ContinueSectionView&) = delete;
  ~ContinueSectionView() override;

  // Returns true if the continue section removal metrics should be logged.
  static bool EnableContinueSectionFileRemovalMetrics();

  // Reset for the continue section file removal metric logging enabling.
  static void ResetContinueSectionFileRemovalMetricEnabledForTest();

  // Called when the `suggestion_container_` finishes updating the tasks.
  void OnSearchResultContainerResultsChanged();

  // Schedule an update to the `suggestion_container_` tasks.
  void UpdateSuggestionTasks();

  size_t GetTasksSuggestionsCount() const;

  void DisableFocusForShowingActiveFolder(bool disabled);

  ContinueTaskView* GetTaskViewAtForTesting(size_t index) const;

  // Whether the privacy notice should be shown to the user.
  bool ShouldShowPrivacyNotice() const;

  // Whether the continue files should be shown to the user.
  bool ShouldShowFilesSection() const;

  // Stops the running `privacy_notice_shown_timer_` if the privacy notice is
  // shown in background.
  void SetShownInBackground(bool shown_in_background);

  void SetNudgeController(AppListNudgeController* nudge_controller);

  // Refresh the continue section element's visibility such as the privacy
  // notice, the continue label and the continue section itself.
  void UpdateElementsVisibility();

  ContinueTaskContainerView* suggestions_container() {
    return suggestions_container_;
  }

  // views::View:
  void AddedToWidget() override;
  void RemovedFromWidget() override;

  // views::FocusChangeListener:
  void OnWillChangeFocus(views::View* focused_before,
                         views::View* focused_now) override {}
  void OnDidChangeFocus(views::View* focused_before,
                        views::View* focused_now) override;

  // AppListModelProvider::Observer:
  void OnActiveAppListModelsChanged(AppListModel* model,
                                    SearchModel* search_model) override;

  // AppListControllerObserver:
  void OnAppListVisibilityChanged(bool shown, int64_t display_id) override;

  // Sets the available width for the privacy toast view, so the privacy toast
  // preferred size fits within `available_width` of available horizontal space.
  void ConfigureLayoutForAvailableWidth(int available_width);

  AppListNudgeController* nudge_controller_for_test() const {
    return nudge_controller_;
  }

  // Fire `privacy_notice_shown_timer_` for testing purposes.
  bool FirePrivacyNoticeShownTimerForTest();

  AppListToastView* GetPrivacyNoticeForTest() const { return privacy_toast_; }

 private:
  // Whether there are a sufficient number of files to display the
  // section.
  bool HasMinimumFilesToShow() const;

  // Whether there is at least 1 admin template.
  bool HasDesksAdminTemplates() const;

  // Displays a toast with a privacy notice for the user in place of the
  // continue section. The user can accept the notice to display the continue
  // section in the launcher.
  void MaybeCreatePrivacyNotice();

  // Removes the privacy notice from the view.
  void RemovePrivacyNotice();

  // Invoked when the privacy notice has been shown for enough time.
  void OnPrivacyNoticeShowTimerDone();

  // Invoked when the privacy notice has been acknowledged.
  void OnPrivacyToastAcknowledged();

  // Starts the animation to dismiss the privacy notice toast.
  void AnimateDismissToast(base::RepeatingClosure callback);

  // Starts the animation to show the continue section in the app list bubble.
  void AnimateShowContinueSection();

  // Starts the animation for sliding other launcher content by
  // `vertical_offset`.
  void AnimateSlideLauncherContent(int vertical_offset);

  // Starts the animation to dismiss the privacy notice toast only. This is used
  // when the privacy notice does not have enough items after an update.
  void MaybeAnimateOutPrivacyNotice();

  const raw_ptr<AppListViewDelegate> view_delegate_;

  // If set, the amount of horizontal space available for the continue section -
  // used to configure layout for the continue section privacy notice toast.
  std::optional<int> available_width_;

  bool tablet_mode_ = false;

  // Timer for marking the privacy notice as shown.
  base::OneShotTimer privacy_notice_shown_timer_;

  // Not owned.
  raw_ptr<AppListNudgeController, DanglingUntriaged> nudge_controller_ =
      nullptr;

  raw_ptr<AppListToastView, DanglingUntriaged> privacy_toast_ = nullptr;
  raw_ptr<ContinueTaskContainerView> suggestions_container_ = nullptr;

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

}  // namespace ash

#endif  // ASH_APP_LIST_VIEWS_CONTINUE_SECTION_VIEW_H_