Commit f8fb8c69 authored by Alexey Baskakov's avatar Alexey Baskakov Committed by Commit Bot

WebApp: Implement WebAppSyncBridge in full.

This code is disabled by default behind kDesktopPWAsWithoutExtensions and
kDesktopPWAsUSS base features.

- Implement WebAppSyncBridge::MergeSyncData and ApplySyncChanges.
- Implement "Local changes" propagation to change_processor.

Unit tests and browser tests will be added later in a follow up CL.
An MVP implementation of the bridge needed first.

This CL follows Chrome Sync's Model API doc
https://chromium.googlesource.com/chromium/src/+/HEAD/docs/sync/model_api.md

In next CLs:
Implement sync-initiated installs and uninstalls.

TBR=alancutter@chromium.org

Bug: 860583
Change-Id: I65d3cae6f47dd8fc8fdbe2c7cfb2ed13012f90f3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1830494Reviewed-by: default avatarAlexey Baskakov <loyso@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Commit-Queue: Alexey Baskakov <loyso@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704482}
parent 92809357
...@@ -45,6 +45,7 @@ source_set("web_applications") { ...@@ -45,6 +45,7 @@ source_set("web_applications") {
"web_app_registry_update.h", "web_app_registry_update.h",
"web_app_sync_bridge.cc", "web_app_sync_bridge.cc",
"web_app_sync_bridge.h", "web_app_sync_bridge.h",
"web_app_sync_install_delegate.h",
] ]
deps = [ deps = [
......
...@@ -19,6 +19,9 @@ enum Type { ...@@ -19,6 +19,9 @@ enum Type {
kSystem = kMinValue, kSystem = kMinValue,
kPolicy, kPolicy,
kWebAppStore, kWebAppStore,
// We sync only regular user-installed apps from the open web. For
// user-installed apps without overlaps this is the only source that will be
// set.
kSync, kSync,
kDefault, kDefault,
kMaxValue kMaxValue
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "chrome/browser/web_applications/test/test_web_app_database_factory.h" #include "chrome/browser/web_applications/test/test_web_app_database_factory.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/browser/web_applications/web_app_registry_update.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h"
...@@ -21,7 +22,7 @@ void TestWebAppRegistryController::SetUp(Profile* profile) { ...@@ -21,7 +22,7 @@ void TestWebAppRegistryController::SetUp(Profile* profile) {
mutable_registrar_ = std::make_unique<WebAppRegistrarMutable>(profile); mutable_registrar_ = std::make_unique<WebAppRegistrarMutable>(profile);
sync_bridge_ = std::make_unique<WebAppSyncBridge>( sync_bridge_ = std::make_unique<WebAppSyncBridge>(
profile, database_factory_.get(), mutable_registrar_.get(), profile, database_factory_.get(), mutable_registrar_.get(), this,
mock_processor_.CreateForwardingProcessor()); mock_processor_.CreateForwardingProcessor());
ON_CALL(processor(), IsTrackingMetadata()) ON_CALL(processor(), IsTrackingMetadata())
...@@ -51,6 +52,12 @@ void TestWebAppRegistryController::UnregisterAll() { ...@@ -51,6 +52,12 @@ void TestWebAppRegistryController::UnregisterAll() {
update->DeleteApp(app_id); update->DeleteApp(app_id);
} }
void TestWebAppRegistryController::InstallWebAppsAfterSync(
std::vector<WebApp*> web_apps) {}
void TestWebAppRegistryController::UninstallWebAppsAfterSync(
std::vector<std::unique_ptr<WebApp>> web_apps) {}
void TestWebAppRegistryController::DestroySubsystems() { void TestWebAppRegistryController::DestroySubsystems() {
mutable_registrar_.reset(); mutable_registrar_.reset();
sync_bridge_.reset(); sync_bridge_.reset();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_sync_install_delegate.h"
#include "components/sync/model/mock_model_type_change_processor.h" #include "components/sync/model/mock_model_type_change_processor.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -20,7 +21,7 @@ class TestWebAppDatabaseFactory; ...@@ -20,7 +21,7 @@ class TestWebAppDatabaseFactory;
class WebAppSyncBridge; class WebAppSyncBridge;
class WebApp; class WebApp;
class TestWebAppRegistryController { class TestWebAppRegistryController : public SyncInstallDelegate {
public: public:
TestWebAppRegistryController(); TestWebAppRegistryController();
~TestWebAppRegistryController(); ~TestWebAppRegistryController();
...@@ -35,6 +36,11 @@ class TestWebAppRegistryController { ...@@ -35,6 +36,11 @@ class TestWebAppRegistryController {
void UnregisterApp(const AppId& app_id); void UnregisterApp(const AppId& app_id);
void UnregisterAll(); void UnregisterAll();
// SyncInstallDelegate:
void InstallWebAppsAfterSync(std::vector<WebApp*> web_apps) override;
void UninstallWebAppsAfterSync(
std::vector<std::unique_ptr<WebApp>> web_apps) override;
void DestroySubsystems(); void DestroySubsystems();
TestWebAppDatabaseFactory& database_factory() { return *database_factory_; } TestWebAppDatabaseFactory& database_factory() { return *database_factory_; }
......
...@@ -33,6 +33,9 @@ class WebApp { ...@@ -33,6 +33,9 @@ class WebApp {
const GURL& scope() const { return scope_; } const GURL& scope() const { return scope_; }
const base::Optional<SkColor>& theme_color() const { return theme_color_; } const base::Optional<SkColor>& theme_color() const { return theme_color_; }
blink::mojom::DisplayMode display_mode() const { return display_mode_; } blink::mojom::DisplayMode display_mode() const { return display_mode_; }
// Locally installed apps have shortcuts installed on various UI surfaces.
// If app isn't locally installed, it is excluded from UIs and only listed as
// a part of user's app library.
bool is_locally_installed() const { return is_locally_installed_; } bool is_locally_installed() const { return is_locally_installed_; }
// Sync-initiated installation produces a sync placeholder app awaiting for // Sync-initiated installation produces a sync placeholder app awaiting for
// full installation process. The sync placeholder app has only app_id, // full installation process. The sync placeholder app has only app_id,
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/browser/web_applications/web_app_registry_update.h"
#include "components/sync/base/model_type.h" #include "components/sync/base/model_type.h"
#include "components/sync/model/metadata_batch.h" #include "components/sync/model/metadata_batch.h"
#include "components/sync/model/metadata_change_list.h"
#include "components/sync/model/model_error.h" #include "components/sync/model/model_error.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
...@@ -50,7 +51,9 @@ void WebAppDatabase::BeginTransaction() { ...@@ -50,7 +51,9 @@ void WebAppDatabase::BeginTransaction() {
write_batch_ = store_->CreateWriteBatch(); write_batch_ = store_->CreateWriteBatch();
} }
void WebAppDatabase::CommitTransaction(const RegistryUpdateData& update_data, void WebAppDatabase::CommitTransaction(
const RegistryUpdateData& update_data,
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
CompletionCallback callback) { CompletionCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(opened_); DCHECK(opened_);
...@@ -58,6 +61,8 @@ void WebAppDatabase::CommitTransaction(const RegistryUpdateData& update_data, ...@@ -58,6 +61,8 @@ void WebAppDatabase::CommitTransaction(const RegistryUpdateData& update_data,
DCHECK(write_batch_); DCHECK(write_batch_);
DCHECK(!update_data.IsEmpty()); DCHECK(!update_data.IsEmpty());
write_batch_->TakeMetadataChangesFrom(std::move(metadata_change_list));
for (const std::unique_ptr<WebApp>& web_app : update_data.apps_to_create) { for (const std::unique_ptr<WebApp>& web_app : update_data.apps_to_create) {
auto proto = CreateWebAppProto(*web_app); auto proto = CreateWebAppProto(*web_app);
write_batch_->WriteData(web_app->app_id(), proto->SerializeAsString()); write_batch_->WriteData(web_app->app_id(), proto->SerializeAsString());
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
namespace syncer { namespace syncer {
class ModelError; class ModelError;
class MetadataBatch; class MetadataBatch;
class MetadataChangeList;
} // namespace syncer } // namespace syncer
namespace web_app { namespace web_app {
...@@ -49,7 +50,9 @@ class WebAppDatabase { ...@@ -49,7 +50,9 @@ class WebAppDatabase {
using CompletionCallback = base::OnceCallback<void(bool success)>; using CompletionCallback = base::OnceCallback<void(bool success)>;
// There can be only 1 transaction at a time. // There can be only 1 transaction at a time.
void BeginTransaction(); void BeginTransaction();
void CommitTransaction(const RegistryUpdateData& update_data, void CommitTransaction(
const RegistryUpdateData& update_data,
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
CompletionCallback callback); CompletionCallback callback);
void CancelTransaction(); void CancelTransaction();
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_constants.h"
#include "chrome/browser/web_applications/components/web_app_data_retriever.h" #include "chrome/browser/web_applications/components/web_app_data_retriever.h"
#include "chrome/browser/web_applications/components/web_app_utils.h" #include "chrome/browser/web_applications/components/web_app_utils.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_install_task.h" #include "chrome/browser/web_applications/web_app_install_task.h"
#include "chrome/common/web_application_info.h" #include "chrome/common/web_application_info.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -154,6 +155,18 @@ void WebAppInstallManager::Shutdown() { ...@@ -154,6 +155,18 @@ void WebAppInstallManager::Shutdown() {
web_contents_.reset(); web_contents_.reset();
} }
void WebAppInstallManager::InstallWebAppsAfterSync(
std::vector<WebApp*> web_apps) {
// TODO(crbug.com/860583): Implement sync-initiated app installs.
NOTIMPLEMENTED();
}
void WebAppInstallManager::UninstallWebAppsAfterSync(
std::vector<std::unique_ptr<WebApp>> web_apps) {
// TODO(crbug.com/860583): Implement sync-initiated app uninstalls.
NOTIMPLEMENTED();
}
void WebAppInstallManager::SetUrlLoaderForTesting( void WebAppInstallManager::SetUrlLoaderForTesting(
std::unique_ptr<WebAppUrlLoader> url_loader) { std::unique_ptr<WebAppUrlLoader> url_loader) {
url_loader_ = std::move(url_loader); url_loader_ = std::move(url_loader);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "chrome/browser/web_applications/components/install_manager.h" #include "chrome/browser/web_applications/components/install_manager.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/components/web_app_url_loader.h" #include "chrome/browser/web_applications/components/web_app_url_loader.h"
#include "chrome/browser/web_applications/web_app_sync_install_delegate.h"
class Profile; class Profile;
...@@ -29,7 +30,8 @@ enum class InstallResultCode; ...@@ -29,7 +30,8 @@ enum class InstallResultCode;
class WebAppDataRetriever; class WebAppDataRetriever;
class WebAppInstallTask; class WebAppInstallTask;
class WebAppInstallManager final : public InstallManager { class WebAppInstallManager final : public InstallManager,
public SyncInstallDelegate {
public: public:
explicit WebAppInstallManager(Profile* profile); explicit WebAppInstallManager(Profile* profile);
~WebAppInstallManager() override; ~WebAppInstallManager() override;
...@@ -64,6 +66,11 @@ class WebAppInstallManager final : public InstallManager { ...@@ -64,6 +66,11 @@ class WebAppInstallManager final : public InstallManager {
OnceInstallCallback callback) override; OnceInstallCallback callback) override;
void Shutdown() override; void Shutdown() override;
// For the new USS-based system only. SyncInstallDelegate:
void InstallWebAppsAfterSync(std::vector<WebApp*> web_apps) override;
void UninstallWebAppsAfterSync(
std::vector<std::unique_ptr<WebApp>> web_apps) override;
using DataRetrieverFactory = using DataRetrieverFactory =
base::RepeatingCallback<std::unique_ptr<WebAppDataRetriever>()>; base::RepeatingCallback<std::unique_ptr<WebAppDataRetriever>()>;
void SetDataRetrieverFactoryForTesting( void SetDataRetrieverFactoryForTesting(
......
...@@ -170,7 +170,8 @@ void WebAppProvider::CreateWebAppsSubsystems(Profile* profile) { ...@@ -170,7 +170,8 @@ void WebAppProvider::CreateWebAppsSubsystems(Profile* profile) {
auto mutable_registrar = std::make_unique<WebAppRegistrarMutable>(profile); auto mutable_registrar = std::make_unique<WebAppRegistrarMutable>(profile);
sync_bridge = std::make_unique<WebAppSyncBridge>( sync_bridge = std::make_unique<WebAppSyncBridge>(
profile, database_factory_.get(), mutable_registrar.get()); profile, database_factory_.get(), mutable_registrar.get(),
install_manager_.get());
// Upcast to read-only WebAppRegistrar. // Upcast to read-only WebAppRegistrar.
registrar = std::move(mutable_registrar); registrar = std::move(mutable_registrar);
......
...@@ -14,12 +14,14 @@ ...@@ -14,12 +14,14 @@
#include "chrome/browser/web_applications/components/app_registry_controller.h" #include "chrome/browser/web_applications/components/app_registry_controller.h"
#include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_registrar.h"
#include "components/sync/model/entity_change.h"
#include "components/sync/model/model_type_sync_bridge.h" #include "components/sync/model/model_type_sync_bridge.h"
class Profile; class Profile;
namespace syncer { namespace syncer {
class MetadataBatch; class MetadataBatch;
class MetadataChangeList;
class ModelError; class ModelError;
class ModelTypeChangeProcessor; class ModelTypeChangeProcessor;
} // namespace syncer } // namespace syncer
...@@ -27,6 +29,7 @@ class ModelTypeChangeProcessor; ...@@ -27,6 +29,7 @@ class ModelTypeChangeProcessor;
namespace web_app { namespace web_app {
class AbstractWebAppDatabaseFactory; class AbstractWebAppDatabaseFactory;
class SyncInstallDelegate;
class WebAppDatabase; class WebAppDatabase;
class WebAppRegistryUpdate; class WebAppRegistryUpdate;
struct RegistryUpdateData; struct RegistryUpdateData;
...@@ -38,12 +41,14 @@ class WebAppSyncBridge : public AppRegistryController, ...@@ -38,12 +41,14 @@ class WebAppSyncBridge : public AppRegistryController,
public: public:
WebAppSyncBridge(Profile* profile, WebAppSyncBridge(Profile* profile,
AbstractWebAppDatabaseFactory* database_factory, AbstractWebAppDatabaseFactory* database_factory,
WebAppRegistrarMutable* registrar); WebAppRegistrarMutable* registrar,
SyncInstallDelegate* install_delegate);
// Tests may inject mocks using this ctor. // Tests may inject mocks using this ctor.
WebAppSyncBridge( WebAppSyncBridge(
Profile* profile, Profile* profile,
AbstractWebAppDatabaseFactory* database_factory, AbstractWebAppDatabaseFactory* database_factory,
WebAppRegistrarMutable* registrar, WebAppRegistrarMutable* registrar,
SyncInstallDelegate* install_delegate,
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor); std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor);
~WebAppSyncBridge() override; ~WebAppSyncBridge() override;
...@@ -64,8 +69,15 @@ class WebAppSyncBridge : public AppRegistryController, ...@@ -64,8 +69,15 @@ class WebAppSyncBridge : public AppRegistryController,
private: private:
void CheckRegistryUpdateData(const RegistryUpdateData& update_data) const; void CheckRegistryUpdateData(const RegistryUpdateData& update_data) const;
// Update the in-memory model.
void UpdateRegistrar(std::unique_ptr<RegistryUpdateData> update_data); // Update the in-memory model. Returns unregistered apps which may be
// disposed.
std::vector<std::unique_ptr<WebApp>> UpdateRegistrar(
std::unique_ptr<RegistryUpdateData> update_data);
// Update the remote sync server.
void UpdateSync(const RegistryUpdateData& update_data,
syncer::MetadataChangeList* metadata_change_list);
void OnDatabaseOpened(base::OnceClosure callback, void OnDatabaseOpened(base::OnceClosure callback,
Registry registry, Registry registry,
...@@ -74,6 +86,17 @@ class WebAppSyncBridge : public AppRegistryController, ...@@ -74,6 +86,17 @@ class WebAppSyncBridge : public AppRegistryController,
void ReportErrorToChangeProcessor(const syncer::ModelError& error); void ReportErrorToChangeProcessor(const syncer::ModelError& error);
// Any local entities that don’t exist remotely must be provided to sync.
void MergeLocalAppsToSync(const syncer::EntityChangeList& entity_data,
syncer::MetadataChangeList* metadata_change_list);
void ApplySyncDataChange(const syncer::EntityChange& change,
RegistryUpdateData* update_local_data);
// Update registrar and Install/Uninstall missing/excessive local apps.
void ApplySyncChangesToRegistrar(
std::unique_ptr<RegistryUpdateData> update_local_data);
// syncer::ModelTypeSyncBridge: // syncer::ModelTypeSyncBridge:
std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList() std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList()
override; override;
...@@ -90,6 +113,7 @@ class WebAppSyncBridge : public AppRegistryController, ...@@ -90,6 +113,7 @@ class WebAppSyncBridge : public AppRegistryController,
std::unique_ptr<WebAppDatabase> database_; std::unique_ptr<WebAppDatabase> database_;
WebAppRegistrarMutable* const registrar_; WebAppRegistrarMutable* const registrar_;
SyncInstallDelegate* const install_delegate_;
bool is_in_update_ = false; bool is_in_update_ = false;
......
// Copyright 2019 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_SYNC_INSTALL_DELEGATE_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_SYNC_INSTALL_DELEGATE_H_
#include <memory>
#include <vector>
namespace web_app {
class WebApp;
// WebAppSyncBridge delegates sync-initiated installs and uninstalls using
// this interface.
class SyncInstallDelegate {
public:
virtual ~SyncInstallDelegate() = default;
// |web_apps| are already registered and owned by the registrar.
virtual void InstallWebAppsAfterSync(std::vector<WebApp*> web_apps) = 0;
// |web_apps| are already unregistered and not owned by the registrar.
virtual void UninstallWebAppsAfterSync(
std::vector<std::unique_ptr<WebApp>> web_apps) = 0;
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_SYNC_INSTALL_DELEGATE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment