blob: 4a627a2ab94730dbd009a4d277b801883bd41af2 [file] [log] [blame]
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_COMMAND_MANAGER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_COMMAND_MANAGER_H_
#include <deque>
#include <map>
#include <memory>
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/values.h"
#include "chrome/browser/web_applications/commands/web_app_command.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_id.h"
#include "components/services/storage/indexed_db/locks/disjoint_range_lock_manager.h"
#include "components/services/storage/indexed_db/locks/leveled_lock_manager.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
class Profile;
namespace content {
class WebContents;
}
namespace web_app {
// The command manager is used to schedule commands or callbacks to write & read
// from the WebAppProvider system. To use, simply call `ScheduleCommand` to
// schedule the given command or a CallbackCommand with given callback.
//
// Commands will be executed (`Start()` will be called) in-order based on
// command's `WebAppCommandLock`, the `WebAppCommandLock` specifies which apps
// or particular entities it wants to lock on. The next command will not execute
// until `SignalCompletionAndSelfDestruct()` was called by the last command.
class WebAppCommandManager {
public:
explicit WebAppCommandManager(Profile* profile);
~WebAppCommandManager();
// Enqueues the given command in the queue corresponding to the command's
// `queue_id()`. `Start()` will always be called asynchronously.
void ScheduleCommand(std::unique_ptr<WebAppCommand> command);
// Called on system shutdown. This call is also forwarded to any commands that
// have been `Start()`ed.
void Shutdown();
// Called by the sync integration when a list of apps are going to be deleted
// from the registry. Any commands that whose `queue_id()`s match an id in
// `app_id` who have also been `Start()`ed will also be notified.
void NotifyBeforeSyncUninstalls(const std::vector<AppId>& app_ids);
// Outputs a debug value of the state of the commands system, including
// running and queued commands.
base::Value ToDebugValue();
protected:
friend class WebAppCommand;
void OnCommandComplete(WebAppCommand* running_command,
CommandResult result,
base::OnceClosure completion_callback);
private:
void AddValueToLog(base::Value value);
void OnLockAcquired(WebAppCommand::Id command_id);
void StartCommand(WebAppCommand* command);
content::WebContents* EnsureWebContentsCreated();
struct CommandState {
explicit CommandState(std::unique_ptr<WebAppCommand> command);
~CommandState();
std::unique_ptr<WebAppCommand> command;
content::LeveledLockHolder lock_holder;
};
SEQUENCE_CHECKER(command_sequence_checker_);
std::map<WebAppCommand::Id, CommandState> commands_{};
Profile* profile_;
std::unique_ptr<content::WebContents> shared_web_contents_;
bool is_in_shutdown_ = false;
std::deque<base::Value> command_debug_log_;
content::DisjointRangeLockManager lock_manager_{
static_cast<int>(WebAppCommandLock::LockLevel::kMaxValue) + 1};
base::WeakPtrFactory<WebAppCommandManager> weak_ptr_factory_{this};
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_COMMAND_MANAGER_H_