OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 package org.chromium.chrome.browser.notifications; | 5 package org.chromium.chrome.browser.notifications; |
6 | 6 |
7 import android.app.Notification; | 7 import android.app.Notification; |
8 import android.graphics.Bitmap; | 8 import android.graphics.Bitmap; |
9 import android.os.Build; | 9 import android.os.Build; |
| 10 import android.test.suitebuilder.annotation.LargeTest; |
10 import android.test.suitebuilder.annotation.MediumTest; | 11 import android.test.suitebuilder.annotation.MediumTest; |
11 import android.util.SparseArray; | 12 import android.util.SparseArray; |
12 | 13 |
13 import org.chromium.base.ThreadUtils; | 14 import org.chromium.base.ThreadUtils; |
14 import org.chromium.base.test.util.Feature; | 15 import org.chromium.base.test.util.Feature; |
15 import org.chromium.base.test.util.MinAndroidSdkLevel; | 16 import org.chromium.base.test.util.MinAndroidSdkLevel; |
16 import org.chromium.chrome.browser.preferences.website.ContentSetting; | 17 import org.chromium.chrome.browser.preferences.website.ContentSetting; |
17 import org.chromium.chrome.browser.preferences.website.PushNotificationInfo; | 18 import org.chromium.chrome.browser.preferences.website.PushNotificationInfo; |
18 import org.chromium.chrome.browser.widget.RoundedIconGenerator; | 19 import org.chromium.chrome.browser.widget.RoundedIconGenerator; |
19 import org.chromium.chrome.shell.ChromeShellTestBase; | 20 import org.chromium.chrome.shell.ChromeShellTestBase; |
20 import org.chromium.chrome.test.util.TestHttpServerClient; | 21 import org.chromium.chrome.test.util.TestHttpServerClient; |
21 import org.chromium.chrome.test.util.browser.notifications.MockNotificationManag
erProxy; | 22 import org.chromium.chrome.test.util.browser.notifications.MockNotificationManag
erProxy; |
22 import org.chromium.content.browser.test.util.Criteria; | 23 import org.chromium.content.browser.test.util.Criteria; |
23 import org.chromium.content.browser.test.util.CriteriaHelper; | 24 import org.chromium.content.browser.test.util.CriteriaHelper; |
24 import org.chromium.content.browser.test.util.JavaScriptUtils; | 25 import org.chromium.content.browser.test.util.JavaScriptUtils; |
25 | 26 |
26 import java.util.concurrent.TimeoutException; | 27 import java.util.concurrent.TimeoutException; |
27 | 28 |
28 /** | 29 /** |
29 * Instrumentation tests for the Notification UI Manager implementation on Andro
id. | 30 * Instrumentation tests for the Notification UI Manager implementation on Andro
id. |
30 * | 31 * |
31 * Web Notifications are only supported on Android JellyBean and beyond. | 32 * Web Notifications are only supported on Android JellyBean and beyond. |
32 */ | 33 */ |
33 @MinAndroidSdkLevel(Build.VERSION_CODES.JELLY_BEAN) | 34 @MinAndroidSdkLevel(Build.VERSION_CODES.JELLY_BEAN) |
34 public class NotificationUIManagerTest extends ChromeShellTestBase { | 35 public class NotificationUIManagerTest extends ChromeShellTestBase { |
35 private static final String NOTIFICATION_TEST_PAGE = | 36 private static final String NOTIFICATION_TEST_PAGE = |
36 TestHttpServerClient.getUrl("chrome/test/data/notifications/android_
test.html"); | 37 TestHttpServerClient.getUrl("chrome/test/data/notifications/android_
test.html"); |
37 private static final String PERMISSION_GRANTED = "\"granted\""; | |
38 | 38 |
39 private MockNotificationManagerProxy mMockNotificationManager; | 39 private MockNotificationManagerProxy mMockNotificationManager; |
40 | 40 |
41 /** | 41 /** |
42 * Returns the origin of the HTTP server the test is being ran on. | 42 * Returns the origin of the HTTP server the test is being ran on. |
43 */ | 43 */ |
44 private static String getOrigin() { | 44 private static String getOrigin() { |
45 return TestHttpServerClient.getUrl(""); | 45 return TestHttpServerClient.getUrl(""); |
46 } | 46 } |
47 | 47 |
48 /** | 48 /** |
49 * Sets the permission to use Web Notifications for the test HTTP server's o
rigin to |setting|. | 49 * Sets the permission to use Web Notifications for the test HTTP server's o
rigin to |setting|. |
50 */ | 50 */ |
51 private void setNotificationContentSettingForCurrentOrigin(final ContentSett
ing setting) { | 51 private void setNotificationContentSettingForCurrentOrigin(final ContentSett
ing setting) |
| 52 throws InterruptedException, TimeoutException { |
52 final String origin = getOrigin(); | 53 final String origin = getOrigin(); |
53 | 54 |
54 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | 55 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
55 @Override | 56 @Override |
56 public void run() { | 57 public void run() { |
57 // The notification content setting does not consider the embedd
er origin. | 58 // The notification content setting does not consider the embedd
er origin. |
58 PushNotificationInfo pushNotificationInfo = new PushNotification
Info(origin, ""); | 59 PushNotificationInfo pushNotificationInfo = new PushNotification
Info(origin, ""); |
59 pushNotificationInfo.setContentSetting(setting); | 60 pushNotificationInfo.setContentSetting(setting); |
60 } | 61 } |
61 }); | 62 }); |
| 63 |
| 64 String permission = runJavaScriptCodeInCurrentTab("Notification.permissi
on"); |
| 65 if (setting == ContentSetting.ALLOW) { |
| 66 assertEquals("\"granted\"", permission); |
| 67 } else if (setting == ContentSetting.BLOCK) { |
| 68 assertEquals("\"denied\"", permission); |
| 69 } else { |
| 70 assertEquals("\"default\"", permission); |
| 71 } |
62 } | 72 } |
63 | 73 |
64 /** | 74 /** |
65 * Runs the Javascript |code| in the current tab, and waits for the result t
o be available. | 75 * Runs the Javascript |code| in the current tab, and waits for the result t
o be available. |
66 * | 76 * |
67 * @param code The JavaScript code to execute in the current tab. | 77 * @param code The JavaScript code to execute in the current tab. |
68 * @return A JSON-formatted string with the result of executing the |code|. | 78 * @return A JSON-formatted string with the result of executing the |code|. |
69 */ | 79 */ |
70 private String runJavaScriptCodeInCurrentTab(String code) throws Interrupted
Exception, | 80 private String runJavaScriptCodeInCurrentTab(String code) throws Interrupted
Exception, |
71 TimeoutExce
ption { | 81 TimeoutExce
ption { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 } | 136 } |
127 | 137 |
128 /** | 138 /** |
129 * Verifies that the intended default properties of a notification will inde
ed be set on the | 139 * Verifies that the intended default properties of a notification will inde
ed be set on the |
130 * Notification object that will be send to Android. | 140 * Notification object that will be send to Android. |
131 */ | 141 */ |
132 @MediumTest | 142 @MediumTest |
133 @Feature({"Browser", "Notifications"}) | 143 @Feature({"Browser", "Notifications"}) |
134 public void testDefaultNotificationProperties() throws Exception { | 144 public void testDefaultNotificationProperties() throws Exception { |
135 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); | 145 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); |
136 assertEquals(PERMISSION_GRANTED, runJavaScriptCodeInCurrentTab("Notifica
tion.permission")); | |
137 | 146 |
138 Notification notification = showAndGetNotification("MyNotification", "{
body: 'Hello' }"); | 147 Notification notification = showAndGetNotification("MyNotification", "{
body: 'Hello' }"); |
139 assertNotNull(notification); | |
140 | 148 |
141 // Validate the contents of the notification. | 149 // Validate the contents of the notification. |
142 assertEquals("MyNotification", notification.extras.getString(Notificatio
n.EXTRA_TITLE)); | 150 assertEquals("MyNotification", notification.extras.getString(Notificatio
n.EXTRA_TITLE)); |
143 assertEquals("Hello", notification.extras.getString(Notification.EXTRA_T
EXT)); | 151 assertEquals("Hello", notification.extras.getString(Notification.EXTRA_T
EXT)); |
144 assertEquals(getOrigin(), notification.extras.getString(Notification.EXT
RA_SUB_TEXT)); | 152 assertEquals(getOrigin(), notification.extras.getString(Notification.EXT
RA_SUB_TEXT)); |
145 | 153 |
146 // Validate the appearance style of the notification. The EXTRA_TEMPLATE
was inroduced | 154 // Validate the appearance style of the notification. The EXTRA_TEMPLATE
was inroduced |
147 // in Android Lollipop, we cannot verify this in earlier versions. | 155 // in Android Lollipop, we cannot verify this in earlier versions. |
148 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | 156 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
149 assertEquals("android.app.Notification$BigTextStyle", | 157 assertEquals("android.app.Notification$BigTextStyle", |
150 notification.extras.getString(Notification.EXTRA_TEMPLATE)); | 158 notification.extras.getString(Notification.EXTRA_TEMPLATE)); |
151 } | 159 } |
152 | 160 |
153 assertNotNull(notification.largeIcon); | 161 assertNotNull(notification.largeIcon); |
154 | 162 |
155 // Validate the notification's behavior. | 163 // Validate the notification's behavior. |
156 assertEquals(Notification.DEFAULT_ALL, notification.defaults); | 164 assertEquals(Notification.DEFAULT_ALL, notification.defaults); |
157 assertEquals(Notification.PRIORITY_DEFAULT, notification.priority); | 165 assertEquals(Notification.PRIORITY_DEFAULT, notification.priority); |
158 } | 166 } |
159 | 167 |
160 /** | 168 /** |
161 * Verifies that notifications which specify an icon will have that icon fet
ched, converted into | 169 * Verifies that notifications which specify an icon will have that icon fet
ched, converted into |
162 * a Bitmap and included as the large icon in the notification. | 170 * a Bitmap and included as the large icon in the notification. |
163 */ | 171 */ |
164 @MediumTest | 172 @MediumTest |
165 @Feature({"Browser", "Notifications"}) | 173 @Feature({"Browser", "Notifications"}) |
166 public void testShowNotificationWithIcon() throws Exception { | 174 public void testShowNotificationWithIcon() throws Exception { |
167 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); | 175 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); |
168 assertEquals(PERMISSION_GRANTED, runJavaScriptCodeInCurrentTab("Notifica
tion.permission")); | |
169 | 176 |
170 Notification notification = showAndGetNotification("MyNotification", "{i
con: 'icon.png'}"); | 177 Notification notification = showAndGetNotification("MyNotification", "{i
con: 'icon.png'}"); |
171 assertNotNull(notification); | |
172 | 178 |
173 assertEquals("MyNotification", notification.extras.getString(Notificatio
n.EXTRA_TITLE)); | 179 assertEquals("MyNotification", notification.extras.getString(Notificatio
n.EXTRA_TITLE)); |
174 assertNotNull(notification.largeIcon); | 180 assertNotNull(notification.largeIcon); |
175 | 181 |
176 // These are the dimensions of //chrome/test/data/notifications/icon.png
at 1x scale. | 182 // These are the dimensions of //chrome/test/data/notifications/icon.png
at 1x scale. |
177 assertEquals(100, notification.largeIcon.getWidth()); | 183 assertEquals(100, notification.largeIcon.getWidth()); |
178 assertEquals(100, notification.largeIcon.getHeight()); | 184 assertEquals(100, notification.largeIcon.getHeight()); |
179 } | 185 } |
180 | 186 |
181 /** | 187 /** |
182 * Verifies that notifications which don't specify an icon will get an autom
atically generated | 188 * Verifies that notifications which don't specify an icon will get an autom
atically generated |
183 * icon based on their origin. The size of these icons are dependent on the
resolution of the | 189 * icon based on their origin. The size of these icons are dependent on the
resolution of the |
184 * device the test is being ran on, so we create it again in order to compar
e. | 190 * device the test is being ran on, so we create it again in order to compar
e. |
185 */ | 191 */ |
186 @MediumTest | 192 @MediumTest |
187 @Feature({"Browser", "Notifications"}) | 193 @Feature({"Browser", "Notifications"}) |
188 public void testShowNotificationWithoutIcon() throws Exception { | 194 public void testShowNotificationWithoutIcon() throws Exception { |
189 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); | 195 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); |
190 assertEquals(PERMISSION_GRANTED, runJavaScriptCodeInCurrentTab("Notifica
tion.permission")); | |
191 | 196 |
192 Notification notification = showAndGetNotification("NoIconNotification",
"{}"); | 197 Notification notification = showAndGetNotification("NoIconNotification",
"{}"); |
193 assertNotNull(notification); | |
194 | 198 |
195 assertEquals("NoIconNotification", notification.extras.getString(Notific
ation.EXTRA_TITLE)); | 199 assertEquals("NoIconNotification", notification.extras.getString(Notific
ation.EXTRA_TITLE)); |
196 assertNotNull(notification.largeIcon); | 200 assertNotNull(notification.largeIcon); |
197 | 201 |
198 // Create a second rounded icon for the test's origin, and compare its d
imensions against | 202 // Create a second rounded icon for the test's origin, and compare its d
imensions against |
199 // those of the icon associated to the notification itself. | 203 // those of the icon associated to the notification itself. |
200 RoundedIconGenerator generator = NotificationUIManager.createRoundedIcon
Generator( | 204 RoundedIconGenerator generator = NotificationUIManager.createRoundedIcon
Generator( |
201 getActivity().getApplicationContext()); | 205 getActivity().getApplicationContext()); |
202 assertNotNull(generator); | 206 assertNotNull(generator); |
203 | 207 |
204 Bitmap generatedIcon = generator.generateIconForUrl(getOrigin()); | 208 Bitmap generatedIcon = generator.generateIconForUrl(getOrigin()); |
205 assertNotNull(generatedIcon); | 209 assertNotNull(generatedIcon); |
206 | 210 |
207 assertEquals(generatedIcon.getWidth(), notification.largeIcon.getWidth()
); | 211 assertEquals(generatedIcon.getWidth(), notification.largeIcon.getWidth()
); |
208 assertEquals(generatedIcon.getHeight(), notification.largeIcon.getHeight
()); | 212 assertEquals(generatedIcon.getHeight(), notification.largeIcon.getHeight
()); |
209 } | 213 } |
| 214 |
| 215 /* |
| 216 * Verifies that starting the PendingIntent stored as the notification's con
tent intent will |
| 217 * start up the associated Service Worker, where the JavaScript code will cl
ose the notification |
| 218 * by calling event.notification.close(). |
| 219 */ |
| 220 @LargeTest |
| 221 @Feature({"Browser", "Notifications"}) |
| 222 public void testNotificationContentIntentClosesNotification() throws Excepti
on { |
| 223 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); |
| 224 |
| 225 Notification notification = showAndGetNotification("MyNotification", "{}
"); |
| 226 |
| 227 // Sending the PendingIntent resembles activating the notification. |
| 228 assertNotNull(notification.contentIntent); |
| 229 notification.contentIntent.send(); |
| 230 |
| 231 // The Service Worker will close the notification upon receiving the not
ificationclick |
| 232 // event. This will eventually bubble up to a call to cancel() in the No
tificationManager. |
| 233 assertTrue(waitForNotificationManagerMutation()); |
| 234 |
| 235 SparseArray<Notification> notifications = mMockNotificationManager.getNo
tifications(); |
| 236 assertEquals(0, notifications.size()); |
| 237 } |
| 238 |
| 239 /** |
| 240 * Verifies that creating a notification with an associated "tag" will cause
any previous |
| 241 * notification with the same tag to be dismissed prior to being shown. |
| 242 */ |
| 243 @MediumTest |
| 244 @Feature({"Browser", "Notifications"}) |
| 245 public void testNotificationTagReplacement() throws Exception { |
| 246 setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); |
| 247 |
| 248 Notification notification = showAndGetNotification("MyNotification", "{t
ag: 'myTag'}"); |
| 249 |
| 250 // Show the second notification with the same tag. We can't use showAndG
etNotification for |
| 251 // this purpose since a second notification would be shown. |
| 252 runJavaScriptCodeInCurrentTab("showNotification('SecondNotification', {t
ag: 'myTag'});"); |
| 253 assertTrue(waitForNotificationManagerMutation()); |
| 254 |
| 255 // Verify that the notification was successfully replaced. |
| 256 SparseArray<Notification> notifications = mMockNotificationManager.getNo
tifications(); |
| 257 assertEquals(1, notifications.size()); |
| 258 assertEquals("SecondNotification", |
| 259 notifications.valueAt(0).extras.getString(Notification.EXTRA_TIT
LE)); |
| 260 } |
210 } | 261 } |
OLD | NEW |