| // Copyright 2015 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. |
| |
| #include "components/sync_driver/device_info_service.h" |
| |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "sync/api/model_type_change_processor.h" |
| #include "sync/api/sync_error.h" |
| #include "sync/protocol/sync.pb.h" |
| #include "sync/util/time.h" |
| |
| namespace sync_driver_v2 { |
| |
| using syncer::SyncError; |
| using syncer_v2::EntityChangeList; |
| using syncer_v2::EntityData; |
| using syncer_v2::EntityDataList; |
| using syncer_v2::MetadataChangeList; |
| using syncer_v2::SimpleMetadataChangeList; |
| using sync_driver::DeviceInfo; |
| using sync_pb::DeviceInfoSpecifics; |
| |
| DeviceInfoService::DeviceInfoService( |
| sync_driver::LocalDeviceInfoProvider* local_device_info_provider) |
| : local_device_backup_time_(-1), |
| local_device_info_provider_(local_device_info_provider) { |
| DCHECK(local_device_info_provider); |
| |
| // This is not threadsafe, but presuably the provider initializes on the same |
| // thread as us so we're okay. |
| if (local_device_info_provider->GetLocalDeviceInfo()) { |
| OnProviderInitialized(); |
| } else { |
| subscription_ = |
| local_device_info_provider->RegisterOnInitializedCallback(base::Bind( |
| &DeviceInfoService::OnProviderInitialized, base::Unretained(this))); |
| } |
| } |
| |
| DeviceInfoService::~DeviceInfoService() {} |
| |
| scoped_ptr<MetadataChangeList> DeviceInfoService::CreateMetadataChangeList() { |
| return make_scoped_ptr(new SimpleMetadataChangeList()); |
| } |
| |
| SyncError DeviceInfoService::MergeSyncData( |
| scoped_ptr<MetadataChangeList> metadata_change_list, |
| EntityDataList entity_data_list) { |
| // TODO(skym): Implementation. |
| return SyncError(); |
| } |
| |
| SyncError DeviceInfoService::ApplySyncChanges( |
| scoped_ptr<MetadataChangeList> metadata_change_list, |
| EntityChangeList entity_changes) { |
| // TODO(skym): Implementation. |
| return SyncError(); |
| } |
| |
| void DeviceInfoService::LoadMetadata(MetadataCallback callback) { |
| // TODO(skym): Implementation. |
| } |
| |
| void DeviceInfoService::GetData(ClientKeyList client_keys, |
| DataCallback callback) { |
| // TODO(skym): Implementation. |
| } |
| |
| void DeviceInfoService::GetAllData(DataCallback callback) { |
| // TODO(skym): Implementation. |
| } |
| |
| std::string DeviceInfoService::GetClientTag(const EntityData& entity_data) { |
| DCHECK(entity_data.specifics.has_device_info()); |
| return entity_data.specifics.device_info().cache_guid(); |
| } |
| |
| bool DeviceInfoService::IsSyncing() const { |
| return !all_data_.empty(); |
| } |
| |
| scoped_ptr<DeviceInfo> DeviceInfoService::GetDeviceInfo( |
| const std::string& client_id) const { |
| ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id); |
| if (iter == all_data_.end()) { |
| return scoped_ptr<DeviceInfo>(); |
| } |
| |
| return CreateDeviceInfo(*iter->second); |
| } |
| |
| ScopedVector<DeviceInfo> DeviceInfoService::GetAllDeviceInfo() const { |
| ScopedVector<DeviceInfo> list; |
| |
| for (ClientIdToSpecifics::const_iterator iter = all_data_.begin(); |
| iter != all_data_.end(); ++iter) { |
| list.push_back(CreateDeviceInfo(*iter->second)); |
| } |
| |
| return list.Pass(); |
| } |
| |
| void DeviceInfoService::AddObserver(Observer* observer) { |
| observers_.AddObserver(observer); |
| } |
| |
| void DeviceInfoService::RemoveObserver(Observer* observer) { |
| observers_.RemoveObserver(observer); |
| } |
| |
| void DeviceInfoService::NotifyObservers() { |
| FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange()); |
| } |
| |
| void DeviceInfoService::UpdateLocalDeviceBackupTime(base::Time backup_time) { |
| // TODO(skym): Replace with is initialized check, we've already started |
| // syncing, provider is ready, make sure we have processort, etc. |
| |
| // Local device info must be available in advance. |
| DCHECK(local_device_info_provider_->GetLocalDeviceInfo()); |
| |
| // TODO(skym): Should this be a less than instead of not equal check? |
| if (GetLocalDeviceBackupTime() != backup_time) { |
| // TODO(skym): Storing this field doesn't really make sense, remove. |
| set_local_device_backup_time(syncer::TimeToProtoTime(backup_time)); |
| scoped_ptr<DeviceInfoSpecifics> new_specifics = CreateLocalSpecifics(); |
| |
| // TODO(skym): Create correct update datastructure, such as EntityChange, |
| // EntityMetadata, or CommitRequestData. |
| // TODO(skym): Call ProcessChanges on SMTP. |
| // TODO(skym): Persist metadata and data. |
| StoreSpecifics(new_specifics.Pass()); |
| } |
| |
| // Don't call NotifyObservers() because backup time is not part of |
| // DeviceInfoTracker interface. |
| } |
| |
| base::Time DeviceInfoService::GetLocalDeviceBackupTime() const { |
| return has_local_device_backup_time() |
| ? syncer::ProtoTimeToTime(local_device_backup_time()) |
| : base::Time(); |
| } |
| |
| // TODO(skym): It might not make sense for this to be a scoped_ptr. |
| scoped_ptr<DeviceInfoSpecifics> DeviceInfoService::CreateLocalSpecifics() { |
| const DeviceInfo* info = local_device_info_provider_->GetLocalDeviceInfo(); |
| DCHECK(info); |
| scoped_ptr<DeviceInfoSpecifics> specifics = CreateSpecifics(*info); |
| if (has_local_device_backup_time()) { |
| specifics->set_backup_timestamp(local_device_backup_time()); |
| } |
| // TODO(skym): Local tag and non unique name have no place to be set now. |
| return specifics; |
| } |
| |
| // TODO(skym): It might not make sense for this to be a scoped_ptr. |
| // Static. |
| scoped_ptr<DeviceInfoSpecifics> DeviceInfoService::CreateSpecifics( |
| const DeviceInfo& info) { |
| scoped_ptr<DeviceInfoSpecifics> specifics = |
| make_scoped_ptr(new DeviceInfoSpecifics); |
| specifics->set_cache_guid(info.guid()); |
| specifics->set_client_name(info.client_name()); |
| specifics->set_chrome_version(info.chrome_version()); |
| specifics->set_sync_user_agent(info.sync_user_agent()); |
| specifics->set_device_type(info.device_type()); |
| specifics->set_signin_scoped_device_id(info.signin_scoped_device_id()); |
| return specifics; |
| } |
| |
| // Static. |
| scoped_ptr<DeviceInfo> DeviceInfoService::CreateDeviceInfo( |
| const DeviceInfoSpecifics& specifics) { |
| return make_scoped_ptr(new DeviceInfo( |
| specifics.cache_guid(), specifics.client_name(), |
| specifics.chrome_version(), specifics.sync_user_agent(), |
| specifics.device_type(), specifics.signin_scoped_device_id())); |
| } |
| |
| void DeviceInfoService::StoreSpecifics( |
| scoped_ptr<DeviceInfoSpecifics> specifics) { |
| DVLOG(1) << "Storing DEVICE_INFO for " << specifics->client_name() |
| << " with ID " << specifics->cache_guid(); |
| all_data_[specifics->cache_guid()] = std::move(specifics); |
| } |
| |
| void DeviceInfoService::DeleteSpecifics(const std::string& client_id) { |
| ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id); |
| if (iter != all_data_.end()) { |
| DVLOG(1) << "Deleting DEVICE_INFO for " << iter->second->client_name() |
| << " with ID " << client_id; |
| all_data_.erase(iter); |
| } |
| } |
| |
| void DeviceInfoService::OnProviderInitialized() { |
| // TODO(skym): Do we need this? |
| } |
| |
| } // namespace sync_driver_v2 |