Commit 47205f1e authored by Rushan Suleymanov's avatar Rushan Suleymanov Committed by Chromium LUCI CQ

[Sync] Implement new invalidations on iOS

This CL implements DeviceInfoClient interface for iOS platform when
invalidations are enabled.

Bug: 1102314
Change-Id: I19f6afaa256d127e2d8869123b632088f648c32a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2605557
Commit-Queue: Rushan Suleymanov <rushans@google.com>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarMikel Astiz <mastiz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843433}
parent 3a30e747
......@@ -13,6 +13,7 @@
#include "components/keyed_service/ios/browser_state_dependency_manager.h"
#include "components/send_tab_to_self/features.h"
#include "components/signin/public/base/device_id_helper.h"
#include "components/sync/invalidations/sync_invalidations_service.h"
#include "components/sync/model/model_type_store_service.h"
#include "components/sync_device_info/device_info_prefs.h"
#include "components/sync_device_info/device_info_sync_client.h"
......@@ -22,6 +23,7 @@
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h"
#include "ios/chrome/browser/sync/model_type_store_service_factory.h"
#include "ios/chrome/browser/sync/sync_invalidations_service_factory.h"
#include "ios/chrome/common/channel_info.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
......@@ -32,7 +34,11 @@ namespace {
class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient {
public:
explicit DeviceInfoSyncClient(PrefService* prefs) : prefs_(prefs) {}
DeviceInfoSyncClient(
PrefService* prefs,
syncer::SyncInvalidationsService* sync_invalidations_service)
: prefs_(prefs),
sync_invalidations_service_(sync_invalidations_service) {}
~DeviceInfoSyncClient() override = default;
// syncer::DeviceInfoSyncClient:
......@@ -53,16 +59,29 @@ class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient {
// syncer::DeviceInfoSyncClient:
base::Optional<std::string> GetFCMRegistrationToken() const override {
if (sync_invalidations_service_) {
return sync_invalidations_service_->GetFCMRegistrationToken();
}
// If the service is not enabled, then the registration token must be empty,
// not unknown (base::nullopt). This is needed to reset previous token if
// the invalidations have been turned off.
return std::string();
}
// syncer::DeviceInfoSyncClient:
base::Optional<syncer::ModelTypeSet> GetInterestedDataTypes() const override {
if (sync_invalidations_service_) {
return sync_invalidations_service_->GetInterestedDataTypes();
}
// If the service is not enabled, then the list of types must be empty, not
// unknown (base::nullopt). This is needed to reset previous types if the
// invalidations have been turned off.
return syncer::ModelTypeSet();
}
private:
PrefService* const prefs_;
syncer::SyncInvalidationsService* const sync_invalidations_service_;
};
} // namespace
......@@ -105,6 +124,7 @@ DeviceInfoSyncServiceFactory::DeviceInfoSyncServiceFactory()
"DeviceInfoSyncService",
BrowserStateDependencyManager::GetInstance()) {
DependsOn(ModelTypeStoreServiceFactory::GetInstance());
DependsOn(SyncInvalidationsServiceFactory::GetInstance());
}
DeviceInfoSyncServiceFactory::~DeviceInfoSyncServiceFactory() {}
......@@ -115,8 +135,10 @@ DeviceInfoSyncServiceFactory::BuildServiceInstanceFor(
ChromeBrowserState* browser_state =
ChromeBrowserState::FromBrowserState(context);
auto device_info_sync_client =
std::make_unique<DeviceInfoSyncClient>(browser_state->GetPrefs());
syncer::SyncInvalidationsService* const sync_invalidations_service =
SyncInvalidationsServiceFactory::GetForBrowserState(browser_state);
auto device_info_sync_client = std::make_unique<DeviceInfoSyncClient>(
browser_state->GetPrefs(), sync_invalidations_service);
auto local_device_info_provider =
std::make_unique<syncer::LocalDeviceInfoProviderImpl>(
::GetChannel(), ::GetVersionString(), device_info_sync_client.get());
......@@ -127,6 +149,5 @@ DeviceInfoSyncServiceFactory::BuildServiceInstanceFor(
ModelTypeStoreServiceFactory::GetForBrowserState(browser_state)
->GetStoreFactory(),
std::move(local_device_info_provider), std::move(device_prefs),
std::move(device_info_sync_client),
/*sync_invalidations_service=*/nullptr);
std::move(device_info_sync_client), sync_invalidations_service);
}
......@@ -46,6 +46,7 @@ source_set("eg2_tests") {
deps = [
"//base",
"//base/test:test_support",
"//components/sync/invalidations",
"//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
"//ios/chrome/browser/ui/bookmarks:eg_test_support+eg2",
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
......
......@@ -4,6 +4,7 @@
#include "base/strings/sys_string_conversions.h"
#import "base/test/ios/wait_util.h"
#include "components/sync/invalidations/switches.h"
#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h"
......@@ -11,6 +12,7 @@
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h"
#import "ios/public/provider/chrome/browser/signin/fake_chrome_identity.h"
#import "ios/testing/earl_grey/app_launch_manager.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "ios/web/public/test/http_server/http_server.h"
#include "ios/web/public/test/http_server/http_server_util.h"
......@@ -63,6 +65,15 @@ void AssertNumberOfEntities(int entity_count, syncer::ModelType entity_type) {
@"No bookmarks should exist before sync tests start.");
}
- (AppLaunchConfiguration)appConfigurationForTestCase {
AppLaunchConfiguration config;
if ([self isRunningTest:@selector(testSyncInvalidationsEnabled)]) {
config.features_enabled.push_back(switches::kSyncSendInterestedDataTypes);
config.features_enabled.push_back(switches::kUseSyncInvalidations);
}
return config;
}
// Tests that a bookmark added on the client (before Sync is enabled) is
// uploaded to the Sync server once Sync is turned on.
- (void)testSyncUploadBookmarkOnFirstSync {
......@@ -470,4 +481,15 @@ void AssertNumberOfEntities(int entity_count, syncer::ModelType entity_type) {
[BookmarkEarlGrey verifyBookmarksWithTitle:title2 expectedCount:1];
}
- (void)testSyncInvalidationsEnabled {
// Sign in to sync.
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity];
[ChromeEarlGrey waitForSyncInitialized:YES syncTimeout:kSyncOperationTimeout];
AssertNumberOfEntities(1, syncer::DEVICE_INFO);
[ChromeEarlGrey waitForSyncInvalidationFields];
}
@end
......@@ -83,6 +83,10 @@ bool IsSyncInitialized();
// calling this.
std::string GetSyncCacheGuid();
// Returns true if the DeviceInfo specifics on the fake server contains sync
// invalidation fields.
bool VerifySyncInvalidationFieldsPopulated();
// Returns true if there is an autofilll profile with the corresponding |guid|
// and |full_name|.
bool IsAutofillProfilePresent(std::string guid, std::string full_name);
......
......@@ -205,6 +205,23 @@ std::string GetSyncCacheGuid() {
return info_provider->GetLocalDeviceInfo()->guid();
}
bool VerifySyncInvalidationFieldsPopulated() {
DCHECK(IsFakeSyncServerSetUp());
const std::string cache_guid = GetSyncCacheGuid();
std::vector<sync_pb::SyncEntity> entities =
gSyncFakeServer->GetSyncEntitiesByModelType(syncer::DEVICE_INFO);
for (const sync_pb::SyncEntity& entity : entities) {
if (entity.specifics().device_info().cache_guid() == cache_guid) {
const sync_pb::InvalidationSpecificFields& invalidation_fields =
entity.specifics().device_info().invalidation_fields();
return !invalidation_fields.interested_data_type_ids().empty() &&
invalidation_fields.has_instance_id_token();
}
}
// The local DeviceInfo hasn't been committed yet.
return false;
}
void AddUserDemographicsToSyncServer(
int birth_year,
metrics::UserDemographicsProto::Gender gender) {
......
......@@ -241,6 +241,10 @@ id ExecuteJavaScript(NSString* javascript, NSError** out_error);
expectPresent:(BOOL)expectPresent
timeout:(NSTimeInterval)timeout;
// Waits for sync invalidation field presence in the DeviceInfo data type on the
// server.
- (void)waitForSyncInvalidationFields;
#pragma mark - Tab Utilities (EG2)
// Opens a new tab and waits for the new tab animation to complete within a
......
......@@ -720,6 +720,11 @@ GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(ChromeEarlGreyAppInterface)
EG_TEST_HELPER_ASSERT_TRUE(success, kTypedURLError);
}
- (void)waitForSyncInvalidationFields {
EG_TEST_HELPER_ASSERT_NO_ERROR(
[ChromeEarlGreyAppInterface waitForSyncInvalidationFields]);
}
- (void)triggerSyncCycleForType:(syncer::ModelType)type {
[ChromeEarlGreyAppInterface triggerSyncCycleForType:type];
}
......
......@@ -304,6 +304,10 @@
// calling this.
+ (NSString*)syncCacheGUID;
// Waits for sync invalidation field presence in the DeviceInfo data type on the
// server.
+ (NSError*)waitForSyncInvalidationFields;
// Whether or not the fake sync server has been setup.
+ (BOOL)isFakeSyncServerSetUp;
......
......@@ -672,6 +672,17 @@ base::test::ScopedFeatureList closeAllTabsScopedFeatureList;
return base::SysUTF8ToNSString(chrome_test_util::GetSyncCacheGuid());
}
+ (NSError*)waitForSyncInvalidationFields {
const bool success = WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{
return chrome_test_util::VerifySyncInvalidationFieldsPopulated();
});
if (!success) {
return testing::NSErrorWithLocalizedDescription(
@"The local DeviceInfo doesn't have invalidation fields");
}
return nil;
}
+ (BOOL)isFakeSyncServerSetUp {
return chrome_test_util::IsFakeSyncServerSetUp();
}
......
......@@ -11,6 +11,7 @@
#include "base/time/default_clock.h"
#include "components/keyed_service/ios/browser_state_dependency_manager.h"
#include "components/signin/public/base/device_id_helper.h"
#include "components/sync/invalidations/sync_invalidations_service.h"
#include "components/sync/model/model_type_store_service.h"
#include "components/sync_device_info/device_info_prefs.h"
#include "components/sync_device_info/device_info_sync_client.h"
......@@ -18,6 +19,7 @@
#include "components/sync_device_info/local_device_info_provider_impl.h"
#include "components/version_info/version_info.h"
#import "ios/web_view/internal/sync/web_view_model_type_store_service_factory.h"
#include "ios/web_view/internal/sync/web_view_sync_invalidations_service_factory.h"
#include "ios/web_view/internal/web_view_browser_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
......@@ -28,7 +30,11 @@ namespace {
class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient {
public:
explicit DeviceInfoSyncClient(PrefService* prefs) : prefs_(prefs) {}
DeviceInfoSyncClient(
PrefService* prefs,
syncer::SyncInvalidationsService* sync_invalidations_service)
: prefs_(prefs),
sync_invalidations_service_(sync_invalidations_service) {}
~DeviceInfoSyncClient() override = default;
// syncer::DeviceInfoSyncClient:
......@@ -47,16 +53,29 @@ class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient {
// syncer::DeviceInfoSyncClient:
base::Optional<std::string> GetFCMRegistrationToken() const override {
if (sync_invalidations_service_) {
return sync_invalidations_service_->GetFCMRegistrationToken();
}
// If the service is not enabled, then the registration token must be empty,
// not unknown (base::nullopt). This is needed to reset previous token if
// the invalidations have been turned off.
return std::string();
}
// syncer::DeviceInfoSyncClient:
base::Optional<syncer::ModelTypeSet> GetInterestedDataTypes() const override {
if (sync_invalidations_service_) {
return sync_invalidations_service_->GetInterestedDataTypes();
}
// If the service is not enabled, then the list of types must be empty, not
// unknown (base::nullopt). This is needed to reset previous types if the
// invalidations have been turned off.
return syncer::ModelTypeSet();
}
private:
PrefService* const prefs_;
syncer::SyncInvalidationsService* const sync_invalidations_service_;
};
} // namespace
......@@ -82,6 +101,7 @@ WebViewDeviceInfoSyncServiceFactory::WebViewDeviceInfoSyncServiceFactory()
"DeviceInfoSyncService",
BrowserStateDependencyManager::GetInstance()) {
DependsOn(WebViewModelTypeStoreServiceFactory::GetInstance());
DependsOn(WebViewSyncInvalidationsServiceFactory::GetInstance());
}
WebViewDeviceInfoSyncServiceFactory::~WebViewDeviceInfoSyncServiceFactory() {}
......@@ -92,8 +112,10 @@ WebViewDeviceInfoSyncServiceFactory::BuildServiceInstanceFor(
WebViewBrowserState* browser_state =
WebViewBrowserState::FromBrowserState(context);
auto device_info_sync_client =
std::make_unique<DeviceInfoSyncClient>(browser_state->GetPrefs());
syncer::SyncInvalidationsService* const sync_invalidations_service =
WebViewSyncInvalidationsServiceFactory::GetForBrowserState(browser_state);
auto device_info_sync_client = std::make_unique<DeviceInfoSyncClient>(
browser_state->GetPrefs(), sync_invalidations_service);
auto local_device_info_provider =
std::make_unique<syncer::LocalDeviceInfoProviderImpl>(
version_info::Channel::STABLE, version_info::GetVersionNumber(),
......@@ -105,8 +127,7 @@ WebViewDeviceInfoSyncServiceFactory::BuildServiceInstanceFor(
WebViewModelTypeStoreServiceFactory::GetForBrowserState(browser_state)
->GetStoreFactory(),
std::move(local_device_info_provider), std::move(device_prefs),
std::move(device_info_sync_client),
/*sync_invalidations_service=*/nullptr);
std::move(device_info_sync_client), sync_invalidations_service);
}
} // namespace ios_web_view
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