blob: 569b6faa66b388ea77baa086573834a37a51031f [file] [log] [blame]
// Copyright 2020 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_MIGRATION_USER_DISPLAY_MODE_CLEAN_UP_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_MIGRATION_USER_DISPLAY_MODE_CLEAN_UP_H_
#include <memory>
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "chrome/browser/web_applications/extensions/bookmark_app_registrar.h"
#include "chrome/browser/web_applications/extensions/bookmark_app_registry_controller.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_service_observer.h"
class Profile;
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace web_app {
class WebAppSyncBridge;
// # Background
// This is a clean up job for https://crbug.com/1125020.
// When BMO shipped to stable the WebAppMigrationManager migration used the
// wrong user_display_mode for kStandalone bookmark apps that were not locally
// installed. It read kBrowser instead of kStandalone because we always open
// non-locally installed apps in browser tabs. The migrated kBrowser web app
// was then used to populate the sync server which replicated across to all
// other devices. Even if they had kStandalone locally installed bookmark apps
// that migrated correctly our sync logic always chooses the sync server's data
// over the local data. If the first device to migrate and populate the sync
// server hit this bug then all devices would replicate the kBrowser state.
// In effect users would experience their kStandalone window PWAs opening in
// browser tabs instead.
//
// # Clean up pseudocode
// On start up:
// - Check that we haven't already run this clean up successfully.
// - Wait for bookmark apps, web apps and sync to be ready.
// - Check for any kStandalone bookmarks with corresponding kBrowser web apps.
// - Set those web apps to be kStandalone.
//
// # Known issue
// The migration bug is indistinguishable from a user manually setting the
// user_display_mode for their web apps to kBrowser after migration. This clean
// up CL will erroneously undo such a change. To mitigate this we only run the
// clean up once per migrated device.
class WebAppMigrationUserDisplayModeCleanUp
: public syncer::SyncServiceObserver {
public:
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
static std::unique_ptr<WebAppMigrationUserDisplayModeCleanUp> CreateIfNeeded(
Profile* profile,
WebAppSyncBridge* sync_bridge);
static void DisableForTesting();
static void SkipWaitForSyncForTesting();
static void SetCompletedCallbackForTesting(base::OnceClosure callback);
WebAppMigrationUserDisplayModeCleanUp(Profile* profile,
WebAppSyncBridge* sync_bridge);
WebAppMigrationUserDisplayModeCleanUp(
const WebAppMigrationUserDisplayModeCleanUp&) = delete;
WebAppMigrationUserDisplayModeCleanUp& operator=(
const WebAppMigrationUserDisplayModeCleanUp&) = delete;
~WebAppMigrationUserDisplayModeCleanUp() final;
void Start();
void Shutdown();
// syncer::SyncServiceObserver:
void OnSyncCycleCompleted(syncer::SyncService* sync_service) final;
void OnSyncShutdown(syncer::SyncService* sync_service) final;
private:
void OnBookmarkAppRegistryReady();
void WaitForFirstSyncCycle(base::OnceClosure callback);
void OnFirstSyncCycleComplete();
Profile* profile_ = nullptr;
WebAppSyncBridge* sync_bridge_ = nullptr;
syncer::SyncService* sync_service_ = nullptr;
base::OnceClosure sync_ready_callback_;
extensions::BookmarkAppRegistrar bookmark_app_registrar_;
extensions::BookmarkAppRegistryController bookmark_app_registry_controller_;
ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver>
sync_observer_{this};
base::WeakPtrFactory<WebAppMigrationUserDisplayModeCleanUp> weak_ptr_factory_{
this};
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_MIGRATION_USER_DISPLAY_MODE_CLEAN_UP_H_