| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/extensions/api/synced_notifications_private/synced_noti
fications_shim.h" | |
| 6 | |
| 7 #include "extensions/browser/event_router.h" | |
| 8 #include "sync/api/sync_change.h" | |
| 9 #include "sync/api/sync_data.h" | |
| 10 #include "sync/api/sync_error_factory.h" | |
| 11 #include "sync/protocol/sync.pb.h" | |
| 12 | |
| 13 using namespace extensions; | |
| 14 using namespace extensions::api; | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 synced_notifications_private::ChangeType SyncerChangeTypeToJS( | |
| 19 syncer::SyncChange::SyncChangeType change_type) { | |
| 20 switch (change_type) { | |
| 21 case syncer::SyncChange::ACTION_UPDATE: | |
| 22 return synced_notifications_private::CHANGE_TYPE_UPDATED; | |
| 23 case syncer::SyncChange::ACTION_DELETE: | |
| 24 return synced_notifications_private::CHANGE_TYPE_DELETED; | |
| 25 case syncer::SyncChange::ACTION_ADD: | |
| 26 return synced_notifications_private::CHANGE_TYPE_ADDED; | |
| 27 case syncer::SyncChange::ACTION_INVALID: | |
| 28 return synced_notifications_private::CHANGE_TYPE_NONE; | |
| 29 } | |
| 30 NOTREACHED(); | |
| 31 return synced_notifications_private::CHANGE_TYPE_NONE; | |
| 32 } | |
| 33 | |
| 34 syncer::ModelType JSDataTypeToSyncer( | |
| 35 synced_notifications_private::SyncDataType data_type) { | |
| 36 switch (data_type) { | |
| 37 case synced_notifications_private::SYNC_DATA_TYPE_APP_INFO: | |
| 38 return syncer::SYNCED_NOTIFICATION_APP_INFO; | |
| 39 case synced_notifications_private::SYNC_DATA_TYPE_SYNCED_NOTIFICATION: | |
| 40 return syncer::SYNCED_NOTIFICATIONS; | |
| 41 default: | |
| 42 NOTREACHED(); | |
| 43 return syncer::UNSPECIFIED; | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 synced_notifications_private::SyncDataType SyncerModelTypeToJS( | |
| 48 syncer::ModelType model_type) { | |
| 49 switch (model_type) { | |
| 50 case syncer::SYNCED_NOTIFICATION_APP_INFO: | |
| 51 return synced_notifications_private::SYNC_DATA_TYPE_APP_INFO; | |
| 52 case syncer::SYNCED_NOTIFICATIONS: | |
| 53 return synced_notifications_private::SYNC_DATA_TYPE_SYNCED_NOTIFICATION; | |
| 54 default: | |
| 55 NOTREACHED(); | |
| 56 return synced_notifications_private::SYNC_DATA_TYPE_NONE; | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 bool BuildNewSyncUpdate( | |
| 61 const tracked_objects::Location& from_here, | |
| 62 const std::string& changed_notification, | |
| 63 syncer::SyncChange* sync_change) { | |
| 64 sync_pb::EntitySpecifics specifics; | |
| 65 sync_pb::SyncedNotificationSpecifics* notification_specifics = | |
| 66 specifics.mutable_synced_notification(); | |
| 67 if (!notification_specifics->ParseFromArray( | |
| 68 changed_notification.c_str(), changed_notification.size())) { | |
| 69 return false; | |
| 70 } | |
| 71 | |
| 72 // TODO(synced notifications): pass the tag via the JS API. | |
| 73 const std::string& tag = | |
| 74 notification_specifics->coalesced_notification().key(); | |
| 75 syncer::SyncData sync_data = | |
| 76 syncer::SyncData::CreateLocalData(tag, tag, specifics); | |
| 77 *sync_change = syncer::SyncChange( | |
| 78 from_here, syncer::SyncChange::ACTION_UPDATE, sync_data); | |
| 79 return true; | |
| 80 } | |
| 81 | |
| 82 linked_ptr<synced_notifications_private::SyncChange> BuildNewJSSyncChange( | |
| 83 const syncer::SyncChange& change) { | |
| 84 linked_ptr<synced_notifications_private::SyncChange> js_change = | |
| 85 make_linked_ptr<synced_notifications_private::SyncChange>( | |
| 86 new synced_notifications_private::SyncChange()); | |
| 87 js_change->change_type = SyncerChangeTypeToJS(change.change_type()); | |
| 88 js_change->data.datatype = | |
| 89 SyncerModelTypeToJS(change.sync_data().GetDataType()); | |
| 90 if (change.sync_data().GetDataType() == syncer::SYNCED_NOTIFICATIONS) { | |
| 91 const sync_pb::SyncedNotificationSpecifics& specifics = | |
| 92 change.sync_data().GetSpecifics().synced_notification(); | |
| 93 js_change->data.data_item = specifics.SerializeAsString(); | |
| 94 } else { | |
| 95 DCHECK_EQ(change.sync_data().GetDataType(), | |
| 96 syncer::SYNCED_NOTIFICATION_APP_INFO); | |
| 97 const sync_pb::SyncedNotificationAppInfoSpecifics& specifics = | |
| 98 change.sync_data().GetSpecifics().synced_notification_app_info(); | |
| 99 js_change->data.data_item = specifics.SerializeAsString(); | |
| 100 } | |
| 101 return js_change; | |
| 102 } | |
| 103 | |
| 104 bool PopulateJSDataListFromSync( | |
| 105 const syncer::SyncDataList& sync_data_list, | |
| 106 std::vector<linked_ptr<synced_notifications_private::SyncData> >* | |
| 107 js_data_list) { | |
| 108 for (size_t i = 0; i < sync_data_list.size(); ++i) { | |
| 109 linked_ptr<synced_notifications_private::SyncData> js_data( | |
| 110 new synced_notifications_private::SyncData()); | |
| 111 syncer::ModelType data_type = sync_data_list[i].GetDataType(); | |
| 112 js_data->datatype = SyncerModelTypeToJS(data_type); | |
| 113 if (data_type == syncer::SYNCED_NOTIFICATIONS) { | |
| 114 const sync_pb::SyncedNotificationSpecifics& specifics = | |
| 115 sync_data_list[i].GetSpecifics().synced_notification(); | |
| 116 js_data->data_item = specifics.SerializeAsString(); | |
| 117 } else if (data_type == syncer::SYNCED_NOTIFICATION_APP_INFO) { | |
| 118 const sync_pb::SyncedNotificationAppInfoSpecifics& specifics = | |
| 119 sync_data_list[i].GetSpecifics().synced_notification_app_info(); | |
| 120 js_data->data_item = specifics.SerializeAsString(); | |
| 121 } else { | |
| 122 return false; | |
| 123 } | |
| 124 js_data_list->push_back(js_data); | |
| 125 } | |
| 126 return true; | |
| 127 } | |
| 128 | |
| 129 } // namespace | |
| 130 | |
| 131 SyncedNotificationsShim::SyncedNotificationsShim( | |
| 132 const EventLauncher& event_launcher, | |
| 133 const base::Closure& refresh_request) | |
| 134 : event_launcher_(event_launcher), | |
| 135 refresh_request_(refresh_request) { | |
| 136 } | |
| 137 | |
| 138 SyncedNotificationsShim::~SyncedNotificationsShim() { | |
| 139 } | |
| 140 | |
| 141 syncer::SyncMergeResult SyncedNotificationsShim::MergeDataAndStartSyncing( | |
| 142 syncer::ModelType type, | |
| 143 const syncer::SyncDataList& initial_sync_data, | |
| 144 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | |
| 145 scoped_ptr<syncer::SyncErrorFactory> error_handler) { | |
| 146 if (type == syncer::SYNCED_NOTIFICATIONS) | |
| 147 notifications_change_processor_ = sync_processor.Pass(); | |
| 148 else if (type == syncer::SYNCED_NOTIFICATION_APP_INFO) | |
| 149 app_info_change_processor_ = sync_processor.Pass(); | |
| 150 else | |
| 151 NOTREACHED(); | |
| 152 | |
| 153 // Only wake up the extension if both sync data types are ready. | |
| 154 if (notifications_change_processor_ && app_info_change_processor_) { | |
| 155 scoped_ptr<Event> event(new Event( | |
| 156 synced_notifications_private::OnSyncStartup::kEventName, | |
| 157 synced_notifications_private::OnSyncStartup::Create())); | |
| 158 event_launcher_.Run(event.Pass()); | |
| 159 } | |
| 160 | |
| 161 return syncer::SyncMergeResult(type); | |
| 162 } | |
| 163 | |
| 164 void SyncedNotificationsShim::StopSyncing(syncer::ModelType type) { | |
| 165 if (type == syncer::SYNCED_NOTIFICATIONS) | |
| 166 notifications_change_processor_.reset(); | |
| 167 else if (type == syncer::SYNCED_NOTIFICATION_APP_INFO) | |
| 168 app_info_change_processor_.reset(); | |
| 169 else | |
| 170 NOTREACHED(); | |
| 171 } | |
| 172 | |
| 173 syncer::SyncError SyncedNotificationsShim::ProcessSyncChanges( | |
| 174 const tracked_objects::Location& from_here, | |
| 175 const syncer::SyncChangeList& changes) { | |
| 176 std::vector<linked_ptr<synced_notifications_private::SyncChange> > js_changes; | |
| 177 for (size_t i = 0; i < changes.size(); ++i) | |
| 178 js_changes.push_back(BuildNewJSSyncChange(changes[i])); | |
| 179 | |
| 180 scoped_ptr<base::ListValue> args( | |
| 181 synced_notifications_private::OnDataChanges::Create(js_changes)); | |
| 182 scoped_ptr<Event> event(new Event( | |
| 183 synced_notifications_private::OnDataChanges::kEventName, args.Pass())); | |
| 184 event_launcher_.Run(event.Pass()); | |
| 185 return syncer::SyncError(); | |
| 186 } | |
| 187 | |
| 188 syncer::SyncDataList SyncedNotificationsShim::GetAllSyncData( | |
| 189 syncer::ModelType type) const { | |
| 190 NOTIMPLEMENTED(); | |
| 191 return syncer::SyncDataList(); | |
| 192 } | |
| 193 | |
| 194 bool SyncedNotificationsShim::GetInitialData( | |
| 195 synced_notifications_private::SyncDataType data_type, | |
| 196 std::vector<linked_ptr<synced_notifications_private::SyncData> >* | |
| 197 js_data_list) const { | |
| 198 if (!IsSyncReady()) | |
| 199 return false; | |
| 200 | |
| 201 syncer::SyncDataList sync_data_list; | |
| 202 if (JSDataTypeToSyncer(data_type) == syncer::SYNCED_NOTIFICATIONS) { | |
| 203 sync_data_list = notifications_change_processor_->GetAllSyncData( | |
| 204 syncer::SYNCED_NOTIFICATIONS); | |
| 205 if (PopulateJSDataListFromSync(sync_data_list, js_data_list)) | |
| 206 return true; | |
| 207 } else if (JSDataTypeToSyncer(data_type) == | |
| 208 syncer::SYNCED_NOTIFICATION_APP_INFO) { | |
| 209 sync_data_list = app_info_change_processor_->GetAllSyncData( | |
| 210 syncer::SYNCED_NOTIFICATION_APP_INFO); | |
| 211 if (PopulateJSDataListFromSync(sync_data_list, js_data_list)) | |
| 212 return true; | |
| 213 } | |
| 214 return false; | |
| 215 } | |
| 216 | |
| 217 bool SyncedNotificationsShim::UpdateNotification( | |
| 218 const std::string& changed_notification) { | |
| 219 if (!IsSyncReady()) | |
| 220 return false; | |
| 221 | |
| 222 syncer::SyncChange sync_change; | |
| 223 if (!BuildNewSyncUpdate(FROM_HERE, changed_notification, &sync_change)) | |
| 224 return false; | |
| 225 syncer::SyncError error = notifications_change_processor_->ProcessSyncChanges( | |
| 226 FROM_HERE, | |
| 227 syncer::SyncChangeList(1, sync_change)); | |
| 228 return !error.IsSet(); | |
| 229 } | |
| 230 | |
| 231 bool SyncedNotificationsShim::SetRenderContext( | |
| 232 synced_notifications_private::RefreshRequest refresh_request, | |
| 233 const std::string& new_context) { | |
| 234 if (!IsSyncReady()) | |
| 235 return false; | |
| 236 | |
| 237 syncer::SyncChangeProcessor::ContextRefreshStatus sync_refresh_status = | |
| 238 refresh_request == | |
| 239 synced_notifications_private::REFRESH_REQUEST_REFRESH_NEEDED | |
| 240 ? syncer::SyncChangeProcessor::REFRESH_NEEDED | |
| 241 : syncer::SyncChangeProcessor::NO_REFRESH; | |
| 242 syncer::SyncError error = | |
| 243 notifications_change_processor_->UpdateDataTypeContext( | |
| 244 syncer::SYNCED_NOTIFICATIONS, sync_refresh_status, new_context); | |
| 245 | |
| 246 if (sync_refresh_status == syncer::SyncChangeProcessor::REFRESH_NEEDED && | |
| 247 !refresh_request_.is_null()) { | |
| 248 refresh_request_.Run(); | |
| 249 } | |
| 250 | |
| 251 return !error.IsSet(); | |
| 252 } | |
| 253 | |
| 254 bool SyncedNotificationsShim::IsSyncReady() const { | |
| 255 return notifications_change_processor_ && app_info_change_processor_; | |
| 256 } | |
| OLD | NEW |