Index: components/wifi_sync/wifi_credential_syncable_service.cc |
diff --git a/components/wifi_sync/wifi_credential_syncable_service.cc b/components/wifi_sync/wifi_credential_syncable_service.cc |
index 76e57fa8d1eb0f287b06cc934e0cd97d14ae51f9..69b502bf38613fc289fd1a028b398526fb694553 100644 |
--- a/components/wifi_sync/wifi_credential_syncable_service.cc |
+++ b/components/wifi_sync/wifi_credential_syncable_service.cc |
@@ -4,18 +4,117 @@ |
#include "components/wifi_sync/wifi_credential_syncable_service.h" |
+#include <stdint.h> |
+#include <vector> |
+ |
#include "base/logging.h" |
+#include "components/wifi_sync/wifi_credential.h" |
+#include "components/wifi_sync/wifi_security_class.h" |
#include "sync/api/sync_change.h" |
+#include "sync/api/sync_data.h" |
#include "sync/api/sync_error.h" |
#include "sync/api/sync_error_factory.h" |
#include "sync/api/sync_merge_result.h" |
+#include "sync/protocol/sync.pb.h" |
namespace wifi_sync { |
+namespace { |
+ |
+void BuildSpecifics( |
+ const std::vector<uint8_t>& ssid, |
+ WifiSecurityClass security_class, |
+ const std::string& passphrase, |
+ sync_pb::EntitySpecifics* out_buffer) { |
stevenjb
2015/01/20 22:20:27
Is this clang formatted? It looks like these will
mukesh agrawal
2015/01/22 00:36:00
I'll reformat in PS6. (That should make the diff f
|
+ DCHECK(out_buffer); |
+ sync_pb::WifiCredentialSpecifics* credential_specifics = |
+ out_buffer->mutable_wifi_credential(); |
+ DCHECK(credential_specifics); |
+ credential_specifics->set_ssid(ssid.data(), ssid.size()); |
+ credential_specifics->set_security_class( |
+ WifiSecurityClassToSyncSecurityClass(security_class)); |
+ if (WifiSecurityClassSupportsPassphrases(security_class)) { |
+ credential_specifics->set_passphrase(passphrase.data(), passphrase.size()); |
+ } |
+} |
+ |
+bool ParseSpecifics( |
+ const sync_pb::EntitySpecifics& specifics, |
+ std::vector<uint8_t>* ssid, |
+ WifiSecurityClass* security_class, |
+ std::string* passphrase) { |
+ DCHECK(ssid); |
+ DCHECK(security_class); |
+ DCHECK(passphrase); |
+ |
+ if (!specifics.has_wifi_credential()) { |
+ LOG(ERROR) << "Specifics with missing wifi_credential; skipping"; |
+ return false; |
+ } |
+ |
+ const sync_pb::WifiCredentialSpecifics& credential_specifics = |
+ specifics.wifi_credential(); |
+ if (!credential_specifics.has_ssid()) { |
+ LOG(ERROR) << "Specifics with missing SSID; skipping"; |
+ return false; |
+ } |
+ if (!credential_specifics.has_security_class()) { |
+ LOG(ERROR) << "Specifics with missing security class; skipping"; |
+ return false; |
+ } |
+ |
+ *ssid = std::vector<uint8_t>( |
+ credential_specifics.ssid().begin(), |
+ credential_specifics.ssid().end()); |
+ *security_class = WifiSecurityClassFromSyncSecurityClass( |
+ credential_specifics.security_class()); |
+ |
+ if (WifiSecurityClassSupportsPassphrases(*security_class)) { |
+ if (!credential_specifics.has_passphrase()) { |
+ LOG(ERROR) << "Specifics for security class " |
+ << *security_class << " is missing passphrase; skipping"; |
+ return false; |
+ } |
+ *passphrase = credential_specifics.passphrase(); |
+ } |
+ |
+ return true; |
+} |
+ |
+bool ParseSyncData( |
+ const syncer::SyncData& sync_data, |
+ std::vector<uint8_t>* ssid_bytes, |
+ WifiSecurityClass* security_class, |
+ std::string* passphrase) { |
+ if (!sync_data.IsValid()) { |
+ LOG(WARNING) << "Invalid SyncData; skipping item"; |
+ return false; |
+ } |
+ |
+ if (sync_data.GetDataType() != syncer::WIFI_CREDENTIALS) { |
+ LOG(WARNING) << "Unexpected SyncData of type " |
+ << syncer::ModelTypeToString(sync_data.GetDataType()) |
+ << "; skipping item"; |
+ return false; |
+ } |
+ |
+ if (!ParseSpecifics( |
+ sync_data.GetSpecifics(), ssid_bytes, security_class, passphrase)) { |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+} // namespace |
+ |
const syncer::ModelType WifiCredentialSyncableService::kModelType = |
syncer::WIFI_CREDENTIALS; |
-WifiCredentialSyncableService::WifiCredentialSyncableService() { |
+WifiCredentialSyncableService::WifiCredentialSyncableService( |
+ scoped_ptr<WifiConfigDelegate> network_config_delegate) |
+ : network_config_delegate_(network_config_delegate.release()) { |
+ DCHECK(network_config_delegate_); |
} |
WifiCredentialSyncableService::~WifiCredentialSyncableService() { |
@@ -33,7 +132,7 @@ syncer::SyncMergeResult WifiCredentialSyncableService::MergeDataAndStartSyncing( |
sync_processor_ = sync_processor.Pass(); |
- // TODO(quiche): Update local WiFi configuration. |
+ // TODO(quiche): Update local WiFi configuration from |initial_sync_data|. |
// TODO(quiche): Notify upper layers that sync is ready. |
NOTIMPLEMENTED(); |
@@ -55,8 +154,92 @@ syncer::SyncDataList WifiCredentialSyncableService::GetAllSyncData( |
syncer::SyncError WifiCredentialSyncableService::ProcessSyncChanges( |
const tracked_objects::Location& /* caller_location */, |
const syncer::SyncChangeList& change_list) { |
- NOTIMPLEMENTED(); |
+ if (!sync_processor_.get()) { |
+ return syncer::SyncError( |
+ FROM_HERE, |
+ syncer::SyncError::UNREADY_ERROR, |
+ "ProcessSyncChanges called before MergeDataAndStartSyncing", |
+ kModelType); |
+ } |
+ |
+ for (const auto& sync_change : change_list) { |
+ if (!sync_change.IsValid()) { |
+ return syncer::SyncError( |
+ FROM_HERE, |
+ syncer::SyncError::DATATYPE_ERROR, |
+ "ProcessSyncChanges was passed an invalid SyncChange", |
+ kModelType); |
+ } |
+ |
+ std::vector<uint8_t> ssid_bytes; |
+ WifiSecurityClass security_class; |
+ std::string passphrase; |
stevenjb
2015/01/20 22:20:27
nit: maybe use a struct for these to simplify the
mukesh agrawal
2015/01/22 00:35:59
Done.
|
+ if (!ParseSyncData(sync_change.sync_data(), |
+ &ssid_bytes, &security_class, &passphrase)) { |
+ LOG(WARNING) << "Failed to parse item; skipping " |
+ << syncer::SyncChange::ChangeTypeToString( |
+ sync_change.change_type()); |
+ continue; |
+ } |
+ |
+ scoped_ptr<WifiCredential> credential; |
+ switch (sync_change.change_type()) { |
+ case syncer::SyncChange::ACTION_ADD: |
+ credential = |
+ WifiCredential::Create(ssid_bytes, security_class, passphrase); |
+ if (!credential) |
+ LOG(WARNING) << "Failed to create credential; skipping"; |
+ else |
+ network_config_delegate_->AddToLocalNetworks(*credential); |
+ break; |
+ case syncer::SyncChange::ACTION_UPDATE: |
+ // TODO(quiche): Implement update, and add appropriate tests. |
+ NOTIMPLEMENTED(); |
+ break; |
+ case syncer::SyncChange::ACTION_DELETE: |
+ // TODO(quiche): Implement delete, and add appropriate tests. |
+ NOTIMPLEMENTED(); |
+ break; |
+ default: |
+ return syncer::SyncError( |
+ FROM_HERE, |
+ syncer::SyncError::DATATYPE_ERROR, |
+ "ProcessSyncChanges given invalid SyncChangeType", |
+ kModelType); |
+ } |
+ } |
+ |
return syncer::SyncError(); |
} |
+bool WifiCredentialSyncableService::AddToSyncedNetworks( |
+ const std::string& item_id, const WifiCredential& credential) { |
+ if (!sync_processor_.get()) { |
+ LOG(WARNING) << "WifiCredentials syncable service is not started."; |
+ return false; |
+ } |
+ |
+ // TODO(quiche): Handle case where network already exists. |
+ syncer::SyncChangeList change_list; |
+ syncer::SyncError sync_error; |
+ sync_pb::EntitySpecifics wifi_credential_specifics; |
+ BuildSpecifics(credential.ssid(), credential.security_class(), |
+ credential.passphrase(), &wifi_credential_specifics); |
+ change_list.push_back( |
+ syncer::SyncChange( |
+ FROM_HERE, |
+ syncer::SyncChange::ACTION_ADD, |
+ syncer::SyncData::CreateLocalData( |
+ item_id, |
+ item_id, |
+ wifi_credential_specifics))); |
+ sync_error = sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); |
+ if (sync_error.IsSet()) { |
+ LOG(ERROR) << sync_error.ToString(); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
} // namespace wifi_sync |