chromium/chrome/browser/ash/boca/on_task/on_task_locked_session_window_tracker.h

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_BOCA_ON_TASK_ON_TASK_LOCKED_SESSION_WINDOW_TRACKER_H_
#define CHROME_BROWSER_ASH_BOCA_ON_TASK_ON_TASK_LOCKED_SESSION_WINDOW_TRACKER_H_

#include "base/memory/raw_ptr.h"
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chromeos/ash/components/boca/on_task/on_task_blocklist.h"
#include "components/keyed_service/core/keyed_service.h"

class Browser;
class BrowserList;

// This class is used to track the windows and tabs that are opened in the
// user's OnTask locked session. Only one browser window is allowed at a time to
// be tracked. Attempting to track another browser while there is one already
// tracked will reset the tracker and setup for the new browser. It will be used
// to block the navigation of the tabs that are not allowed to be opened in the
// locked session. Each tab has its set of rules as defined in the
// `OnTaskBlocklist` which determines what types of urls are allowed on a per
// tab basis. See `OnTaskBlocklist` for more details about what the restrictions
// are. All of these calls should be called from the main thread.
class LockedSessionWindowTracker : public KeyedService,
                                   public TabStripModelObserver,
                                   public BrowserListObserver {
 public:
  explicit LockedSessionWindowTracker(
      std::unique_ptr<OnTaskBlocklist> on_task_blocklist);
  LockedSessionWindowTracker(const LockedSessionWindowTracker&) = delete;
  LockedSessionWindowTracker& operator=(const LockedSessionWindowTracker&) =
      delete;
  ~LockedSessionWindowTracker() override;

  // Starts tracking the `browser` for navigation changes.
  void InitializeBrowserInfoForTracking(Browser* browser);

  // Updates the current blocklist with its appropriate restriction. This should
  // rarely be explicitly called except for when we start tracking a new browser
  // window. All other calls should come from tab strip model changes (ex:
  // active tab changes).
  // TODO: b/357139784 - Remove RefreshBlockList.
  void RefreshUrlBlocklist();

  // Checks to make sure this is the first time an OAuth popup has occurred.
  // This is to make sure popup retries don't try to reopen windows while older
  // popups are still open.
  bool IsFirstTimePopup();

  OnTaskBlocklist* on_task_blocklist();
  Browser* browser();

 private:
  // TabStripModelObserver Impl
  void TabChangedAt(content::WebContents* contents,
                    int index,
                    TabChangeType change_type) override;
  void OnTabStripModelChanged(
      TabStripModel* tab_strip_model,
      const TabStripModelChange& change,
      const TabStripSelectionChange& selection) override;

  // BrowserListObserver Implementation
  void OnBrowserClosing(Browser* browser) override;
  void OnBrowserAdded(Browser* browser) override;

  void MaybeCloseBrowser(base::WeakPtr<Browser> weak_browser_ptr);
  void CleanupWindowTracker();

  bool first_time_popup_ = true;
  const std::unique_ptr<OnTaskBlocklist> on_task_blocklist_;
  raw_ptr<Browser> browser_ = nullptr;

  base::ScopedObservation<BrowserList, BrowserListObserver>
      browser_list_observation_{this};
  base::WeakPtrFactory<LockedSessionWindowTracker> weak_pointer_factory_{this};
};

#endif  // CHROME_BROWSER_ASH_BOCA_ON_TASK_ON_TASK_LOCKED_SESSION_WINDOW_TRACKER_H_