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
3 // found in the LICENSE file.
5 #include "chrome/browser/notifications/notification_ui_manager_android.h"
9 #include "base/android/jni_array.h"
10 #include "base/android/jni_string.h"
11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/notifications/notification.h"
15 #include "chrome/browser/notifications/persistent_notification_delegate.h"
16 #include "chrome/browser/notifications/platform_notification_service_impl.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "content/public/common/persistent_notification_status.h"
19 #include "content/public/common/platform_notification_data.h"
20 #include "jni/NotificationUIManager_jni.h"
21 #include "ui/gfx/android/java_bitmap.h"
22 #include "ui/gfx/image/image.h"
24 using base::android::AttachCurrentThread
;
25 using base::android::ConvertJavaStringToUTF8
;
26 using base::android::ConvertUTF16ToJavaString
;
27 using base::android::ConvertUTF8ToJavaString
;
29 // Called by the Java side when a notification event has been received, but the
30 // NotificationUIManager has not been initialized yet. Enforce initialization of
32 static void InitializeNotificationUIManager(JNIEnv
* env
,
33 const JavaParamRef
<jclass
>& clazz
) {
34 g_browser_process
->notification_ui_manager();
38 NotificationUIManager
* NotificationUIManager::Create(PrefService
* local_state
) {
39 return new NotificationUIManagerAndroid();
42 NotificationUIManagerAndroid::NotificationUIManagerAndroid() {
44 Java_NotificationUIManager_create(
45 AttachCurrentThread(),
46 reinterpret_cast<intptr_t>(this),
47 base::android::GetApplicationContext()));
50 NotificationUIManagerAndroid::~NotificationUIManagerAndroid() {
51 Java_NotificationUIManager_destroy(AttachCurrentThread(),
55 bool NotificationUIManagerAndroid::OnNotificationClicked(
58 jlong persistent_notification_id
,
62 GURL
origin(ConvertJavaStringToUTF8(env
, java_origin
));
63 std::string tag
= ConvertJavaStringToUTF8(env
, java_tag
);
65 regenerated_notification_infos_
[persistent_notification_id
] =
66 std::make_pair(origin
.spec(), tag
);
68 // TODO(peter): Rather than assuming that the last used profile is the
69 // appropriate one for this notification, the used profile should be
70 // stored as part of the notification's data. See https://crbug.com/437574.
71 PlatformNotificationServiceImpl::GetInstance()->OnPersistentNotificationClick(
72 ProfileManager::GetLastUsedProfile(),
73 persistent_notification_id
,
80 bool NotificationUIManagerAndroid::OnNotificationClosed(
83 jlong persistent_notification_id
,
86 GURL
origin(ConvertJavaStringToUTF8(env
, java_origin
));
87 std::string tag
= ConvertJavaStringToUTF8(env
, java_tag
);
89 // The notification was closed by the platform, so clear all local state.
90 regenerated_notification_infos_
.erase(persistent_notification_id
);
92 // TODO(peter): Rather than assuming that the last used profile is the
93 // appropriate one for this notification, the used profile should be
94 // stored as part of the notification's data. See https://crbug.com/437574.
95 PlatformNotificationServiceImpl::GetInstance()->OnPersistentNotificationClose(
96 ProfileManager::GetLastUsedProfile(),
97 persistent_notification_id
,
103 void NotificationUIManagerAndroid::Add(const Notification
& notification
,
105 JNIEnv
* env
= AttachCurrentThread();
107 // The Android notification UI manager only supports Web Notifications, which
108 // have a PersistentNotificationDelegate. The persistent id of the
109 // notification is exposed through it's interface.
111 // TODO(peter): When content/ passes a message_center::Notification to the
112 // chrome/ layer, the persistent notification id should be captured as a
113 // property on that object instead, making this cast unnecessary.
114 PersistentNotificationDelegate
* delegate
=
115 static_cast<PersistentNotificationDelegate
*>(notification
.delegate());
118 int64_t persistent_notification_id
= delegate
->persistent_notification_id();
119 GURL
origin_url(notification
.origin_url().GetOrigin());
121 ScopedJavaLocalRef
<jstring
> origin
= ConvertUTF8ToJavaString(
122 env
, origin_url
.spec());
123 ScopedJavaLocalRef
<jstring
> tag
=
124 ConvertUTF8ToJavaString(env
, notification
.tag());
125 ScopedJavaLocalRef
<jstring
> title
= ConvertUTF16ToJavaString(
126 env
, notification
.title());
127 ScopedJavaLocalRef
<jstring
> body
= ConvertUTF16ToJavaString(
128 env
, notification
.message());
130 ScopedJavaLocalRef
<jobject
> icon
;
132 SkBitmap icon_bitmap
= notification
.icon().AsBitmap();
133 if (!icon_bitmap
.isNull())
134 icon
= gfx::ConvertToJavaBitmap(&icon_bitmap
);
136 std::vector
<base::string16
> action_titles_vector
;
137 for (const message_center::ButtonInfo
& button
: notification
.buttons())
138 action_titles_vector
.push_back(button
.title
);
139 ScopedJavaLocalRef
<jobjectArray
> action_titles
=
140 base::android::ToJavaArrayOfStrings(env
, action_titles_vector
);
142 ScopedJavaLocalRef
<jintArray
> vibration_pattern
=
143 base::android::ToJavaIntArray(env
, notification
.vibration_pattern());
145 Java_NotificationUIManager_displayNotification(
148 persistent_notification_id
,
154 vibration_pattern
.obj(),
155 notification
.silent(),
156 action_titles
.obj());
158 regenerated_notification_infos_
[persistent_notification_id
] =
159 std::make_pair(origin_url
.spec(), notification
.tag());
161 notification
.delegate()->Display();
164 bool NotificationUIManagerAndroid::Update(const Notification
& notification
,
170 const Notification
* NotificationUIManagerAndroid::FindById(
171 const std::string
& delegate_id
,
172 ProfileID profile_id
) const {
177 bool NotificationUIManagerAndroid::CancelById(const std::string
& delegate_id
,
178 ProfileID profile_id
) {
179 int64_t persistent_notification_id
= 0;
181 // TODO(peter): Use the |delegate_id| directly when notification ids are being
182 // generated by content/ instead of us.
183 if (!base::StringToInt64(delegate_id
, &persistent_notification_id
))
186 const auto iterator
=
187 regenerated_notification_infos_
.find(persistent_notification_id
);
188 if (iterator
== regenerated_notification_infos_
.end())
191 const RegeneratedNotificationInfo
& notification_info
= iterator
->second
;
193 JNIEnv
* env
= AttachCurrentThread();
195 ScopedJavaLocalRef
<jstring
> origin
=
196 ConvertUTF8ToJavaString(env
, notification_info
.first
);
197 ScopedJavaLocalRef
<jstring
> tag
=
198 ConvertUTF8ToJavaString(env
, notification_info
.second
);
200 regenerated_notification_infos_
.erase(iterator
);
202 Java_NotificationUIManager_closeNotification(env
,
204 persistent_notification_id
,
210 std::set
<std::string
>
211 NotificationUIManagerAndroid::GetAllIdsByProfileAndSourceOrigin(
212 ProfileID profile_id
,
213 const GURL
& source
) {
215 return std::set
<std::string
>();
218 std::set
<std::string
> NotificationUIManagerAndroid::GetAllIdsByProfile(
219 ProfileID profile_id
) {
221 return std::set
<std::string
>();
224 bool NotificationUIManagerAndroid::CancelAllBySourceOrigin(
225 const GURL
& source_origin
) {
230 bool NotificationUIManagerAndroid::CancelAllByProfile(ProfileID profile_id
) {
235 void NotificationUIManagerAndroid::CancelAll() {
239 bool NotificationUIManagerAndroid::RegisterNotificationUIManager(JNIEnv
* env
) {
240 return RegisterNativesImpl(env
);