Index: chrome/browser/notifications/notification_ui_manager_android.cc |
diff --git a/chrome/browser/notifications/notification_ui_manager_android.cc b/chrome/browser/notifications/notification_ui_manager_android.cc |
index 71526389d092c2528f72a721ad5f978d6a940515..aa5984cf9515cb91bc8f980498f6da65da1cd80b 100644 |
--- a/chrome/browser/notifications/notification_ui_manager_android.cc |
+++ b/chrome/browser/notifications/notification_ui_manager_android.cc |
@@ -9,7 +9,7 @@ |
#include "base/android/jni_array.h" |
#include "base/android/jni_string.h" |
#include "base/logging.h" |
-#include "base/pickle.h" |
+#include "base/strings/string_number_conversions.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/notifications/notification.h" |
#include "chrome/browser/notifications/persistent_notification_delegate.h" |
@@ -29,91 +29,6 @@ using base::android::ConvertUTF8ToJavaString; |
namespace { |
-// The maximum size of the serialized pickle that carries a notification's meta |
-// information. Notifications carrying more data will be silently dropped - with |
-// an error being written to the log. |
-const int kMaximumSerializedNotificationSizeBytes = 1024 * 1024; |
- |
-// Persistent notifications are likely to outlive the browser process they were |
-// created by on Android. In order to be able to re-surface the notification |
-// when the user interacts with them, all relevant notification data needs to |
-// be serialized with the notification itself. |
-// |
-// In the near future, as more features get added to Chrome's notification |
-// implementation, this will be done by storing the persistent notification data |
-// in a database. However, to support launching Chrome for Android from a |
-// notification event until that exists, serialize the data in the Intent. |
-// |
-// TODO(peter): Move towards storing notification data in a database rather than |
-// as a serialized Intent extra. |
- |
-scoped_ptr<Pickle> SerializePersistentNotification( |
- const content::PlatformNotificationData& notification_data, |
- const GURL& origin, |
- int64 service_worker_registration_id) { |
- scoped_ptr<Pickle> pickle(new Pickle); |
- |
- // content::PlatformNotificationData |
- pickle->WriteString16(notification_data.title); |
- pickle->WriteInt(static_cast<int>(notification_data.direction)); |
- pickle->WriteString(notification_data.lang); |
- pickle->WriteString16(notification_data.body); |
- pickle->WriteString(notification_data.tag); |
- pickle->WriteString(notification_data.icon.spec()); |
- pickle->WriteBool(notification_data.silent); |
- |
- // The origin which is displaying the notification. |
- pickle->WriteString(origin.spec()); |
- |
- // The Service Worker registration this notification is associated with. |
- pickle->WriteInt64(service_worker_registration_id); |
- |
- if (pickle->size() > kMaximumSerializedNotificationSizeBytes) |
- return nullptr; |
- |
- return pickle.Pass(); |
-} |
- |
-bool UnserializePersistentNotification( |
- const Pickle& pickle, |
- content::PlatformNotificationData* notification_data, |
- GURL* origin, |
- int64* service_worker_registration_id) { |
- DCHECK(notification_data && origin && service_worker_registration_id); |
- PickleIterator iterator(pickle); |
- |
- std::string icon_url, origin_url; |
- int direction_value; |
- |
- // Unpack content::PlatformNotificationData. |
- if (!iterator.ReadString16(¬ification_data->title) || |
- !iterator.ReadInt(&direction_value) || |
- !iterator.ReadString(¬ification_data->lang) || |
- !iterator.ReadString16(¬ification_data->body) || |
- !iterator.ReadString(¬ification_data->tag) || |
- !iterator.ReadString(&icon_url) || |
- !iterator.ReadBool(¬ification_data->silent)) { |
- return false; |
- } |
- |
- notification_data->direction = |
- static_cast<content::PlatformNotificationData::NotificationDirection>( |
- direction_value); |
- notification_data->icon = GURL(icon_url); |
- |
- // Unpack the origin which displayed this notification. |
- if (!iterator.ReadString(&origin_url)) |
- return false; |
- |
- *origin = GURL(origin_url); |
- |
- // Unpack the Service Worker registration id. |
- if (!iterator.ReadInt64(service_worker_registration_id)) |
- return false; |
- |
- return true; |
-} |
- |
// Called when the "notificationclick" event in the Service Worker has finished |
// executing for a notification that was created in a previous instance of the |
// browser. |
@@ -143,8 +58,6 @@ NotificationUIManagerAndroid::NotificationUIManagerAndroid() { |
AttachCurrentThread(), |
reinterpret_cast<intptr_t>(this), |
base::android::GetApplicationContext())); |
- |
- // TODO(peter): Synchronize notifications with the Java side. |
} |
NotificationUIManagerAndroid::~NotificationUIManagerAndroid() { |
@@ -155,72 +68,35 @@ NotificationUIManagerAndroid::~NotificationUIManagerAndroid() { |
bool NotificationUIManagerAndroid::OnNotificationClicked( |
JNIEnv* env, |
jobject java_object, |
- jstring notification_id, |
- jbyteArray serialized_notification_data) { |
- std::string id = ConvertJavaStringToUTF8(env, notification_id); |
- |
- auto iter = profile_notifications_.find(id); |
- if (iter != profile_notifications_.end()) { |
- const Notification& notification = iter->second->notification(); |
- notification.delegate()->Click(); |
+ jlong persistent_notification_id, |
+ jstring java_origin, |
+ jstring java_tag) { |
+ GURL origin(ConvertJavaStringToUTF8(env, java_origin)); |
+ std::string tag = ConvertJavaStringToUTF8(env, java_tag); |
- return true; |
- } |
- |
- // If the Notification were not found, it may be a persistent notification |
- // that outlived the Chrome browser process. In this case, try to |
- // unserialize the notification's serialized data and trigger the click |
- // event manually. |
- |
- std::vector<uint8> bytes; |
- base::android::JavaByteArrayToByteVector(env, serialized_notification_data, |
- &bytes); |
- if (!bytes.size()) |
- return false; |
- |
- content::PlatformNotificationData notification_data; |
- GURL origin; |
- int64 service_worker_registration_id; |
- |
- Pickle pickle(reinterpret_cast<const char*>(&bytes[0]), bytes.size()); |
- if (!UnserializePersistentNotification(pickle, ¬ification_data, &origin, |
- &service_worker_registration_id)) { |
- return false; |
- } |
- |
- // Store the tag and origin of this notification so that it can later be |
- // closed using these details. |
- regenerated_notification_infos_[id] = |
- std::make_pair(notification_data.tag, origin.spec()); |
- |
- PlatformNotificationServiceImpl* service = |
- PlatformNotificationServiceImpl::GetInstance(); |
+ regenerated_notification_infos_[persistent_notification_id] = |
+ std::make_pair(origin.spec(), tag); |
// TODO(peter): Rather than assuming that the last used profile is the |
// appropriate one for this notification, the used profile should be |
// stored as part of the notification's data. See https://crbug.com/437574. |
- service->OnPersistentNotificationClick( |
+ PlatformNotificationServiceImpl::GetInstance()->OnPersistentNotificationClick( |
ProfileManager::GetLastUsedProfile(), |
- service_worker_registration_id, |
- id, |
+ persistent_notification_id, |
origin, |
- notification_data, |
base::Bind(&OnEventDispatchComplete)); |
return true; |
} |
bool NotificationUIManagerAndroid::OnNotificationClosed( |
- JNIEnv* env, jobject java_object, jstring notification_id) { |
- std::string id = ConvertJavaStringToUTF8(env, notification_id); |
- |
- auto iter = profile_notifications_.find(id); |
- if (iter == profile_notifications_.end()) |
- return false; |
- |
- const Notification& notification = iter->second->notification(); |
- notification.delegate()->Close(true /** by_user **/); |
- RemoveProfileNotification(iter->second, true /* close */); |
+ JNIEnv* env, |
+ jobject java_object, |
+ jlong persistent_notification_id, |
+ jstring java_origin, |
+ jstring java_tag) { |
+ // TODO(peter): Implement handling when a notification has been closed. The |
+ // notification database has to reflect this in its own state. |
return true; |
} |
@@ -242,16 +118,21 @@ void NotificationUIManagerAndroid::Add(const Notification& notification, |
JNIEnv* env = AttachCurrentThread(); |
+ PersistentNotificationDelegate* delegate = |
+ static_cast<PersistentNotificationDelegate*>(notification.delegate()); |
dewittj
2015/04/10 17:02:19
This could be dangerous in the face of Chrome-inte
Peter Beverloo
2015/04/13 16:22:32
There are no other users right now.
When //conten
|
+ DCHECK(delegate); |
+ |
+ int64_t persistent_notification_id = delegate->persistent_notification_id(); |
+ GURL origin_url(notification.origin_url().GetOrigin()); |
+ |
+ ScopedJavaLocalRef<jstring> origin = ConvertUTF8ToJavaString( |
+ env, origin_url.spec()); |
ScopedJavaLocalRef<jstring> tag = |
ConvertUTF8ToJavaString(env, notification.tag()); |
- ScopedJavaLocalRef<jstring> id = ConvertUTF8ToJavaString( |
- env, profile_notification->notification().id()); |
ScopedJavaLocalRef<jstring> title = ConvertUTF16ToJavaString( |
env, notification.title()); |
ScopedJavaLocalRef<jstring> body = ConvertUTF16ToJavaString( |
env, notification.message()); |
- ScopedJavaLocalRef<jstring> origin = ConvertUTF8ToJavaString( |
- env, notification.origin_url().GetOrigin().spec()); |
ScopedJavaLocalRef<jobject> icon; |
@@ -259,41 +140,19 @@ void NotificationUIManagerAndroid::Add(const Notification& notification, |
if (!icon_bitmap.isNull()) |
icon = gfx::ConvertToJavaBitmap(&icon_bitmap); |
- ScopedJavaLocalRef<jbyteArray> notification_data; |
- if (true /** is_persistent_notification **/) { |
- PersistentNotificationDelegate* delegate = |
- static_cast<PersistentNotificationDelegate*>(notification.delegate()); |
- scoped_ptr<Pickle> pickle = SerializePersistentNotification( |
- delegate->notification_data(), |
- notification.origin_url(), |
- delegate->service_worker_registration_id()); |
- |
- if (!pickle) { |
- LOG(ERROR) << |
- "Unable to serialize the notification, payload too large (max 1MB)."; |
- RemoveProfileNotification(profile_notification, true /* close */); |
- return; |
- } |
- |
- notification_data = base::android::ToJavaByteArray( |
- env, static_cast<const uint8*>(pickle->data()), pickle->size()); |
- } |
- |
Java_NotificationUIManager_displayNotification( |
env, |
java_object_.obj(), |
+ persistent_notification_id, |
+ origin.obj(), |
tag.obj(), |
- id.obj(), |
title.obj(), |
body.obj(), |
icon.obj(), |
- origin.obj(), |
- notification.silent(), |
- notification_data.obj()); |
+ notification.silent()); |
- regenerated_notification_infos_[profile_notification->notification().id()] = |
- std::make_pair(notification.tag(), |
- notification.origin_url().GetOrigin().spec()); |
+ regenerated_notification_infos_[persistent_notification_id] = |
+ std::make_pair(origin_url.spec(), notification.tag()); |
notification.delegate()->Display(); |
} |
@@ -408,25 +267,30 @@ bool NotificationUIManagerAndroid::RegisterNotificationUIManager(JNIEnv* env) { |
void NotificationUIManagerAndroid::PlatformCloseNotification( |
const std::string& notification_id) { |
- auto iterator = regenerated_notification_infos_.find(notification_id); |
+ int64_t persistent_notification_id = 0; |
+ if (!base::StringToInt64(notification_id, &persistent_notification_id)) |
+ return; |
+ |
+ const auto iterator = |
+ regenerated_notification_infos_.find(persistent_notification_id); |
if (iterator == regenerated_notification_infos_.end()) |
return; |
RegeneratedNotificationInfo notification_info = iterator->second; |
JNIEnv* env = AttachCurrentThread(); |
- ScopedJavaLocalRef<jstring> tag = |
- ConvertUTF8ToJavaString(env, notification_info.first); |
ScopedJavaLocalRef<jstring> origin = |
+ ConvertUTF8ToJavaString(env, notification_info.first); |
+ ScopedJavaLocalRef<jstring> tag = |
ConvertUTF8ToJavaString(env, notification_info.second); |
- ScopedJavaLocalRef<jstring> java_notification_id = |
- ConvertUTF8ToJavaString(env, notification_id); |
- regenerated_notification_infos_.erase(notification_id); |
+ regenerated_notification_infos_.erase(iterator); |
- Java_NotificationUIManager_closeNotification( |
- env, java_object_.obj(), tag.obj(), java_notification_id.obj(), |
- origin.obj()); |
+ Java_NotificationUIManager_closeNotification(env, |
+ java_object_.obj(), |
+ persistent_notification_id, |
+ origin.obj(), |
+ tag.obj()); |
} |
void NotificationUIManagerAndroid::AddProfileNotification( |