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 SyncedNotificationSendingServiceSettingsData:: |
| 24 SyncedNotificationSendingServiceSettingsData( |
| 25 std::string settings_display_name_param, |
| 26 gfx::Image settings_icon_param, |
| 27 message_center::NotifierId notifier_id_param) |
| 28 : settings_display_name(settings_display_name_param), |
| 29 settings_icon(settings_icon_param), |
| 30 notifier_id(notifier_id_param) {} |
| 31 |
| 32 bool SyncedNotificationAppInfoService::avoid_bitmap_fetching_for_test_ = false; |
| 33 |
21 SyncedNotificationAppInfoService::SyncedNotificationAppInfoService( | 34 SyncedNotificationAppInfoService::SyncedNotificationAppInfoService( |
22 Profile* profile) | 35 Profile* profile) |
23 : profile_(profile) {} | 36 : profile_(profile), chrome_notifier_service_(NULL) {} |
24 | 37 |
25 SyncedNotificationAppInfoService::~SyncedNotificationAppInfoService() {} | 38 SyncedNotificationAppInfoService::~SyncedNotificationAppInfoService() {} |
26 | 39 |
27 // Methods from BrowserContextKeyedService. | 40 // Methods from BrowserContextKeyedService. |
28 void SyncedNotificationAppInfoService::Shutdown() {} | 41 void SyncedNotificationAppInfoService::Shutdown() {} |
29 | 42 |
30 // syncer::SyncableService implementation. | 43 // syncer::SyncableService implementation. |
31 | 44 |
32 // This is called at startup to sync with the sync data. This code is not thread | 45 // 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. | 46 // 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 | 145 |
133 // TODO(petewil): Recreate this from internal data instead, | 146 // TODO(petewil): Recreate this from internal data instead, |
134 // it improves code maintainability. | 147 // it improves code maintainability. |
135 | 148 |
136 // make a copy for the list we give back to the caller. | 149 // make a copy for the list we give back to the caller. |
137 sync_data_list.push_back(sync_data_); | 150 sync_data_list.push_back(sync_data_); |
138 | 151 |
139 return sync_data_list; | 152 return sync_data_list; |
140 } | 153 } |
141 | 154 |
| 155 // When a new protobuf comes in, we will fetch all the bitmaps before reporting |
| 156 // the new protobufs to the ChromeNotifierService. This helps insure that new |
| 157 // protobufs appear at the same time old ones disappear, and that no protobuf |
| 158 // appears before its bitmaps are present. |
| 159 // We also check for duplicate bitmap URLs when loading the bitmaps for a |
| 160 // protobuf, so we aren't left waiting for a second copy of the bitmap to be |
| 161 // fetched before we call the protobuf done. |
142 void SyncedNotificationAppInfoService::ProcessIncomingAppInfoProtobuf( | 162 void SyncedNotificationAppInfoService::ProcessIncomingAppInfoProtobuf( |
143 const sync_pb::SyncedNotificationAppInfo& app_info) { | 163 const sync_pb::SyncedNotificationAppInfo& app_info) { |
144 // Build a local app_info object from the sync data. | 164 // Build a local app_info object from the sync data. |
145 scoped_ptr<SyncedNotificationAppInfo> incoming( | 165 scoped_ptr<SyncedNotificationAppInfo> incoming( |
146 CreateSyncedNotificationAppInfoFromProtobuf(app_info)); | 166 CreateSyncedNotificationAppInfoFromProtobuf(app_info)); |
147 DCHECK(incoming.get()); | 167 DCHECK(incoming.get()); |
148 | 168 |
149 // Process each incoming app_info protobuf. | 169 // Process each incoming app_info protobuf. |
150 const std::string& name = incoming->settings_display_name(); | 170 const std::string& name = incoming->settings_display_name(); |
151 DCHECK_GT(name.length(), 0U); | 171 DCHECK_GT(name.length(), 0U); |
152 if (name.length() == 0) { | 172 if (name.length() == 0) { |
153 // If there is no unique id (name), there is nothing we can do. | 173 // If there is no unique id (name), there is nothing we can do. |
154 return; | 174 return; |
155 } | 175 } |
156 | 176 |
157 SyncedNotificationAppInfo* found = FindSyncedNotificationAppInfoByName(name); | 177 SyncedNotificationAppInfo* found = FindSyncedNotificationAppInfoByName(name); |
158 | 178 |
159 if (NULL != found) { | 179 std::vector<std::string> old_app_ids; |
| 180 std::vector<std::string> new_app_ids; |
| 181 std::vector<std::string> added_app_ids; |
| 182 std::vector<std::string> removed_app_ids; |
| 183 |
| 184 new_app_ids = incoming->GetAppIdList(); |
| 185 |
| 186 if (NULL == found) { |
| 187 added_app_ids = new_app_ids; |
| 188 } else { |
160 // When we have an update, some app id types may be added or removed. | 189 // When we have an update, some app id types may be added or removed. |
161 // Append to lists of added and removed types. | 190 // Append to lists of added and removed types. |
| 191 old_app_ids = found->GetAppIdList(); |
| 192 new_app_ids = incoming->GetAppIdList(); |
162 FreeSyncedNotificationAppInfoByName(name); | 193 FreeSyncedNotificationAppInfoByName(name); |
| 194 |
| 195 // Set up for a set difference by sorting the lists. |
| 196 std::sort(old_app_ids.begin(), old_app_ids.end()); |
| 197 std::sort(new_app_ids.begin(), new_app_ids.end()); |
| 198 |
| 199 // Calculate which app ids are removed (in old, but not in new app ids). |
| 200 std::set_difference(old_app_ids.begin(), |
| 201 old_app_ids.end(), |
| 202 new_app_ids.begin(), |
| 203 new_app_ids.end(), |
| 204 std::back_inserter(removed_app_ids)); |
| 205 |
| 206 // Calculate which app_ids are added (in new, but not in old app ids). |
| 207 std::set_difference(new_app_ids.begin(), |
| 208 new_app_ids.end(), |
| 209 old_app_ids.begin(), |
| 210 old_app_ids.end(), |
| 211 std::back_inserter(added_app_ids)); |
| 212 } |
| 213 |
| 214 // Put these lists into the app_info object. |
| 215 incoming->SetAddedAppIds(added_app_ids); |
| 216 incoming->SetRemovedAppIds(removed_app_ids); |
| 217 |
| 218 // Start bitmap fetch. |
| 219 if (!avoid_bitmap_fetching_for_test_) { |
| 220 incoming->QueueBitmapFetchJobs(); |
| 221 incoming->StartBitmapFetch(); |
| 222 } else { |
| 223 OnBitmapFetchesDone(incoming->added_app_ids(), incoming->removed_app_ids()); |
163 } | 224 } |
164 | 225 |
165 sending_service_infos_.push_back(incoming.release()); | 226 sending_service_infos_.push_back(incoming.release()); |
| 227 } |
166 | 228 |
| 229 void SyncedNotificationAppInfoService::OnBitmapFetchesDone( |
| 230 std::vector<std::string> added_app_ids, |
| 231 std::vector<std::string> removed_app_ids) { |
167 // Tell the Chrome Notifier Service so it can show any notifications that were | 232 // 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 | 233 // waiting for the app id to arrive, and to remave any notifications that are |
169 // no longer supported. | 234 // no longer supported. |
170 // TODO(petewil): Notify CNS of added ids | 235 if (chrome_notifier_service_ != NULL) { |
171 // TODO(petewil): Notify CNS of deleted ids. | 236 chrome_notifier_service_->SetAddedAppIds(added_app_ids); |
| 237 chrome_notifier_service_->SetRemovedAppIds(removed_app_ids); |
| 238 } |
172 } | 239 } |
173 | 240 |
174 // Static Method. Convert from a server protobuf to our internal format. | 241 // Static Method. Convert from a server protobuf to our internal format. |
175 scoped_ptr<SyncedNotificationAppInfo> | 242 scoped_ptr<SyncedNotificationAppInfo> |
176 SyncedNotificationAppInfoService::CreateSyncedNotificationAppInfoFromProtobuf( | 243 SyncedNotificationAppInfoService::CreateSyncedNotificationAppInfoFromProtobuf( |
177 const sync_pb::SyncedNotificationAppInfo& server_app_info) { | 244 const sync_pb::SyncedNotificationAppInfo& server_app_info) { |
178 | 245 |
179 // Check for mandatory fields in the sync_data object. | 246 // Check for mandatory fields in the sync_data object. |
180 std::string display_name; | 247 std::string display_name; |
181 if (server_app_info.has_settings_display_name()) { | 248 if (server_app_info.has_settings_display_name()) { |
182 display_name = server_app_info.settings_display_name(); | 249 display_name = server_app_info.settings_display_name(); |
183 } | 250 } |
184 scoped_ptr<SyncedNotificationAppInfo> app_info; | 251 scoped_ptr<SyncedNotificationAppInfo> app_info; |
185 if (display_name.length() == 0) | 252 if (display_name.length() == 0) |
186 return app_info.Pass(); | 253 return app_info.Pass(); |
187 | 254 |
188 // Create a new app info object based on the supplied protobuf. | 255 // Create a new app info object based on the supplied protobuf. |
189 app_info.reset(new SyncedNotificationAppInfo(display_name)); | 256 app_info.reset(new SyncedNotificationAppInfo(profile_, display_name, this)); |
190 | 257 |
191 // TODO(petewil): Eventually we will add the monochrome icon here, and we may | 258 // TODO(petewil): Eventually we will add the monochrome icon here, and we may |
192 // need to fetch the correct url for the current DPI. | 259 // need to fetch the correct url for the current DPI. |
193 // Add the icon URL, if any. | 260 // Add the icon URL, if any. |
194 if (server_app_info.has_icon()) { | 261 if (server_app_info.has_icon()) { |
195 std::string icon_url = server_app_info.icon().url(); | 262 std::string icon_url = server_app_info.icon().url(); |
196 app_info->SetSettingsIcon(GURL(icon_url)); | 263 // Set the URLs for the low and high DPI images. |
| 264 // TODO(petewil): Since the high DPI image is not available yet, we just |
| 265 // pass an empty URL for now. Fix this once the high DPI URL is available. |
| 266 app_info->SetSettingsURLs(GURL(icon_url), GURL()); |
197 } | 267 } |
198 | 268 |
199 // Add all the AppIds from the protobuf. | 269 // Add all the AppIds from the protobuf. |
200 size_t app_id_count = server_app_info.app_id_size(); | 270 size_t app_id_count = server_app_info.app_id_size(); |
201 for (size_t ii = 0; ii < app_id_count; ++ii) { | 271 for (size_t ii = 0; ii < app_id_count; ++ii) { |
202 app_info->AddAppId(server_app_info.app_id(ii)); | 272 app_info->AddAppId(server_app_info.app_id(ii)); |
203 } | 273 } |
204 | 274 |
205 return app_info.Pass(); | 275 return app_info.Pass(); |
206 } | 276 } |
207 | 277 |
208 // This returns a pointer into a vector that we own. Caller must not free it. | 278 // This returns a pointer into a vector that we own. Caller must not free it. |
209 // Returns NULL if no match is found. | 279 // Returns NULL if no match is found. |
210 notifier::SyncedNotificationAppInfo* | 280 notifier::SyncedNotificationAppInfo* |
211 SyncedNotificationAppInfoService::FindSyncedNotificationAppInfoByName( | 281 SyncedNotificationAppInfoService::FindSyncedNotificationAppInfoByName( |
212 const std::string& name) { | 282 const std::string& name) { |
213 for (ScopedVector<SyncedNotificationAppInfo>::const_iterator it = | 283 for (ScopedVector<SyncedNotificationAppInfo>::const_iterator it = |
214 sending_service_infos_.begin(); | 284 sending_service_infos_.begin(); |
215 it != sending_service_infos_.end(); | 285 it != sending_service_infos_.end(); |
216 ++it) { | 286 ++it) { |
217 SyncedNotificationAppInfo* app_info = *it; | 287 SyncedNotificationAppInfo* app_info = *it; |
218 if (name == app_info->settings_display_name()) | 288 if (name == app_info->settings_display_name()) |
219 return *it; | 289 return *it; |
220 } | 290 } |
221 | 291 |
222 return NULL; | 292 return NULL; |
223 } | 293 } |
224 | 294 |
| 295 // This returns a pointer into a vector that we own. Caller must not free it. |
| 296 // Returns NULL if no match is found. |
| 297 notifier::SyncedNotificationAppInfo* |
| 298 SyncedNotificationAppInfoService::FindSyncedNotificationAppInfoByAppId( |
| 299 const std::string& app_id) { |
| 300 for (ScopedVector<SyncedNotificationAppInfo>::const_iterator it = |
| 301 sending_service_infos_.begin(); |
| 302 it != sending_service_infos_.end(); |
| 303 ++it) { |
| 304 SyncedNotificationAppInfo* app_info = *it; |
| 305 if (app_info->HasAppId(app_id)) |
| 306 return *it; |
| 307 } |
| 308 |
| 309 return NULL; |
| 310 } |
| 311 |
| 312 // Lookup the sending service name for a given app id. |
| 313 std::string SyncedNotificationAppInfoService::FindSendingServiceNameFromAppId( |
| 314 const std::string app_id) { |
| 315 for (ScopedVector<SyncedNotificationAppInfo>::const_iterator it = |
| 316 sending_service_infos_.begin(); |
| 317 it != sending_service_infos_.end(); |
| 318 ++it) { |
| 319 SyncedNotificationAppInfo* app_info = *it; |
| 320 if (app_info->HasAppId(app_id)) |
| 321 return app_info->settings_display_name(); |
| 322 } |
| 323 |
| 324 return std::string(); |
| 325 } |
| 326 |
225 void SyncedNotificationAppInfoService::FreeSyncedNotificationAppInfoByName( | 327 void SyncedNotificationAppInfoService::FreeSyncedNotificationAppInfoByName( |
226 const std::string& name) { | 328 const std::string& name) { |
227 ScopedVector<SyncedNotificationAppInfo>::iterator it = | 329 ScopedVector<SyncedNotificationAppInfo>::iterator it = |
228 sending_service_infos_.begin(); | 330 sending_service_infos_.begin(); |
229 for (; it != sending_service_infos_.end(); ++it) { | 331 for (; it != sending_service_infos_.end(); ++it) { |
230 SyncedNotificationAppInfo* app_info = *it; | 332 SyncedNotificationAppInfo* app_info = *it; |
231 if (name == app_info->settings_display_name()) { | 333 if (name == app_info->settings_display_name()) { |
232 sending_service_infos_.erase(it); | 334 sending_service_infos_.erase(it); |
233 return; | 335 return; |
234 } | 336 } |
235 } | 337 } |
236 } | 338 } |
237 | 339 |
| 340 std::vector<SyncedNotificationSendingServiceSettingsData> |
| 341 SyncedNotificationAppInfoService::GetAllSendingServiceSettingsData() { |
| 342 std::vector<SyncedNotificationSendingServiceSettingsData> settings_data; |
| 343 ScopedVector<SyncedNotificationAppInfo>::iterator it = |
| 344 sending_service_infos_.begin(); |
| 345 |
| 346 for (; it != sending_service_infos_.end(); ++it) { |
| 347 SyncedNotificationSendingServiceSettingsData this_service( |
| 348 (*it)->settings_display_name(), |
| 349 (*it)->icon(), |
| 350 (*it)->GetNotifierId()); |
| 351 settings_data.push_back(this_service); |
| 352 } |
| 353 |
| 354 return settings_data; |
| 355 } |
| 356 |
238 // Add a new app info to our data structure. This takes ownership | 357 // Add a new app info to our data structure. This takes ownership |
239 // of the passed in pointer. | 358 // of the passed in pointer. |
240 void SyncedNotificationAppInfoService::Add( | 359 void SyncedNotificationAppInfoService::Add( |
241 scoped_ptr<SyncedNotificationAppInfo> app_info) { | 360 scoped_ptr<SyncedNotificationAppInfo> app_info) { |
242 sending_service_infos_.push_back(app_info.release()); | 361 sending_service_infos_.push_back(app_info.release()); |
243 } | 362 } |
244 | 363 |
245 } // namespace notifier | 364 } // namespace notifier |
OLD | NEW |