Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(527)

Side by Side Diff: chrome/browser/notifications/notification_conversion_helper.cc

Issue 2659533003: Remove the notificationProvider extension API (Closed)
Patch Set: Remove the notificationProvider extension API Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/notifications/notification_conversion_helper.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14
15 #include "base/logging.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/common/extensions/api/notification_provider.h"
18 #include "chrome/common/extensions/api/notifications/notification_style.h"
19 #include "ui/gfx/image/image_skia.h"
20 #include "ui/gfx/image/image_skia_rep.h"
21 #include "ui/gfx/skia_util.h"
22
23 void NotificationConversionHelper::NotificationToNotificationOptions(
24 const Notification& notification,
25 extensions::api::notifications::NotificationOptions* options) {
26 // Extract required fields: type, title, message, and icon.
27 std::string type = MapTypeToString(notification.type());
28 options->type = extensions::api::notifications::ParseTemplateType(type);
29
30 if (!notification.icon().IsEmpty()) {
31 std::unique_ptr<extensions::api::notifications::NotificationBitmap> icon(
32 new extensions::api::notifications::NotificationBitmap());
33 GfxImageToNotificationBitmap(&notification.icon(), icon.get());
34 options->icon_bitmap = std::move(icon);
35 }
36
37 options->title.reset(
38 new std::string(base::UTF16ToUTF8(notification.title())));
39 options->message.reset(
40 new std::string(base::UTF16ToUTF8(notification.message())));
41
42 // Handle optional data provided.
43 const message_center::RichNotificationData* rich_data =
44 &notification.rich_notification_data();
45
46 if (!rich_data->small_image.IsEmpty()) {
47 std::unique_ptr<extensions::api::notifications::NotificationBitmap>
48 icon_mask(new extensions::api::notifications::NotificationBitmap());
49 GfxImageToNotificationBitmap(&rich_data->small_image, icon_mask.get());
50 options->app_icon_mask_bitmap = std::move(icon_mask);
51 }
52
53 options->priority.reset(new int(rich_data->priority));
54
55 options->is_clickable.reset(new bool(rich_data->clickable));
56
57 options->event_time.reset(new double(rich_data->timestamp.ToDoubleT()));
58
59 if (!rich_data->context_message.empty())
60 options->context_message.reset(
61 new std::string(base::UTF16ToUTF8(rich_data->context_message)));
62
63 if (!rich_data->buttons.empty()) {
64 options->buttons.reset(
65 new std::vector<extensions::api::notifications::NotificationButton>());
66 for (const message_center::ButtonInfo& button_info : rich_data->buttons) {
67 extensions::api::notifications::NotificationButton button;
68 button.title = base::UTF16ToUTF8(button_info.title);
69
70 if (!button_info.icon.IsEmpty()) {
71 std::unique_ptr<extensions::api::notifications::NotificationBitmap>
72 icon(new extensions::api::notifications::NotificationBitmap());
73 GfxImageToNotificationBitmap(&button_info.icon, icon.get());
74 button.icon_bitmap = std::move(icon);
75 }
76 options->buttons->push_back(std::move(button));
77 }
78 }
79
80 // Only image type notifications should have images.
81 if (type == "image" && !rich_data->image.IsEmpty()) {
82 std::unique_ptr<extensions::api::notifications::NotificationBitmap> image(
83 new extensions::api::notifications::NotificationBitmap());
84 GfxImageToNotificationBitmap(&notification.image(), image.get());
85 options->image_bitmap = std::move(image);
86 } else if (type != "image" && !rich_data->image.IsEmpty()) {
87 DVLOG(1) << "Only image type notifications should have images.";
88 }
89
90 // Only progress type notifications should have progress bars.
91 if (type == "progress")
92 options->progress.reset(new int(rich_data->progress));
93 else if (rich_data->progress != 0)
94 DVLOG(1) << "Only progress type notifications should have progress.";
95
96 // Only list type notifications should have lists.
97 if (type == "list" && !rich_data->items.empty()) {
98 options->items.reset(
99 new std::vector<extensions::api::notifications::NotificationItem>());
100 for (const message_center::NotificationItem& item : rich_data->items) {
101 extensions::api::notifications::NotificationItem api_item;
102 api_item.title = base::UTF16ToUTF8(item.title);
103 api_item.message = base::UTF16ToUTF8(item.message);
104 options->items->push_back(std::move(api_item));
105 }
106 } else if (type != "list" && !rich_data->items.empty()) {
107 DVLOG(1) << "Only list type notifications should have lists.";
108 }
109 }
110
111 void NotificationConversionHelper::GfxImageToNotificationBitmap(
112 const gfx::Image* gfx_image,
113 extensions::api::notifications::NotificationBitmap* notification_bitmap) {
114 SkBitmap sk_bitmap = gfx_image->AsBitmap();
115 sk_bitmap.lockPixels();
116
117 notification_bitmap->width = sk_bitmap.width();
118 notification_bitmap->height = sk_bitmap.height();
119 int pixel_count = sk_bitmap.width() * sk_bitmap.height();
120 const int BYTES_PER_PIXEL = 4;
121
122 uint32_t* bitmap_pixels = sk_bitmap.getAddr32(0, 0);
123 const unsigned char* bitmap =
124 reinterpret_cast<const unsigned char*>(bitmap_pixels);
125 std::unique_ptr<std::vector<char>> rgba_bitmap_data(
126 new std::vector<char>(pixel_count * BYTES_PER_PIXEL));
127
128 gfx::ConvertSkiaToRGBA(bitmap, pixel_count, reinterpret_cast<unsigned char*>(
129 rgba_bitmap_data->data()));
130 sk_bitmap.unlockPixels();
131
132 notification_bitmap->data = std::move(rgba_bitmap_data);
133 return;
134 }
135
136 bool NotificationConversionHelper::NotificationBitmapToGfxImage(
137 float max_scale,
138 const gfx::Size& target_size_dips,
139 const extensions::api::notifications::NotificationBitmap&
140 notification_bitmap,
141 gfx::Image* return_image) {
142 const int max_device_pixel_width = target_size_dips.width() * max_scale;
143 const int max_device_pixel_height = target_size_dips.height() * max_scale;
144
145 const int BYTES_PER_PIXEL = 4;
146
147 const int width = notification_bitmap.width;
148 const int height = notification_bitmap.height;
149
150 if (width < 0 || height < 0 || width > max_device_pixel_width ||
151 height > max_device_pixel_height)
152 return false;
153
154 // Ensure we have rgba data.
155 std::vector<char>* rgba_data = notification_bitmap.data.get();
156 if (!rgba_data)
157 return false;
158
159 const size_t rgba_data_length = rgba_data->size();
160 const size_t rgba_area = width * height;
161
162 if (rgba_data_length != rgba_area * BYTES_PER_PIXEL)
163 return false;
164
165 SkBitmap bitmap;
166 // Allocate the actual backing store with the sanitized dimensions.
167 if (!bitmap.tryAllocN32Pixels(width, height))
168 return false;
169
170 // Ensure that our bitmap and our data now refer to the same number of pixels.
171 if (rgba_data_length != bitmap.getSafeSize())
172 return false;
173
174 uint32_t* pixels = bitmap.getAddr32(0, 0);
175 const char* c_rgba_data = rgba_data->data();
176
177 for (size_t t = 0; t < rgba_area; ++t) {
178 // |c_rgba_data| is RGBA, pixels is ARGB.
179 size_t rgba_index = t * BYTES_PER_PIXEL;
180 pixels[t] =
181 SkPreMultiplyColor(((c_rgba_data[rgba_index + 3] & 0xFF) << 24) |
182 ((c_rgba_data[rgba_index + 0] & 0xFF) << 16) |
183 ((c_rgba_data[rgba_index + 1] & 0xFF) << 8) |
184 ((c_rgba_data[rgba_index + 2] & 0xFF) << 0));
185 }
186
187 // TODO(dewittj): Handle HiDPI images with more than one scale factor
188 // representation.
189 gfx::ImageSkia skia(gfx::ImageSkiaRep(bitmap, 1.0f));
190 *return_image = gfx::Image(skia);
191 return true;
192 }
193
194 std::string NotificationConversionHelper::MapTypeToString(
195 message_center::NotificationType type) {
196 switch (type) {
197 case message_center::NOTIFICATION_TYPE_BASE_FORMAT:
198 return "basic";
199 case message_center::NOTIFICATION_TYPE_IMAGE:
200 return "image";
201 case message_center::NOTIFICATION_TYPE_MULTIPLE:
202 return "list";
203 case message_center::NOTIFICATION_TYPE_PROGRESS:
204 return "progress";
205 case message_center::NOTIFICATION_TYPE_CUSTOM:
206 return "custom";
207 default:
208 NOTREACHED();
209 return "";
210 }
211 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698