Skip to content
This repository has been archived by the owner on Sep 25, 2019. It is now read-only.

Commit

Permalink
[Sync] Add support for automatic enabling of syncing tab favicons.
Browse files Browse the repository at this point in the history
We add the sync_tab_favicons field to the nigori node and add support
for automatically enabling the feature when we receive a new nigori node.
Once we do enable the feature, the browser will only start writing favicons
after the next restart.

BUG=92728
TEST=using python testserver to enable sync tab favicons, then restarting.


Review URL: http://codereview.chromium.org/10235013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134184 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
zea@chromium.org committed Apr 27, 2012
1 parent b073881 commit 30cc5ed
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 23 deletions.
6 changes: 6 additions & 0 deletions chrome/app/generated_resources.grd
Expand Up @@ -5282,6 +5282,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_SYNC_TABS_DESCRIPTION" desc="Description for the flag to enable syncing the open tabs datatype"> <message name="IDS_FLAGS_SYNC_TABS_DESCRIPTION" desc="Description for the flag to enable syncing the open tabs datatype">
Enable open tabs in the sync settings. This allows syncing your open tabs to other clients. Enable open tabs in the sync settings. This allows syncing your open tabs to other clients.
</message> </message>
<message name="IDS_FLAGS_SYNC_TAB_FAVICONS_NAME" desc="Title for the flag to enable syncing tab favicons with tab sync">
Enable tab favicon sync.
</message>
<message name="IDS_FLAGS_SYNC_TAB_FAVICONS_DESCRIPTION" desc="Description for the flag to enable syncing tab favicons with tab sync">
Enable syncing the favicons of open tabs as part of Open Tab sync.
</message>
<message name="IDS_FLAGS_SYNC_APP_NOTIFICATIONS_NAME" desc="Title for the flag to disable syncing the app notifications datatype"> <message name="IDS_FLAGS_SYNC_APP_NOTIFICATIONS_NAME" desc="Title for the flag to disable syncing the app notifications datatype">
Disable syncing app notifications Disable syncing app notifications
</message> </message>
Expand Down
7 changes: 7 additions & 0 deletions chrome/browser/about_flags.cc
Expand Up @@ -350,6 +350,13 @@ const Experiment kExperiments[] = {
kOsAll, kOsAll,
SINGLE_VALUE_TYPE(switches::kEnableSyncTabs) SINGLE_VALUE_TYPE(switches::kEnableSyncTabs)
}, },
{
"sync-tab-favicons",
IDS_FLAGS_SYNC_TAB_FAVICONS_NAME,
IDS_FLAGS_SYNC_TAB_FAVICONS_DESCRIPTION,
kOsAll,
SINGLE_VALUE_TYPE(switches::kSyncTabFavicons)
},
{ {
"sync-app-notifications", "sync-app-notifications",
IDS_FLAGS_SYNC_APP_NOTIFICATIONS_NAME, IDS_FLAGS_SYNC_APP_NOTIFICATIONS_NAME,
Expand Down
7 changes: 4 additions & 3 deletions chrome/browser/sync/glue/sync_backend_host.cc
Expand Up @@ -45,6 +45,7 @@
#include "sync/notifier/sync_notifier.h" #include "sync/notifier/sync_notifier.h"
#include "sync/protocol/encryption.pb.h" #include "sync/protocol/encryption.pb.h"
#include "sync/protocol/sync.pb.h" #include "sync/protocol/sync.pb.h"
#include "sync/util/experiments.h"
#include "sync/util/nigori.h" #include "sync/util/nigori.h"


static const int kSaveChangesIntervalSeconds = 10; static const int kSaveChangesIntervalSeconds = 10;
Expand Down Expand Up @@ -1212,9 +1213,9 @@ void SyncBackendHost::Core::SaveChanges() {


void SyncBackendHost::AddExperimentalTypes() { void SyncBackendHost::AddExperimentalTypes() {
CHECK(initialized()); CHECK(initialized());
syncable::ModelTypeSet to_add; Experiments experiments;
if (core_->sync_manager()->ReceivedExperimentalTypes(&to_add)) if (core_->sync_manager()->ReceivedExperiment(&experiments))
frontend_->OnDataTypesChanged(to_add); frontend_->OnExperimentsChanged(experiments);
} }


void SyncBackendHost::OnNigoriDownloadRetry() { void SyncBackendHost::OnNigoriDownloadRetry() {
Expand Down
4 changes: 3 additions & 1 deletion chrome/browser/sync/glue/sync_backend_host.h
Expand Up @@ -38,6 +38,7 @@ class Profile;
namespace browser_sync { namespace browser_sync {


class ChangeProcessor; class ChangeProcessor;
struct Experiments;
class JsBackend; class JsBackend;
class JsEventHandler; class JsEventHandler;
class SyncBackendRegistrar; class SyncBackendRegistrar;
Expand Down Expand Up @@ -121,7 +122,8 @@ class SyncFrontend {
syncable::ModelTypeSet types) = 0; syncable::ModelTypeSet types) = 0;


// Inform the Frontend that new datatypes are available for registration. // Inform the Frontend that new datatypes are available for registration.
virtual void OnDataTypesChanged(syncable::ModelTypeSet to_add) = 0; virtual void OnExperimentsChanged(
const browser_sync::Experiments& experiments) = 0;


// Called when the sync cycle returns there is an user actionable error. // Called when the sync cycle returns there is an user actionable error.
virtual void OnActionableError( virtual void OnActionableError(
Expand Down
4 changes: 3 additions & 1 deletion chrome/browser/sync/glue/sync_backend_host_unittest.cc
Expand Up @@ -17,6 +17,7 @@
#include "sync/protocol/encryption.pb.h" #include "sync/protocol/encryption.pb.h"
#include "sync/protocol/sync_protocol_error.h" #include "sync/protocol/sync_protocol_error.h"
#include "sync/syncable/model_type.h" #include "sync/syncable/model_type.h"
#include "sync/util/experiments.h"
#include "sync/util/test_unrecoverable_error_handler.h" #include "sync/util/test_unrecoverable_error_handler.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
Expand Down Expand Up @@ -46,7 +47,8 @@ class MockSyncFrontend : public SyncFrontend {
void(syncable::ModelTypeSet, bool)); void(syncable::ModelTypeSet, bool));
MOCK_METHOD0(OnEncryptionComplete, void()); MOCK_METHOD0(OnEncryptionComplete, void());
MOCK_METHOD1(OnMigrationNeededForTypes, void(syncable::ModelTypeSet)); MOCK_METHOD1(OnMigrationNeededForTypes, void(syncable::ModelTypeSet));
MOCK_METHOD1(OnDataTypesChanged, void(syncable::ModelTypeSet)); MOCK_METHOD1(OnExperimentsChanged,
void(const browser_sync::Experiments&));
MOCK_METHOD1(OnActionableError, MOCK_METHOD1(OnActionableError,
void(const browser_sync::SyncProtocolError& sync_error)); void(const browser_sync::SyncProtocolError& sync_error));
MOCK_METHOD0(OnSyncConfigureRetry, void()); MOCK_METHOD0(OnSyncConfigureRetry, void());
Expand Down
31 changes: 22 additions & 9 deletions chrome/browser/sync/profile_sync_service.cc
Expand Up @@ -61,6 +61,7 @@
#include "sync/js/js_arg_list.h" #include "sync/js/js_arg_list.h"
#include "sync/js/js_event_details.h" #include "sync/js/js_event_details.h"
#include "sync/util/cryptographer.h" #include "sync/util/cryptographer.h"
#include "sync/util/experiments.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"


using browser_sync::ChangeProcessor; using browser_sync::ChangeProcessor;
Expand Down Expand Up @@ -707,28 +708,30 @@ void ProfileSyncService::OnSyncCycleCompleted() {
NotifyObservers(); NotifyObservers();
} }


// TODO(sync): eventually support removing datatypes too. void ProfileSyncService::OnExperimentsChanged(
void ProfileSyncService::OnDataTypesChanged( const browser_sync::Experiments& experiments) {
syncable::ModelTypeSet to_add) { if (current_experiments.Matches(experiments))
return;

// If this is a first time sync for a client, this will be called before // If this is a first time sync for a client, this will be called before
// OnBackendInitialized() to ensure the new datatypes are available at sync // OnBackendInitialized() to ensure the new datatypes are available at sync
// setup. As a result, the migrator won't exist yet. This is fine because for // setup. As a result, the migrator won't exist yet. This is fine because for
// first time sync cases we're only concerned with making the datatype // first time sync cases we're only concerned with making the datatype
// available. // available.
if (migrator_.get() && if (migrator_.get() &&
migrator_->state() != browser_sync::BackendMigrator::IDLE) { migrator_->state() != browser_sync::BackendMigrator::IDLE) {
DVLOG(1) << "Dropping OnDataTypesChanged due to migrator busy."; DVLOG(1) << "Dropping OnExperimentsChanged due to migrator busy.";
return; return;
} }


DVLOG(2) << "OnDataTypesChanged called with types: "
<< syncable::ModelTypeSetToString(to_add);

const syncable::ModelTypeSet registered_types = GetRegisteredDataTypes(); const syncable::ModelTypeSet registered_types = GetRegisteredDataTypes();

syncable::ModelTypeSet to_add;
if (experiments.sync_tabs)
to_add.Put(syncable::SESSIONS);
const syncable::ModelTypeSet to_register = const syncable::ModelTypeSet to_register =
Difference(to_add, registered_types); Difference(to_add, registered_types);

DVLOG(2) << "OnExperimentsChanged called with types: "
<< syncable::ModelTypeSetToString(to_add);
DVLOG(2) << "Enabling types: " << syncable::ModelTypeSetToString(to_register); DVLOG(2) << "Enabling types: " << syncable::ModelTypeSetToString(to_register);


for (syncable::ModelTypeSet::Iterator it = to_register.First(); for (syncable::ModelTypeSet::Iterator it = to_register.First();
Expand Down Expand Up @@ -768,6 +771,16 @@ void ProfileSyncService::OnDataTypesChanged(
OnMigrationNeededForTypes(to_register); OnMigrationNeededForTypes(to_register);
} }
} }

// Now enable any non-datatype features.
if (experiments.sync_tab_favicons) {
DVLOG(1) << "Enabling syncing of tab favicons.";
about_flags::SetExperimentEnabled(g_browser_process->local_state(),
"sync-tab-favicons",
true);
}

current_experiments = experiments;
} }


void ProfileSyncService::UpdateAuthErrorState( void ProfileSyncService::UpdateAuthErrorState(
Expand Down
8 changes: 6 additions & 2 deletions chrome/browser/sync/profile_sync_service.h
Expand Up @@ -35,6 +35,7 @@
#include "sync/engine/model_safe_worker.h" #include "sync/engine/model_safe_worker.h"
#include "sync/js/sync_js_controller.h" #include "sync/js/sync_js_controller.h"
#include "sync/syncable/model_type.h" #include "sync/syncable/model_type.h"
#include "sync/util/experiments.h"
#include "sync/util/unrecoverable_error_handler.h" #include "sync/util/unrecoverable_error_handler.h"


class Profile; class Profile;
Expand Down Expand Up @@ -235,8 +236,8 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
virtual void OnEncryptionComplete() OVERRIDE; virtual void OnEncryptionComplete() OVERRIDE;
virtual void OnMigrationNeededForTypes( virtual void OnMigrationNeededForTypes(
syncable::ModelTypeSet types) OVERRIDE; syncable::ModelTypeSet types) OVERRIDE;
virtual void OnDataTypesChanged( virtual void OnExperimentsChanged(
syncable::ModelTypeSet to_add) OVERRIDE; const browser_sync::Experiments& experiments) OVERRIDE;
virtual void OnActionableError( virtual void OnActionableError(
const browser_sync::SyncProtocolError& error) OVERRIDE; const browser_sync::SyncProtocolError& error) OVERRIDE;


Expand Down Expand Up @@ -741,6 +742,9 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
// data types. // data types.
bool setup_in_progress_; bool setup_in_progress_;


// The set of currently enabled sync experiments.
browser_sync::Experiments current_experiments;

DISALLOW_COPY_AND_ASSIGN(ProfileSyncService); DISALLOW_COPY_AND_ASSIGN(ProfileSyncService);
}; };


Expand Down
14 changes: 10 additions & 4 deletions sync/internal_api/sync_manager.cc
Expand Up @@ -52,6 +52,7 @@
#include "sync/syncable/model_type_payload_map.h" #include "sync/syncable/model_type_payload_map.h"
#include "sync/syncable/syncable.h" #include "sync/syncable/syncable.h"
#include "sync/util/cryptographer.h" #include "sync/util/cryptographer.h"
#include "sync/util/experiments.h"
#include "sync/util/get_session_name.h" #include "sync/util/get_session_name.h"
#include "sync/util/time.h" #include "sync/util/time.h"


Expand Down Expand Up @@ -2478,19 +2479,24 @@ syncable::ModelTypeSet SyncManager::GetEncryptedDataTypesForTest() const {
return GetEncryptedTypes(&trans); return GetEncryptedTypes(&trans);
} }


bool SyncManager::ReceivedExperimentalTypes(syncable::ModelTypeSet* to_add) bool SyncManager::ReceivedExperiment(browser_sync::Experiments* experiments)
const { const {
ReadTransaction trans(FROM_HERE, GetUserShare()); ReadTransaction trans(FROM_HERE, GetUserShare());
ReadNode node(&trans); ReadNode node(&trans);
if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) { if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) {
DVLOG(1) << "Couldn't find Nigori node."; DVLOG(1) << "Couldn't find Nigori node.";
return false; return false;
} }
bool found_experiment = false;
if (node.GetNigoriSpecifics().sync_tabs()) { if (node.GetNigoriSpecifics().sync_tabs()) {
to_add->Put(syncable::SESSIONS); experiments->sync_tabs = true;
return true; found_experiment = true;
}
if (node.GetNigoriSpecifics().sync_tab_favicons()) {
experiments->sync_tab_favicons = true;
found_experiment = true;
} }
return false; return found_experiment;
} }


bool SyncManager::HasUnsyncedItems() const { bool SyncManager::HasUnsyncedItems() const {
Expand Down
7 changes: 4 additions & 3 deletions sync/internal_api/sync_manager.h
Expand Up @@ -25,6 +25,7 @@


namespace browser_sync { namespace browser_sync {
class Encryptor; class Encryptor;
struct Experiments;
class ExtensionsActivityMonitor; class ExtensionsActivityMonitor;
class JsBackend; class JsBackend;
class JsEventHandler; class JsEventHandler;
Expand Down Expand Up @@ -591,10 +592,10 @@ class SyncManager {
// Note: opens a transaction. May be called from any thread. // Note: opens a transaction. May be called from any thread.
syncable::ModelTypeSet GetEncryptedDataTypesForTest() const; syncable::ModelTypeSet GetEncryptedDataTypesForTest() const;


// Reads the nigori node to determine if any experimental types should be // Reads the nigori node to determine if any experimental features should
// enabled. // be enabled.
// Note: opens a transaction. May be called on any thread. // Note: opens a transaction. May be called on any thread.
bool ReceivedExperimentalTypes(syncable::ModelTypeSet* to_add) const; bool ReceivedExperiment(browser_sync::Experiments* experiments) const;


// Uses a read-only transaction to determine if the directory being synced has // Uses a read-only transaction to determine if the directory being synced has
// any remaining unsynced items. May be called on any thread. // any remaining unsynced items. May be called on any thread.
Expand Down
3 changes: 3 additions & 0 deletions sync/protocol/nigori_specifics.proto
Expand Up @@ -90,5 +90,8 @@ message NigoriSpecifics {
// User device information. Contains information about each device that has a // User device information. Contains information about each device that has a
// sync-enabled Chrome browser connected to the user account. // sync-enabled Chrome browser connected to the user account.
repeated DeviceInformation device_information = 28; repeated DeviceInformation device_information = 28;

// Enable syncing favicons as part of tab sync.
optional bool sync_tab_favicons = 29;
} }


1 change: 1 addition & 0 deletions sync/protocol/proto_value_conversions.cc
Expand Up @@ -310,6 +310,7 @@ DictionaryValue* NigoriSpecificsToValue(
SET_BOOL(sync_tabs); SET_BOOL(sync_tabs);
SET_BOOL(encrypt_everything); SET_BOOL(encrypt_everything);
SET_REP(device_information, DeviceInformationToValue); SET_REP(device_information, DeviceInformationToValue);
SET_BOOL(sync_tab_favicons);
return value; return value;
} }


Expand Down
1 change: 1 addition & 0 deletions sync/sync.gyp
Expand Up @@ -157,6 +157,7 @@
'util/data_type_histogram.h', 'util/data_type_histogram.h',
'util/encryptor.h', 'util/encryptor.h',
'util/enum_set.h', 'util/enum_set.h',
'util/experiments.h',
'util/extensions_activity_monitor.cc', 'util/extensions_activity_monitor.cc',
'util/extensions_activity_monitor.h', 'util/extensions_activity_monitor.h',
'util/get_session_name.cc', 'util/get_session_name.cc',
Expand Down
32 changes: 32 additions & 0 deletions sync/util/experiments.h
@@ -0,0 +1,32 @@
// Copyright (c) 2012 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 SYNC_UTIL_EXPERIMENTS_
#define SYNC_UTIL_EXPERIMENTS_
#pragma once

#include "sync/syncable/model_type.h"

namespace browser_sync {

// A structure to hold the enable status of experimental sync features.
struct Experiments {
Experiments() : sync_tabs(false), sync_tab_favicons(false) {}

bool Matches(const Experiments& rhs) {
return (sync_tabs == rhs.sync_tabs) &&
(sync_tab_favicons == rhs.sync_tab_favicons);
}

// Enable the tab sync (SESSIONS) datatype.
bool sync_tabs;

// Enable syncing of favicons within tab sync (only has an effect if tab sync
// is already enabled). This takes effect on the next restart.
bool sync_tab_favicons;
};

}

#endif // SYNC_UTIL_EXPERIMENTS_

0 comments on commit 30cc5ed

Please sign in to comment.