0
Files
src/chrome/browser/web_applications/web_app_database.h
Glen Robertson 9a8865864e Reland "WebApps: Store whole sync proto to prevent losing new fields"
This is a reland of commit 44b6667c57

Fixes a bug in the original CL where fields weren't cleared before
being maybe-set. Adds a test that verifies the correct behaviour.

Note Patchset#1 is a pure reland, so you can see the diff.

Original change's description:
> WebApps: Store whole sync proto to prevent losing new fields
>
> Currently we convert a WebAppSpecifics sync proto into several fields
> which are stored on the WebApp struct (or its WebAppSpecifics struct) in
> memory. When writing to disk or sync we convert back into a
> WebAppSpecifics proto. This conversion causes data loss of new fields
> and new field values when handled by older clients.
>
> This CL stores the sync proto directly on the WebApp struct so lossy
> conversions aren't done and the data is maintained. An exception is that
> we still actively convert absent UserDisplayMode values into set values,
> and proto2 (which we are using) represents unknown enum values as
> absent. A follow-up CL could change this to lazily set UserDisplayMode
> values instead, in order to preserve new enum values.
>
> Bug: b:320769909
> Change-Id: Ieaf98d25d5cc359ca9906b5c7e1d31543a3b88f1
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5372767
> Commit-Queue: Glen Robertson <glenrob@chromium.org>
> Reviewed-by: Daniel Murphy <dmurph@chromium.org>
> Reviewed-by: Mahmoud Rashad <mmrashad@google.com>
> Reviewed-by: Dibyajyoti Pal <dibyapal@chromium.org>
> Reviewed-by: Kyle Horimoto <khorimoto@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1276651}

Bug: b:320769909
Change-Id: Ibbf34e3662e7fdf0ef9d82ea0c6ea68a32bb0ff6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5418533
Reviewed-by: Mahmoud Rashad <mmrashad@google.com>
Auto-Submit: Glen Robertson <glenrob@chromium.org>
Reviewed-by: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: Kyle Horimoto <khorimoto@chromium.org>
Commit-Queue: Glen Robertson <glenrob@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1287120}
2024-04-15 01:17:28 +00:00

107 lines
3.7 KiB
C++

// Copyright 2018 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_WEB_APPLICATIONS_WEB_APP_DATABASE_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_DATABASE_H_
#include <memory>
#include <optional>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "chrome/browser/web_applications/proto/web_app.pb.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "components/sync/model/model_type_store.h"
#include "components/sync/protocol/web_app_specifics.pb.h"
#include "components/webapps/common/web_app_id.h"
namespace syncer {
class ModelError;
class MetadataBatch;
class MetadataChangeList;
} // namespace syncer
namespace web_app {
class AbstractWebAppDatabaseFactory;
class WebApp;
class WebAppProto;
struct RegistryUpdateData;
// Exclusively used from the UI thread.
class WebAppDatabase {
public:
using ReportErrorCallback =
base::RepeatingCallback<void(const syncer::ModelError&)>;
WebAppDatabase(AbstractWebAppDatabaseFactory* database_factory,
ReportErrorCallback error_callback);
WebAppDatabase(const WebAppDatabase&) = delete;
WebAppDatabase& operator=(const WebAppDatabase&) = delete;
~WebAppDatabase();
using RegistryOpenedCallback = base::OnceCallback<void(
Registry registry,
std::unique_ptr<syncer::MetadataBatch> metadata_batch)>;
// Open existing or create new DB. Read all data and return it via callback.
void OpenDatabase(RegistryOpenedCallback callback);
using CompletionCallback = base::OnceCallback<void(bool success)>;
void Write(const RegistryUpdateData& update_data,
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
CompletionCallback callback);
// Exposed for testing.
static std::unique_ptr<WebAppProto> CreateWebAppProto(const WebApp& web_app);
// Exposed for testing.
static std::unique_ptr<WebApp> ParseWebApp(const webapps::AppId& app_id,
const std::string& value);
// Exposed for testing.
static std::unique_ptr<WebApp> CreateWebApp(const WebAppProto& local_data);
bool is_opened() const { return opened_; }
private:
void OnDatabaseOpened(RegistryOpenedCallback callback,
const std::optional<syncer::ModelError>& error,
std::unique_ptr<syncer::ModelTypeStore> store);
void OnAllDataRead(
RegistryOpenedCallback callback,
const std::optional<syncer::ModelError>& error,
std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records);
void OnAllMetadataRead(
std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records,
RegistryOpenedCallback callback,
const std::optional<syncer::ModelError>& error,
std::unique_ptr<syncer::MetadataBatch> metadata_batch);
void OnDataWritten(CompletionCallback callback,
const std::optional<syncer::ModelError>& error);
std::unique_ptr<syncer::ModelTypeStore> store_;
const raw_ptr<AbstractWebAppDatabaseFactory, DanglingUntriaged>
database_factory_;
ReportErrorCallback error_callback_;
// Database is opened if store is created and all data read.
bool opened_ = false;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<WebAppDatabase> weak_ptr_factory_{this};
};
DisplayMode ToMojomDisplayMode(WebAppProto::DisplayMode display_mode);
WebAppProto::DisplayMode ToWebAppProtoDisplayMode(DisplayMode display_mode);
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_DATABASE_H_