OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // The SyncedNotificationAppInfoService brings down read only metadata from the | 5 // The SyncedNotificationAppInfoService brings down read only metadata from the |
6 // sync server with information about the services sending synced notifications. | 6 // sync server with information about the services sending synced notifications. |
7 | 7 |
8 #include "chrome/browser/notifications/sync_notifier/synced_notification_app_inf o_service.h" | 8 #include "chrome/browser/notifications/sync_notifier/synced_notification_app_inf o_service.h" |
9 | 9 |
10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
11 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h" | |
12 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_fac tory.h" | |
11 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
12 #include "sync/api/sync_change.h" | 14 #include "sync/api/sync_change.h" |
13 #include "sync/api/sync_change_processor.h" | 15 #include "sync/api/sync_change_processor.h" |
14 #include "sync/api/sync_error_factory.h" | 16 #include "sync/api/sync_error_factory.h" |
15 #include "sync/protocol/sync.pb.h" | 17 #include "sync/protocol/sync.pb.h" |
16 #include "sync/protocol/synced_notification_app_info_specifics.pb.h" | 18 #include "sync/protocol/synced_notification_app_info_specifics.pb.h" |
17 #include "url/gurl.h" | 19 #include "url/gurl.h" |
18 | 20 |
19 namespace notifier { | 21 namespace notifier { |
20 | 22 |
23 bool SyncedNotificationAppInfoService::avoid_bitmap_fetching_for_test_ = false; | |
24 | |
21 SyncedNotificationAppInfoService::SyncedNotificationAppInfoService( | 25 SyncedNotificationAppInfoService::SyncedNotificationAppInfoService( |
22 Profile* profile) | 26 Profile* profile) |
23 : profile_(profile) {} | 27 : profile_(profile), chrome_notifier_service_(NULL) {} |
24 | 28 |
25 SyncedNotificationAppInfoService::~SyncedNotificationAppInfoService() {} | 29 SyncedNotificationAppInfoService::~SyncedNotificationAppInfoService() {} |
26 | 30 |
27 // Methods from BrowserContextKeyedService. | 31 // Methods from BrowserContextKeyedService. |
28 void SyncedNotificationAppInfoService::Shutdown() {} | 32 void SyncedNotificationAppInfoService::Shutdown() {} |
29 | 33 |
30 // syncer::SyncableService implementation. | 34 // syncer::SyncableService implementation. |
31 | 35 |
32 // This is called at startup to sync with the sync data. This code is not thread | 36 // This is called at startup to sync with the sync data. This code is not thread |
33 // safe, it should only be called by sync on the browser thread. | 37 // safe, it should only be called by sync on the browser thread. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 | 136 |
133 // TODO(petewil): Recreate this from internal data instead, | 137 // TODO(petewil): Recreate this from internal data instead, |
134 // it improves code maintainability. | 138 // it improves code maintainability. |
135 | 139 |
136 // make a copy for the list we give back to the caller. | 140 // make a copy for the list we give back to the caller. |
137 sync_data_list.push_back(sync_data_); | 141 sync_data_list.push_back(sync_data_); |
138 | 142 |
139 return sync_data_list; | 143 return sync_data_list; |
140 } | 144 } |
141 | 145 |
142 void SyncedNotificationAppInfoService::ProcessIncomingAppInfoProtobuf( | 146 void SyncedNotificationAppInfoService::ProcessIncomingAppInfoProtobuf( |
dewittj
2014/03/20 18:00:28
I think this code is resilient to the race conditi
Pete Williamson
2014/03/25 00:08:37
Done.
| |
143 const sync_pb::SyncedNotificationAppInfo& app_info) { | 147 const sync_pb::SyncedNotificationAppInfo& app_info) { |
144 // Build a local app_info object from the sync data. | 148 // Build a local app_info object from the sync data. |
145 scoped_ptr<SyncedNotificationAppInfo> incoming( | 149 scoped_ptr<SyncedNotificationAppInfo> incoming( |
146 CreateSyncedNotificationAppInfoFromProtobuf(app_info)); | 150 CreateSyncedNotificationAppInfoFromProtobuf(app_info)); |
147 DCHECK(incoming.get()); | 151 DCHECK(incoming.get()); |
148 | 152 |
149 // Process each incoming app_info protobuf. | 153 // Process each incoming app_info protobuf. |
150 const std::string& name = incoming->settings_display_name(); | 154 const std::string& name = incoming->settings_display_name(); |
151 DCHECK_GT(name.length(), 0U); | 155 DCHECK_GT(name.length(), 0U); |
152 if (name.length() == 0) { | 156 if (name.length() == 0) { |
153 // If there is no unique id (name), there is nothing we can do. | 157 // If there is no unique id (name), there is nothing we can do. |
154 return; | 158 return; |
155 } | 159 } |
156 | 160 |
157 SyncedNotificationAppInfo* found = FindSyncedNotificationAppInfoByName(name); | 161 SyncedNotificationAppInfo* found = FindSyncedNotificationAppInfoByName(name); |
158 | 162 |
159 if (NULL != found) { | 163 std::vector<std::string> old_app_ids; |
164 std::vector<std::string> new_app_ids; | |
165 std::vector<std::string> added_app_ids; | |
166 std::vector<std::string> removed_app_ids; | |
167 | |
168 new_app_ids = incoming->GetAppIdList(); | |
169 | |
170 if (NULL == found) { | |
171 added_app_ids = new_app_ids; | |
172 } else { | |
160 // When we have an update, some app id types may be added or removed. | 173 // When we have an update, some app id types may be added or removed. |
161 // Append to lists of added and removed types. | 174 // Append to lists of added and removed types. |
175 old_app_ids = found->GetAppIdList(); | |
176 new_app_ids = incoming->GetAppIdList(); | |
162 FreeSyncedNotificationAppInfoByName(name); | 177 FreeSyncedNotificationAppInfoByName(name); |
178 | |
179 // Set up for a set difference by sorting the lists. | |
180 std::sort(old_app_ids.begin(), old_app_ids.end()); | |
dewittj
2014/03/20 18:00:28
is it better to maintain a sorted order within Syn
Pete Williamson
2014/03/25 00:08:37
Adding a new app info is incredibly rare, as is re
| |
181 std::sort(new_app_ids.begin(), new_app_ids.end()); | |
182 | |
183 // Calculate which app ids are removed (in old, but not in new app ids). | |
184 std::set_difference(old_app_ids.begin(), | |
185 old_app_ids.end(), | |
186 new_app_ids.begin(), | |
187 new_app_ids.end(), | |
188 std::back_inserter(removed_app_ids)); | |
189 | |
190 // Calculate which app_ids are added (in new, but not in old app ids). | |
191 std::set_difference(new_app_ids.begin(), | |
192 new_app_ids.end(), | |
193 old_app_ids.begin(), | |
194 old_app_ids.end(), | |
195 std::back_inserter(added_app_ids)); | |
196 } | |
197 | |
198 // Put these lists into the app_info object. | |
199 incoming->SetAddedAppIds(added_app_ids); | |
200 incoming->SetRemovedAppIds(removed_app_ids); | |
201 | |
202 // Start bitmap fetch. | |
203 if (!avoid_bitmap_fetching_for_test_) { | |
204 incoming->QueueBitmapFetchJobs(); | |
205 incoming->StartBitmapFetch(); | |
206 } else { | |
207 OnBitmapFetchesDone(incoming->added_app_ids(), incoming->removed_app_ids()); | |
163 } | 208 } |
164 | 209 |
165 sending_service_infos_.push_back(incoming.release()); | 210 sending_service_infos_.push_back(incoming.release()); |
211 } | |
166 | 212 |
213 void SyncedNotificationAppInfoService::OnBitmapFetchesDone( | |
214 std::vector<std::string> added_app_ids, | |
215 std::vector<std::string> removed_app_ids) { | |
167 // Tell the Chrome Notifier Service so it can show any notifications that were | 216 // Tell the Chrome Notifier Service so it can show any notifications that were |
168 // waiting for the app id to arrive, and to remave any notifications that are | 217 // waiting for the app id to arrive, and to remave any notifications that are |
169 // no longer supported. | 218 // no longer supported. |
170 // TODO(petewil): Notify CNS of added ids | 219 if (chrome_notifier_service_ != NULL) { |
171 // TODO(petewil): Notify CNS of deleted ids. | 220 chrome_notifier_service_->SetAddedAppIds(added_app_ids); |
221 chrome_notifier_service_->SetRemovedAppIds(removed_app_ids); | |
222 } | |
172 } | 223 } |
173 | 224 |
174 // Static Method. Convert from a server protobuf to our internal format. | 225 // Static Method. Convert from a server protobuf to our internal format. |
175 scoped_ptr<SyncedNotificationAppInfo> | 226 scoped_ptr<SyncedNotificationAppInfo> |
176 SyncedNotificationAppInfoService::CreateSyncedNotificationAppInfoFromProtobuf( | 227 SyncedNotificationAppInfoService::CreateSyncedNotificationAppInfoFromProtobuf( |
177 const sync_pb::SyncedNotificationAppInfo& server_app_info) { | 228 const sync_pb::SyncedNotificationAppInfo& server_app_info) { |
178 | 229 |
179 // Check for mandatory fields in the sync_data object. | 230 // Check for mandatory fields in the sync_data object. |
180 std::string display_name; | 231 std::string display_name; |
181 if (server_app_info.has_settings_display_name()) { | 232 if (server_app_info.has_settings_display_name()) { |
182 display_name = server_app_info.settings_display_name(); | 233 display_name = server_app_info.settings_display_name(); |
183 } | 234 } |
184 scoped_ptr<SyncedNotificationAppInfo> app_info; | 235 scoped_ptr<SyncedNotificationAppInfo> app_info; |
185 if (display_name.length() == 0) | 236 if (display_name.length() == 0) |
186 return app_info.Pass(); | 237 return app_info.Pass(); |
187 | 238 |
188 // Create a new app info object based on the supplied protobuf. | 239 // Create a new app info object based on the supplied protobuf. |
189 app_info.reset(new SyncedNotificationAppInfo(display_name)); | 240 app_info.reset(new SyncedNotificationAppInfo(profile_, display_name, this)); |
190 | 241 |
191 // TODO(petewil): Eventually we will add the monochrome icon here, and we may | 242 // TODO(petewil): Eventually we will add the monochrome icon here, and we may |
192 // need to fetch the correct url for the current DPI. | 243 // need to fetch the correct url for the current DPI. |
193 // Add the icon URL, if any. | 244 // Add the icon URL, if any. |
194 if (server_app_info.has_icon()) { | 245 if (server_app_info.has_icon()) { |
195 std::string icon_url = server_app_info.icon().url(); | 246 std::string icon_url = server_app_info.icon().url(); |
196 app_info->SetSettingsIcon(GURL(icon_url)); | 247 app_info->SetSettingsIcon(GURL(icon_url)); |
197 } | 248 } |
198 | 249 |
199 // Add all the AppIds from the protobuf. | 250 // Add all the AppIds from the protobuf. |
(...skipping 15 matching lines...) Expand all Loading... | |
215 it != sending_service_infos_.end(); | 266 it != sending_service_infos_.end(); |
216 ++it) { | 267 ++it) { |
217 SyncedNotificationAppInfo* app_info = *it; | 268 SyncedNotificationAppInfo* app_info = *it; |
218 if (name == app_info->settings_display_name()) | 269 if (name == app_info->settings_display_name()) |
219 return *it; | 270 return *it; |
220 } | 271 } |
221 | 272 |
222 return NULL; | 273 return NULL; |
223 } | 274 } |
224 | 275 |
276 // This returns a pointer into a vector that we own. Caller must not free it. | |
277 // Returns NULL if no match is found. | |
278 notifier::SyncedNotificationAppInfo* | |
279 SyncedNotificationAppInfoService::FindSyncedNotificationAppInfoByAppId( | |
280 const std::string& app_id) { | |
281 for (ScopedVector<SyncedNotificationAppInfo>::const_iterator it = | |
282 sending_service_infos_.begin(); | |
283 it != sending_service_infos_.end(); | |
284 ++it) { | |
285 SyncedNotificationAppInfo* app_info = *it; | |
286 if (app_info->HasAppId(app_id)) | |
287 return *it; | |
288 } | |
289 | |
290 return NULL; | |
291 } | |
292 | |
293 // Lookup the sending service name for a given app id. | |
294 std::string SyncedNotificationAppInfoService::FindSendingServiceNameFromAppId( | |
295 const std::string app_id) { | |
296 for (ScopedVector<SyncedNotificationAppInfo>::const_iterator it = | |
297 sending_service_infos_.begin(); | |
298 it != sending_service_infos_.end(); | |
299 ++it) { | |
300 SyncedNotificationAppInfo* app_info = *it; | |
301 if (app_info->HasAppId(app_id)) | |
302 return app_info->settings_display_name(); | |
303 } | |
304 | |
305 return std::string(); | |
306 } | |
307 | |
225 void SyncedNotificationAppInfoService::FreeSyncedNotificationAppInfoByName( | 308 void SyncedNotificationAppInfoService::FreeSyncedNotificationAppInfoByName( |
226 const std::string& name) { | 309 const std::string& name) { |
227 ScopedVector<SyncedNotificationAppInfo>::iterator it = | 310 ScopedVector<SyncedNotificationAppInfo>::iterator it = |
228 sending_service_infos_.begin(); | 311 sending_service_infos_.begin(); |
229 for (; it != sending_service_infos_.end(); ++it) { | 312 for (; it != sending_service_infos_.end(); ++it) { |
230 SyncedNotificationAppInfo* app_info = *it; | 313 SyncedNotificationAppInfo* app_info = *it; |
231 if (name == app_info->settings_display_name()) { | 314 if (name == app_info->settings_display_name()) { |
232 sending_service_infos_.erase(it); | 315 sending_service_infos_.erase(it); |
233 return; | 316 return; |
234 } | 317 } |
235 } | 318 } |
236 } | 319 } |
237 | 320 |
321 std::vector<std::string> | |
322 SyncedNotificationAppInfoService::GetAllSendingServiceNames() { | |
323 std::vector<std::string> names; | |
324 ScopedVector<SyncedNotificationAppInfo>::iterator it = | |
325 sending_service_infos_.begin(); | |
326 | |
327 for (; it != sending_service_infos_.end(); ++it) { | |
328 SyncedNotificationAppInfo* app_info = *it; | |
329 names.push_back(app_info->settings_display_name()); | |
330 } | |
331 | |
332 return names; | |
333 } | |
334 | |
238 // Add a new app info to our data structure. This takes ownership | 335 // Add a new app info to our data structure. This takes ownership |
239 // of the passed in pointer. | 336 // of the passed in pointer. |
240 void SyncedNotificationAppInfoService::Add( | 337 void SyncedNotificationAppInfoService::Add( |
241 scoped_ptr<SyncedNotificationAppInfo> app_info) { | 338 scoped_ptr<SyncedNotificationAppInfo> app_info) { |
242 sending_service_infos_.push_back(app_info.release()); | 339 sending_service_infos_.push_back(app_info.release()); |
243 } | 340 } |
244 | 341 |
245 } // namespace notifier | 342 } // namespace notifier |
OLD | NEW |