| 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->set_added_app_ids(added_app_ids); |
| 216 incoming->set_removed_app_ids(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_->OnAddedAppIds(added_app_ids); |
| 237 chrome_notifier_service_->OnRemovedAppIds(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 |