Commit 459b1e93 authored by Tim Song's avatar Tim Song Committed by Commit Bot

[CrOS PhoneHub] Create CrOS notification based on corresponding fields.

Given the PhoneHub notification data, this CL fills in the created CrOS
corresponding notification's details:
  * timestamp
  * icons and images
  * priority
  * inline reply button

Screenshot:
https://screenshot.googleplex.com/8bhJVzvqFmPcufT.png

BUG=1128091,1106937

Change-Id: I82d64c1bb01235bb1dc64fab0b29cd00b3bef1a0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2418557
Commit-Queue: Tim Song <tengs@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808810}
parent f889890c
......@@ -1020,6 +1020,12 @@ This file contains the strings for ash.
<message name="IDS_ASH_PHONE_HUB_CONNECTION_ERROR_DIALOG_LEARN_MORE_BUTTON" desc="Learn more button on the connection error dialog to show more related information.">
Learn more
</message>
<message name="IDS_ASH_PHONE_HUB_NOTIFICATION_INLINE_REPLY_BUTTON" desc="Label for the inline reply button inside a PhoneHub notification.">
Reply
</message>
<message name="IDS_ASH_PHONE_HUB_NOTIFICATION_INLINE_CANCEL_BUTTON" desc="Label for the cancel button inside a PhoneHub notification.">
Cancel
</message>
<message name="IDS_ASH_STYLUS_TOOLS_CAPTURE_REGION_ACTION" desc="Title of the capture region action in the stylus tools (a pop-up panel next to the status tray). This causes a partial screenshot to be taken (the user selects an area of the screen to take a screenshot of).">
Capture region
......
eec76ed30accc851aabc95d10badb610413c3b57
\ No newline at end of file
eec76ed30accc851aabc95d10badb610413c3b57
\ No newline at end of file
......@@ -4,11 +4,14 @@
#include "ash/system/phonehub/phone_hub_notification_controller.h"
#include "ash/strings/grit/ash_strings.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "chromeos/components/phonehub/notification.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
......@@ -18,6 +21,8 @@ namespace ash {
namespace {
const char kNotifierId[] = "chrome://phonehub";
const char kNotifierIdSeparator[] = "-";
const int kReplyButtonIndex = 0;
const int kCancelButtonIndex = 1;
} // namespace
// Delegate for the displayed ChromeOS notification.
......@@ -59,8 +64,16 @@ class PhoneHubNotificationController::NotificationDelegate
void Click(const base::Optional<int>& button_index,
const base::Optional<base::string16>& reply) override {
if (controller_ && reply.has_value())
if (!controller_ || !button_index.has_value())
return;
if (button_index.value() == kReplyButtonIndex && reply.has_value()) {
controller_->SendInlineReply(phone_hub_id_, reply.value());
return;
}
if (button_index.value() == kCancelButtonIndex)
Remove();
}
void SettingsClick() override {
......@@ -173,20 +186,64 @@ PhoneHubNotificationController::CreateNotification(
const chromeos::phonehub::Notification* notification,
const std::string& cros_id,
NotificationDelegate* delegate) {
// TODO(tengs): Fill in the notification fields based on the PhoneHub
// notification data.
message_center::NotifierId notifier_id(
message_center::NotifierType::SYSTEM_COMPONENT, kNotifierId);
auto notification_type = message_center::NOTIFICATION_TYPE_SIMPLE;
base::string16 title = notification->title().value_or(base::string16());
base::string16 message =
notification->text_content().value_or(base::string16());
gfx::Image icon;
message_center::NotifierId notifier_id(
message_center::NotifierType::SYSTEM_COMPONENT, kNotifierId);
auto app_metadata = notification->app_metadata();
base::string16 display_source = app_metadata.visible_app_name;
message_center::RichNotificationData optional_fields;
optional_fields.small_image = app_metadata.icon;
optional_fields.timestamp = notification->timestamp();
auto shared_image = notification->shared_image();
if (shared_image.has_value()) {
optional_fields.image = shared_image.value();
notification_type = message_center::NOTIFICATION_TYPE_IMAGE;
}
const gfx::Image& icon = notification->contact_image().value_or(gfx::Image());
switch (notification->importance()) {
case chromeos::phonehub::Notification::Importance::kNone:
FALLTHROUGH;
case chromeos::phonehub::Notification::Importance::kLow:
optional_fields.priority = message_center::MIN_PRIORITY;
break;
case chromeos::phonehub::Notification::Importance::kUnspecified:
FALLTHROUGH;
case chromeos::phonehub::Notification::Importance::kMin:
FALLTHROUGH;
case chromeos::phonehub::Notification::Importance::kDefault:
optional_fields.priority = message_center::LOW_PRIORITY;
break;
case chromeos::phonehub::Notification::Importance::kHigh:
optional_fields.priority = message_center::MAX_PRIORITY;
break;
}
message_center::ButtonInfo reply_button;
reply_button.title = l10n_util::GetStringUTF16(
IDS_ASH_PHONE_HUB_NOTIFICATION_INLINE_REPLY_BUTTON);
reply_button.placeholder = base::string16();
optional_fields.buttons.push_back(reply_button);
message_center::ButtonInfo cancel_button;
cancel_button.title = l10n_util::GetStringUTF16(
IDS_ASH_PHONE_HUB_NOTIFICATION_INLINE_CANCEL_BUTTON);
optional_fields.buttons.push_back(cancel_button);
optional_fields.settings_button_handler =
message_center::SettingsButtonHandler::DELEGATE;
return std::make_unique<message_center::Notification>(
notification_type, cros_id, title, message, icon,
/*display_source=*/base::string16(),
notification_type, cros_id, title, message, icon, display_source,
/*origin_url=*/GURL(), notifier_id, optional_fields,
delegate->AsScopedRefPtr());
}
......
......@@ -13,7 +13,9 @@
#include "chromeos/components/phonehub/fake_notification_manager.h"
#include "chromeos/components/phonehub/notification.h"
#include "chromeos/constants/chromeos_features.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/events/event.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/message_center/message_center.h"
namespace ash {
......@@ -170,4 +172,66 @@ TEST_F(PhoneHubNotificationControllerTest, ClickSettings) {
// TODO(tengs): Test this case once it is implemented.
}
TEST_F(PhoneHubNotificationControllerTest, CancelReply) {
chromeos::phonehub::Notification fake_notification(
kPhoneHubNotificationId0,
chromeos::phonehub::Notification::AppMetadata(base::UTF8ToUTF16(kAppName),
kPackageName,
/*icon=*/gfx::Image()),
base::Time::Now(), chromeos::phonehub::Notification::Importance::kDefault,
/*inline_reply_id=*/1, base::UTF8ToUTF16(kTitle),
base::UTF8ToUTF16(kTextContent));
notification_manager_.SetNotification(fake_notification);
auto* cros_notification =
message_center_->FindVisibleNotificationById(kCrOSNotificationId0);
ASSERT_TRUE(cros_notification);
EXPECT_EQ(2u, cros_notification->buttons().size());
message_center_->ClickOnNotificationButton(kCrOSNotificationId0, 1);
EXPECT_EQ(0u, message_center_->NotificationCount());
}
TEST_F(PhoneHubNotificationControllerTest, NotificationDataAndImages) {
base::Time timestamp = base::Time::FromJsTime(12345);
SkBitmap icon_bitmap;
icon_bitmap.allocN32Pixels(32, 32);
gfx::Image icon(gfx::ImageSkia::CreateFrom1xBitmap(icon_bitmap));
SkBitmap contact_image_bitmap;
contact_image_bitmap.allocN32Pixels(80, 80);
gfx::Image contact_image(
gfx::ImageSkia::CreateFrom1xBitmap(contact_image_bitmap));
SkBitmap shared_image_bitmap;
shared_image_bitmap.allocN32Pixels(400, 300);
gfx::Image shared_image(
gfx::ImageSkia::CreateFrom1xBitmap(shared_image_bitmap));
chromeos::phonehub::Notification fake_notification(
kPhoneHubNotificationId0,
chromeos::phonehub::Notification::AppMetadata(base::UTF8ToUTF16(kAppName),
kPackageName, icon),
timestamp, chromeos::phonehub::Notification::Importance::kHigh,
/*inline_reply_id=*/0, base::UTF8ToUTF16(kTitle),
base::UTF8ToUTF16(kTextContent), shared_image, contact_image);
notification_manager_.SetNotification(fake_notification);
auto* cros_notification =
message_center_->FindVisibleNotificationById(kCrOSNotificationId0);
ASSERT_TRUE(cros_notification);
EXPECT_EQ(timestamp, cros_notification->timestamp());
EXPECT_EQ(message_center::MAX_PRIORITY, cros_notification->priority());
EXPECT_EQ(kTitle, base::UTF16ToUTF8(cros_notification->title()));
EXPECT_EQ(kAppName, base::UTF16ToUTF8(cros_notification->display_source()));
// Note that there's a slight discrepancy between the PhoneHub and
// notification image naming.
EXPECT_EQ(contact_image, cros_notification->icon());
EXPECT_EQ(icon, cros_notification->small_image());
EXPECT_EQ(shared_image, cros_notification->image());
}
} // namespace ash
......@@ -19,6 +19,10 @@ namespace multidevice {
namespace {
const int kIconSize = 16;
const int kContactImageSize = 80;
const int kSharedImageSize = 400;
// Fake image types used for fields that require gfx::Image().
enum class ImageType {
kPink = 1,
......@@ -28,24 +32,24 @@ enum class ImageType {
kYellow = 5,
};
const SkBitmap ImageTypeToBitmap(ImageType image_type_num) {
const SkBitmap ImageTypeToBitmap(ImageType image_type_num, int size) {
SkBitmap bitmap;
bitmap.allocN32Pixels(16, 16);
bitmap.allocN32Pixels(size, size);
switch (image_type_num) {
case ImageType::kPink:
bitmap.eraseARGB(0, 255, 192, 203);
bitmap.eraseARGB(255, 255, 192, 203);
break;
case ImageType::kRed:
bitmap.eraseARGB(0, 255, 0, 0);
bitmap.eraseARGB(255, 255, 0, 0);
break;
case ImageType::kGreen:
bitmap.eraseARGB(0, 0, 255, 0);
bitmap.eraseARGB(255, 0, 255, 0);
break;
case ImageType::kBlue:
bitmap.eraseARGB(0, 0, 0, 255);
bitmap.eraseARGB(255, 0, 0, 255);
break;
case ImageType::kYellow:
bitmap.eraseARGB(0, 255, 255, 0);
bitmap.eraseARGB(255, 255, 255, 0);
break;
default:
break;
......@@ -65,8 +69,8 @@ phonehub::Notification::AppMetadata DictToAppMetadata(
CHECK(app_metadata_dict->GetInteger("icon", &icon_image_type_as_int));
auto icon_image_type = static_cast<ImageType>(icon_image_type_as_int);
gfx::Image icon =
gfx::Image::CreateFrom1xBitmap(ImageTypeToBitmap(icon_image_type));
gfx::Image icon = gfx::Image::CreateFrom1xBitmap(
ImageTypeToBitmap(icon_image_type, kIconSize));
return phonehub::Notification::AppMetadata(visible_app_name, package_name,
icon);
}
......@@ -103,8 +107,8 @@ void TryAddingMetadata(
}
auto favicon_image_type = static_cast<ImageType>(favicon_image_type_as_int);
gfx::Image favicon =
gfx::Image::CreateFrom1xBitmap(ImageTypeToBitmap(favicon_image_type));
gfx::Image favicon = gfx::Image::CreateFrom1xBitmap(
ImageTypeToBitmap(favicon_image_type, kIconSize));
auto metadata = phonehub::BrowserTabsModel::BrowserTabMetadata(
GURL(url), title, base::Time::FromJsTime(last_accessed_timestamp),
......@@ -378,8 +382,8 @@ void MultidevicePhoneHubHandler::HandleSetNotification(
&shared_image_type_as_int) &&
shared_image_type_as_int) {
auto shared_image_type = static_cast<ImageType>(shared_image_type_as_int);
opt_shared_image =
gfx::Image::CreateFrom1xBitmap(ImageTypeToBitmap(shared_image_type));
opt_shared_image = gfx::Image::CreateFrom1xBitmap(
ImageTypeToBitmap(shared_image_type, kSharedImageSize));
}
base::Optional<gfx::Image> opt_contact_image;
......@@ -390,7 +394,7 @@ void MultidevicePhoneHubHandler::HandleSetNotification(
auto shared_contact_image_type =
static_cast<ImageType>(contact_image_type_as_int);
opt_contact_image = gfx::Image::CreateFrom1xBitmap(
ImageTypeToBitmap(shared_contact_image_type));
ImageTypeToBitmap(shared_contact_image_type, kContactImageSize));
}
auto notification = phonehub::Notification(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment