blob: f7459072ca4faecb8027f0a4b8e8e9afdc30de35 [file] [log] [blame]
// Copyright 2019 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_UI_EXTENSIONS_EXTENSION_INSTALLED_WAITER_H_
#define CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_INSTALLED_WAITER_H_
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
class Browser;
// ExtensionInstalledWaiter is used to wait for a given extension to be
// installed in a given browser's profile.
class ExtensionInstalledWaiter : public extensions::ExtensionRegistryObserver,
public BrowserListObserver {
public:
// Wait until both:
// 1. |extension| is installed into |browser|
// 2. All EXTENSION_LOADED observers have been notified of (1)
// and then invoke |done_callback|.
// If either |browser| is destroyed or |extension| is uninstalled from it
// before that happens, |done_callback| is not run.
static void WaitForInstall(
scoped_refptr<const extensions::Extension> extension,
Browser* browser,
base::OnceClosure done_callback);
// Sets a callback for testing purposes to be invoked whenever an
// ExtensionInstalledWaiter gives up on waiting for any reason. You should not
// need this in production code!
static void SetGivingUpCallbackForTesting(base::RepeatingClosure callback);
private:
// This class manages its own lifetime.
ExtensionInstalledWaiter(scoped_refptr<const extensions::Extension> extension,
Browser* browser,
base::OnceClosure done_callback);
~ExtensionInstalledWaiter() override;
ExtensionInstalledWaiter(const ExtensionInstalledWaiter& other) = delete;
ExtensionInstalledWaiter& operator=(const ExtensionInstalledWaiter& other) =
delete;
// Check if the extension is installed. If so, run |done_callback_| and
// self-destruct.
void RunCallbackIfExtensionInstalled();
// Returns whether condition (1) as described above WaitForInstall
// are true. Condition (2) is guaranteed by logic in OnExtensionLoaded.
bool IsExtensionInstalled() const;
// ExtensionRegistryObserver:
void OnExtensionLoaded(content::BrowserContext* browser_context,
const extensions::Extension* extension) override;
void OnExtensionUnloaded(content::BrowserContext* browser_context,
const extensions::Extension* extension,
extensions::UnloadedExtensionReason reason) override;
// BrowserListObserver:
void OnBrowserRemoved(Browser* browser) override;
const scoped_refptr<const extensions::Extension> extension_;
const raw_ptr<const Browser> browser_;
base::OnceClosure done_callback_;
base::ScopedObservation<extensions::ExtensionRegistry,
extensions::ExtensionRegistryObserver>
extension_registry_observation_{this};
base::WeakPtrFactory<ExtensionInstalledWaiter> weak_factory_{this};
};
#endif // CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_INSTALLED_WAITER_H_