OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 #include "chrome/browser/notifications/notification_platform_bridge_linux.h" | 5 #include "chrome/browser/notifications/notification_platform_bridge_linux.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <memory> | 8 #include <memory> |
9 #include <set> | 9 #include <set> |
10 #include <unordered_map> | 10 #include <unordered_map> |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "base/task_scheduler/post_task.h" | 24 #include "base/task_scheduler/post_task.h" |
25 #include "base/version.h" | 25 #include "base/version.h" |
26 #include "chrome/browser/browser_process.h" | 26 #include "chrome/browser/browser_process.h" |
27 #include "chrome/browser/chrome_notification_types.h" | 27 #include "chrome/browser/chrome_notification_types.h" |
28 #include "chrome/browser/notifications/native_notification_display_service.h" | 28 #include "chrome/browser/notifications/native_notification_display_service.h" |
29 #include "chrome/browser/notifications/notification.h" | 29 #include "chrome/browser/notifications/notification.h" |
30 #include "chrome/browser/notifications/notification_display_service_factory.h" | 30 #include "chrome/browser/notifications/notification_display_service_factory.h" |
31 #include "chrome/browser/profiles/profile_manager.h" | 31 #include "chrome/browser/profiles/profile_manager.h" |
32 #include "chrome/browser/shell_integration_linux.h" | 32 #include "chrome/browser/shell_integration_linux.h" |
33 #include "chrome/grit/generated_resources.h" | 33 #include "chrome/grit/generated_resources.h" |
34 #include "components/url_formatter/elide_url.h" | |
34 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
35 #include "content/public/browser/notification_service.h" | 36 #include "content/public/browser/notification_service.h" |
36 #include "dbus/bus.h" | 37 #include "dbus/bus.h" |
37 #include "dbus/message.h" | 38 #include "dbus/message.h" |
38 #include "dbus/object_proxy.h" | 39 #include "dbus/object_proxy.h" |
39 #include "skia/ext/image_operations.h" | 40 #include "skia/ext/image_operations.h" |
40 #include "ui/base/l10n/l10n_util.h" | 41 #include "ui/base/l10n/l10n_util.h" |
41 #include "ui/gfx/image/image_skia.h" | 42 #include "ui/gfx/image/image_skia.h" |
42 | 43 |
43 namespace { | 44 namespace { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 return title; | 121 return title; |
121 } | 122 } |
122 | 123 |
123 gfx::Image DeepCopyImage(const gfx::Image& image) { | 124 gfx::Image DeepCopyImage(const gfx::Image& image) { |
124 if (image.IsEmpty()) | 125 if (image.IsEmpty()) |
125 return gfx::Image(); | 126 return gfx::Image(); |
126 std::unique_ptr<gfx::ImageSkia> image_skia(image.CopyImageSkia()); | 127 std::unique_ptr<gfx::ImageSkia> image_skia(image.CopyImageSkia()); |
127 return gfx::Image(*image_skia); | 128 return gfx::Image(*image_skia); |
128 } | 129 } |
129 | 130 |
131 void EscapeBodyText(std::string* text) { | |
132 base::ReplaceSubstringsAfterOffset(text, 0, "&", "&"); | |
133 base::ReplaceSubstringsAfterOffset(text, 0, "<", "<"); | |
134 base::ReplaceSubstringsAfterOffset(text, 0, ">", ">"); | |
135 } | |
136 | |
130 int NotificationPriorityToFdoUrgency(int priority) { | 137 int NotificationPriorityToFdoUrgency(int priority) { |
131 enum FdoUrgency { | 138 enum FdoUrgency { |
132 LOW = 0, | 139 LOW = 0, |
133 NORMAL = 1, | 140 NORMAL = 1, |
134 CRITICAL = 2, | 141 CRITICAL = 2, |
135 }; | 142 }; |
136 switch (priority) { | 143 switch (priority) { |
137 case message_center::MIN_PRIORITY: | 144 case message_center::MIN_PRIORITY: |
138 case message_center::LOW_PRIORITY: | 145 case message_center::LOW_PRIORITY: |
139 return LOW; | 146 return LOW; |
140 case message_center::HIGH_PRIORITY: | 147 case message_center::HIGH_PRIORITY: |
141 case message_center::MAX_PRIORITY: | 148 case message_center::MAX_PRIORITY: |
142 return CRITICAL; | 149 return CRITICAL; |
143 default: | 150 default: |
144 NOTREACHED(); | 151 NOTREACHED(); |
145 case message_center::DEFAULT_PRIORITY: | 152 case message_center::DEFAULT_PRIORITY: |
146 return NORMAL; | 153 return NORMAL; |
147 } | 154 } |
148 } | 155 } |
149 | 156 |
150 // Constrain |image|'s size to |kMaxImageWidth|x|kMaxImageHeight|. If | 157 // Constrain |image|'s size to |kMaxImageWidth|x|kMaxImageHeight|. If |
151 // the image does not need to be resized, or the image is empty, | 158 // the image does not need to be resized, or the image is empty, |
152 // returns |image| directly. | 159 // returns |image| directly. |
153 gfx::Image ResizeImageToFdoMaxSize(const gfx::Image& image) { | 160 gfx::Image ResizeImageToFdoMaxSize(const gfx::Image& image) { |
161 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
154 if (image.IsEmpty()) | 162 if (image.IsEmpty()) |
155 return image; | 163 return image; |
156 int width = image.Width(); | 164 int width = image.Width(); |
157 int height = image.Height(); | 165 int height = image.Height(); |
158 if (width <= kMaxImageWidth && height <= kMaxImageHeight) { | 166 if (width <= kMaxImageWidth && height <= kMaxImageHeight) { |
159 return image; | 167 return image; |
160 } | 168 } |
161 const SkBitmap* image_bitmap = image.ToSkBitmap(); | 169 const SkBitmap* image_bitmap = image.ToSkBitmap(); |
162 double scale = std::min(static_cast<double>(kMaxImageWidth) / width, | 170 double scale = std::min(static_cast<double>(kMaxImageWidth) / width, |
163 static_cast<double>(kMaxImageHeight) / height); | 171 static_cast<double>(kMaxImageHeight) / height); |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 // app_icon passed implicitly via desktop-entry. | 535 // app_icon passed implicitly via desktop-entry. |
528 writer.AppendString(""); | 536 writer.AppendString(""); |
529 | 537 |
530 writer.AppendString( | 538 writer.AppendString( |
531 base::UTF16ToUTF8(CreateNotificationTitle(*notification))); | 539 base::UTF16ToUTF8(CreateNotificationTitle(*notification))); |
532 | 540 |
533 StringStreamSizable body; | 541 StringStreamSizable body; |
534 if (base::ContainsKey(capabilities_, kCapabilityBody)) { | 542 if (base::ContainsKey(capabilities_, kCapabilityBody)) { |
535 const bool body_markup = | 543 const bool body_markup = |
536 base::ContainsKey(capabilities_, kCapabilityBodyMarkup); | 544 base::ContainsKey(capabilities_, kCapabilityBodyMarkup); |
545 | |
546 if (notification->UseOriginAsContextMessage()) { | |
547 std::string url_display_text = | |
548 base::UTF16ToUTF8(url_formatter::FormatUrlForSecurityDisplay( | |
549 notification->origin_url(), | |
550 url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)); | |
551 std::string spec = notification->origin_url().spec(); | |
Lei Zhang
2017/05/15 22:19:59
Do we know if the origin URL is guaranteed to be v
Peter Beverloo
2017/05/15 22:43:26
Yes. UseOriginAsContextMessage() verifies this.
| |
552 if (base::ContainsKey(capabilities_, kCapabilityBodyHyperlinks)) { | |
553 body << "<a href=\"" << spec << "\">" << url_display_text << "</a>"; | |
554 } else { | |
555 body << url_display_text; | |
556 } | |
557 } else if (!notification->context_message().empty()) { | |
558 std::string context = | |
559 base::UTF16ToUTF8(notification->context_message()); | |
560 if (body_markup) | |
561 EscapeBodyText(&context); | |
Peter Beverloo
2017/05/15 22:43:26
Is it possible for |body_markup| to be FALSE but k
Tom (Use chromium acct)
2017/05/16 04:43:34
no. body-hyperlinks => body-markup
| |
562 body << context; | |
563 } | |
564 | |
537 std::string message = base::UTF16ToUTF8(notification->message()); | 565 std::string message = base::UTF16ToUTF8(notification->message()); |
538 if (body_markup) { | 566 if (body_markup) |
539 base::ReplaceSubstringsAfterOffset(&message, 0, "&", "&"); | 567 EscapeBodyText(&message); |
540 base::ReplaceSubstringsAfterOffset(&message, 0, "<", "<"); | 568 if (body.size()) |
541 base::ReplaceSubstringsAfterOffset(&message, 0, ">", ">"); | 569 body << "\n"; |
542 } | |
543 body << message; | 570 body << message; |
544 | 571 |
545 if (notification->type() == message_center::NOTIFICATION_TYPE_MULTIPLE) { | 572 if (notification->type() == message_center::NOTIFICATION_TYPE_MULTIPLE) { |
546 for (const auto& item : notification->items()) { | 573 for (const auto& item : notification->items()) { |
547 if (body.size()) | 574 if (body.size()) |
548 body << "\n"; | 575 body << "\n"; |
549 const std::string title = base::UTF16ToUTF8(item.title); | 576 const std::string title = base::UTF16ToUTF8(item.title); |
550 const std::string message = base::UTF16ToUTF8(item.message); | 577 const std::string message = base::UTF16ToUTF8(item.message); |
551 // TODO(peter): Figure out the right way to internationalize | 578 // TODO(peter): Figure out the right way to internationalize |
552 // this for RTL languages. | 579 // this for RTL languages. |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
920 } | 947 } |
921 | 948 |
922 void NotificationPlatformBridgeLinux::SetReadyCallback( | 949 void NotificationPlatformBridgeLinux::SetReadyCallback( |
923 NotificationBridgeReadyCallback callback) { | 950 NotificationBridgeReadyCallback callback) { |
924 impl_->SetReadyCallback(std::move(callback)); | 951 impl_->SetReadyCallback(std::move(callback)); |
925 } | 952 } |
926 | 953 |
927 void NotificationPlatformBridgeLinux::CleanUp() { | 954 void NotificationPlatformBridgeLinux::CleanUp() { |
928 impl_->CleanUp(); | 955 impl_->CleanUp(); |
929 } | 956 } |
OLD | NEW |