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 #include "chrome/browser/notifications/notification_ui_manager_android.h" | 5 #include "chrome/browser/notifications/notification_ui_manager_android.h" |
6 | 6 |
7 #include "base/android/jni_array.h" | 7 #include "base/android/jni_array.h" |
8 #include "base/android/jni_string.h" | 8 #include "base/android/jni_string.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/pickle.h" | 10 #include "base/pickle.h" |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 145 |
146 NotificationUIManagerAndroid::~NotificationUIManagerAndroid() { | 146 NotificationUIManagerAndroid::~NotificationUIManagerAndroid() { |
147 Java_NotificationUIManager_destroy(AttachCurrentThread(), | 147 Java_NotificationUIManager_destroy(AttachCurrentThread(), |
148 java_object_.obj()); | 148 java_object_.obj()); |
149 } | 149 } |
150 | 150 |
151 bool NotificationUIManagerAndroid::OnNotificationClicked( | 151 bool NotificationUIManagerAndroid::OnNotificationClicked( |
152 JNIEnv* env, | 152 JNIEnv* env, |
153 jobject java_object, | 153 jobject java_object, |
154 jstring notification_id, | 154 jstring notification_id, |
| 155 jint platform_id, |
155 jbyteArray serialized_notification_data) { | 156 jbyteArray serialized_notification_data) { |
156 std::string id = ConvertJavaStringToUTF8(env, notification_id); | 157 std::string id = ConvertJavaStringToUTF8(env, notification_id); |
157 | 158 |
158 auto iter = profile_notifications_.find(id); | 159 auto iter = profile_notifications_.find(id); |
159 if (iter != profile_notifications_.end()) { | 160 if (iter != profile_notifications_.end()) { |
160 const Notification& notification = iter->second->notification(); | 161 const Notification& notification = iter->second->notification(); |
161 notification.delegate()->Click(); | 162 notification.delegate()->Click(); |
162 | 163 |
163 return true; | 164 return true; |
164 } | 165 } |
(...skipping 12 matching lines...) Expand all Loading... |
177 content::PlatformNotificationData notification_data; | 178 content::PlatformNotificationData notification_data; |
178 GURL origin; | 179 GURL origin; |
179 int64 service_worker_registration_id; | 180 int64 service_worker_registration_id; |
180 | 181 |
181 Pickle pickle(reinterpret_cast<const char*>(&bytes[0]), bytes.size()); | 182 Pickle pickle(reinterpret_cast<const char*>(&bytes[0]), bytes.size()); |
182 if (!UnserializePersistentNotification(pickle, ¬ification_data, &origin, | 183 if (!UnserializePersistentNotification(pickle, ¬ification_data, &origin, |
183 &service_worker_registration_id)) { | 184 &service_worker_registration_id)) { |
184 return false; | 185 return false; |
185 } | 186 } |
186 | 187 |
| 188 // Store the platform Id of this notification so that it can be closed. |
| 189 platform_notifications_[id] = platform_id; |
| 190 |
187 PlatformNotificationServiceImpl* service = | 191 PlatformNotificationServiceImpl* service = |
188 PlatformNotificationServiceImpl::GetInstance(); | 192 PlatformNotificationServiceImpl::GetInstance(); |
189 | 193 |
190 // TODO(peter): Rather than assuming that the last used profile is the | 194 // TODO(peter): Rather than assuming that the last used profile is the |
191 // appropriate one for this notification, the used profile should be | 195 // appropriate one for this notification, the used profile should be |
192 // stored as part of the notification's data. See https://crbug.com/437574. | 196 // stored as part of the notification's data. See https://crbug.com/437574. |
193 service->OnPersistentNotificationClick( | 197 service->OnPersistentNotificationClick( |
194 ProfileManager::GetLastUsedProfile(), | 198 ProfileManager::GetLastUsedProfile(), |
195 service_worker_registration_id, | 199 service_worker_registration_id, |
196 id, | 200 id, |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 | 316 |
313 return &profile_notification->notification(); | 317 return &profile_notification->notification(); |
314 } | 318 } |
315 | 319 |
316 bool NotificationUIManagerAndroid::CancelById(const std::string& delegate_id, | 320 bool NotificationUIManagerAndroid::CancelById(const std::string& delegate_id, |
317 ProfileID profile_id) { | 321 ProfileID profile_id) { |
318 std::string profile_notification_id = | 322 std::string profile_notification_id = |
319 ProfileNotification::GetProfileNotificationId(delegate_id, profile_id); | 323 ProfileNotification::GetProfileNotificationId(delegate_id, profile_id); |
320 ProfileNotification* profile_notification = | 324 ProfileNotification* profile_notification = |
321 FindProfileNotification(profile_notification_id); | 325 FindProfileNotification(profile_notification_id); |
322 if (!profile_notification) | 326 if (profile_notification) { |
323 return false; | 327 RemoveProfileNotification(profile_notification); |
| 328 return true; |
| 329 } |
324 | 330 |
325 RemoveProfileNotification(profile_notification); | 331 // On Android, it's still possible that the notification can be closed in case |
| 332 // the platform Id is known, even if no delegate exists. This happens when the |
| 333 // browser process is started because of interaction with a Notification. |
| 334 PlatformCloseNotification(delegate_id); |
326 return true; | 335 return true; |
327 } | 336 } |
328 | 337 |
329 std::set<std::string> | 338 std::set<std::string> |
330 NotificationUIManagerAndroid::GetAllIdsByProfileAndSourceOrigin( | 339 NotificationUIManagerAndroid::GetAllIdsByProfileAndSourceOrigin( |
331 Profile* profile, | 340 Profile* profile, |
332 const GURL& source) { | 341 const GURL& source) { |
333 // |profile| may be invalid, so no calls must be made based on the instance. | 342 // |profile| may be invalid, so no calls must be made based on the instance. |
334 std::set<std::string> delegate_ids; | 343 std::set<std::string> delegate_ids; |
335 | 344 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 } | 386 } |
378 } | 387 } |
379 | 388 |
380 return removed; | 389 return removed; |
381 } | 390 } |
382 | 391 |
383 void NotificationUIManagerAndroid::CancelAll() { | 392 void NotificationUIManagerAndroid::CancelAll() { |
384 for (auto iterator : profile_notifications_) { | 393 for (auto iterator : profile_notifications_) { |
385 ProfileNotification* profile_notification = iterator.second; | 394 ProfileNotification* profile_notification = iterator.second; |
386 | 395 |
387 PlatformCloseNotification(profile_notification); | 396 PlatformCloseNotification(profile_notification->notification().id()); |
388 delete profile_notification; | 397 delete profile_notification; |
389 } | 398 } |
390 | 399 |
391 profile_notifications_.clear(); | 400 profile_notifications_.clear(); |
392 } | 401 } |
393 | 402 |
394 bool NotificationUIManagerAndroid::RegisterNotificationUIManager(JNIEnv* env) { | 403 bool NotificationUIManagerAndroid::RegisterNotificationUIManager(JNIEnv* env) { |
395 return RegisterNativesImpl(env); | 404 return RegisterNativesImpl(env); |
396 } | 405 } |
397 | 406 |
398 void NotificationUIManagerAndroid::PlatformCloseNotification( | 407 void NotificationUIManagerAndroid::PlatformCloseNotification( |
399 ProfileNotification* profile_notification) { | 408 const std::string& notification_id) { |
400 std::string id = profile_notification->notification().id(); | 409 auto iterator = platform_notifications_.find(notification_id); |
401 | |
402 auto iterator = platform_notifications_.find(id); | |
403 if (iterator == platform_notifications_.end()) | 410 if (iterator == platform_notifications_.end()) |
404 return; | 411 return; |
405 | 412 |
406 int platform_id = iterator->second; | 413 int platform_id = iterator->second; |
407 platform_notifications_.erase(id); | 414 platform_notifications_.erase(notification_id); |
408 | 415 |
409 Java_NotificationUIManager_closeNotification(AttachCurrentThread(), | 416 Java_NotificationUIManager_closeNotification(AttachCurrentThread(), |
410 java_object_.obj(), | 417 java_object_.obj(), |
411 platform_id); | 418 platform_id); |
412 } | 419 } |
413 | 420 |
414 void NotificationUIManagerAndroid::AddProfileNotification( | 421 void NotificationUIManagerAndroid::AddProfileNotification( |
415 ProfileNotification* profile_notification) { | 422 ProfileNotification* profile_notification) { |
416 std::string id = profile_notification->notification().id(); | 423 std::string id = profile_notification->notification().id(); |
417 | 424 |
418 // Notification ids should be unique. | 425 // Notification ids should be unique. |
419 DCHECK(profile_notifications_.find(id) == profile_notifications_.end()); | 426 DCHECK(profile_notifications_.find(id) == profile_notifications_.end()); |
420 | 427 |
421 profile_notifications_[id] = profile_notification; | 428 profile_notifications_[id] = profile_notification; |
422 } | 429 } |
423 | 430 |
424 void NotificationUIManagerAndroid::RemoveProfileNotification( | 431 void NotificationUIManagerAndroid::RemoveProfileNotification( |
425 ProfileNotification* profile_notification) { | 432 ProfileNotification* profile_notification) { |
426 PlatformCloseNotification(profile_notification); | 433 std::string notification_id = profile_notification->notification().id(); |
| 434 PlatformCloseNotification(notification_id); |
427 | 435 |
428 std::string id = profile_notification->notification().id(); | 436 profile_notifications_.erase(notification_id); |
429 profile_notifications_.erase(id); | |
430 delete profile_notification; | 437 delete profile_notification; |
431 } | 438 } |
432 | 439 |
433 ProfileNotification* NotificationUIManagerAndroid::FindProfileNotification( | 440 ProfileNotification* NotificationUIManagerAndroid::FindProfileNotification( |
434 const std::string& id) const { | 441 const std::string& id) const { |
435 auto iter = profile_notifications_.find(id); | 442 auto iter = profile_notifications_.find(id); |
436 if (iter == profile_notifications_.end()) | 443 if (iter == profile_notifications_.end()) |
437 return nullptr; | 444 return nullptr; |
438 | 445 |
439 return iter->second; | 446 return iter->second; |
440 } | 447 } |
441 | 448 |
OLD | NEW |