Win 10 Notifications: Implement reminders (requireInteraction).

Also add a null timestamp test.

Bug: 734095
Change-Id: Ib51c0f05e685c29cf282122e6e1b5e62aff70771
Reviewed-on: https://chromium-review.googlesource.com/739385
Commit-Queue: Finnur Thorarinsson <finnur@chromium.org>
Reviewed-by: Peter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#514241}
diff --git a/chrome/browser/notifications/notification_template_builder.cc b/chrome/browser/notifications/notification_template_builder.cc
index 5583e6c..445c103 100644
--- a/chrome/browser/notifications/notification_template_builder.cc
+++ b/chrome/browser/notifications/notification_template_builder.cc
@@ -35,14 +35,16 @@
 const char kInputType[] = "type";
 const char kPlaceholderContent[] = "placeHolderContent";
 const char kPlacement[] = "placement";
+const char kReminder[] = "reminder";
+const char kScenario[] = "scenario";
 const char kSilent[] = "silent";
 const char kText[] = "text";
 const char kTrue[] = "true";
 const char kUserResponse[] = "userResponse";
 const char kTextElement[] = "text";
 const char kToastElement[] = "toast";
-const char kToastElementLaunchAttribute[] = "launch";
 const char kToastElementDisplayTimestamp[] = "displayTimestamp";
+const char kToastElementLaunchAttribute[] = "launch";
 const char kVisualElement[] = "visual";
 
 // Name of the template used for default Chrome notifications.
@@ -59,12 +61,9 @@
   std::unique_ptr<NotificationTemplateBuilder> builder =
       base::WrapUnique(new NotificationTemplateBuilder);
 
-  // TODO(finnur): Can we set <toast scenario="reminder"> for notifications
-  // that have set the never_timeout() flag?
-  builder->StartToastElement(notification.id(), notification.timestamp());
+  builder->StartToastElement(notification.id(), notification);
   builder->StartVisualElement();
 
-  // TODO(finnur): Set the correct binding template based on the |notification|.
   builder->StartBindingElement(kDefaultTemplate);
 
   // Content for the toast template.
@@ -118,19 +117,24 @@
 
 void NotificationTemplateBuilder::StartToastElement(
     const std::string& notification_id,
-    const base::Time& timestamp) {
+    const message_center::Notification& notification) {
   xml_writer_->StartElement(kToastElement);
   xml_writer_->AddAttribute(kToastElementLaunchAttribute, notification_id);
+  // Note: If the notification doesn't include a button, then Windows will
+  // ignore the Reminder flag.
+  if (notification.never_timeout())
+    xml_writer_->AddAttribute(kScenario, kReminder);
 
-  if (!timestamp.is_null()) {
-    base::Time::Exploded exploded;
-    timestamp.UTCExplode(&exploded);
-    xml_writer_->AddAttribute(
-        kToastElementDisplayTimestamp,
-        base::StringPrintf("%04d-%02d-%02dT%02d:%02d:%02dZ", exploded.year,
-                           exploded.month, exploded.day_of_month, exploded.hour,
-                           exploded.minute, exploded.second));
-  }
+  if (notification.timestamp().is_null())
+    return;
+
+  base::Time::Exploded exploded;
+  notification.timestamp().UTCExplode(&exploded);
+  xml_writer_->AddAttribute(
+      kToastElementDisplayTimestamp,
+      base::StringPrintf("%04d-%02d-%02dT%02d:%02d:%02dZ", exploded.year,
+                         exploded.month, exploded.day_of_month, exploded.hour,
+                         exploded.minute, exploded.second));
 }
 
 void NotificationTemplateBuilder::EndToastElement() {
diff --git a/chrome/browser/notifications/notification_template_builder.h b/chrome/browser/notifications/notification_template_builder.h
index 6bb7ff7..29d6657e 100644
--- a/chrome/browser/notifications/notification_template_builder.h
+++ b/chrome/browser/notifications/notification_template_builder.h
@@ -15,10 +15,6 @@
 class GURL;
 class XmlWriter;
 
-namespace base {
-class Time;
-}
-
 namespace message_center {
 struct ButtonInfo;
 class Notification;
@@ -54,7 +50,7 @@
   // Writes the <toast> element with the |notification_id| as the launch string.
   // Also closes the |xml_writer_| for writing as the toast is now complete.
   void StartToastElement(const std::string& notification_id,
-                         const base::Time& timastamp);
+                         const message_center::Notification& notification);
   void EndToastElement();
 
   // Writes the <visual> element.
diff --git a/chrome/browser/notifications/notification_template_builder_unittest.cc b/chrome/browser/notifications/notification_template_builder_unittest.cc
index 7871346..5bb1c9b 100644
--- a/chrome/browser/notifications/notification_template_builder_unittest.cc
+++ b/chrome/browser/notifications/notification_template_builder_unittest.cc
@@ -53,6 +53,7 @@
         base::UTF8ToUTF16(kNotificationMessage), gfx::Image() /* icon */,
         base::string16() /* display_source */, origin_url,
         NotifierId(origin_url), RichNotificationData(), nullptr /* delegate */);
+    // Set a fixed timestamp, to avoid having to test against current timestamp.
     base::Time timestamp;
     if (!FixedTime(&timestamp))
       return nullptr;
@@ -243,3 +244,51 @@
 
   ASSERT_NO_FATAL_FAILURE(VerifyXml(*notification, kExpectedXml));
 }
+
+TEST_F(NotificationTemplateBuilderTest, RequireInteraction) {
+  std::unique_ptr<message_center::Notification> notification =
+      InitializeBasicNotification();
+
+  std::vector<message_center::ButtonInfo> buttons;
+  buttons.emplace_back(base::ASCIIToUTF16("Button1"));
+  notification->set_buttons(buttons);
+  notification->set_never_timeout(true);
+
+  const wchar_t kExpectedXml[] =
+      LR"(<toast launch="notification_id" scenario="reminder" displayTimestamp="1998-09-04T01:02:03Z">
+ <visual>
+  <binding template="ToastGeneric">
+   <text>My Title</text>
+   <text>My Message</text>
+   <text placement="attribution">example.com</text>
+  </binding>
+ </visual>
+ <actions>
+  <action activationType="foreground" content="Button1" arguments="buttonIndex=0"/>
+ </actions>
+</toast>
+)";
+
+  ASSERT_NO_FATAL_FAILURE(VerifyXml(*notification, kExpectedXml));
+}
+
+TEST_F(NotificationTemplateBuilderTest, NullTimestamp) {
+  std::unique_ptr<message_center::Notification> notification =
+      InitializeBasicNotification();
+  base::Time timestamp;
+  notification->set_timestamp(timestamp);
+
+  const wchar_t kExpectedXml[] =
+      LR"(<toast launch="notification_id">
+ <visual>
+  <binding template="ToastGeneric">
+   <text>My Title</text>
+   <text>My Message</text>
+   <text placement="attribution">example.com</text>
+  </binding>
+ </visual>
+</toast>
+)";
+
+  ASSERT_NO_FATAL_FAILURE(VerifyXml(*notification, kExpectedXml));
+}