OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 #include "core/frame/UseCounter.h" | 44 #include "core/frame/UseCounter.h" |
45 #include "modules/notifications/NotificationOptions.h" | 45 #include "modules/notifications/NotificationOptions.h" |
46 #include "modules/notifications/NotificationPermissionClient.h" | 46 #include "modules/notifications/NotificationPermissionClient.h" |
47 #include "platform/RuntimeEnabledFeatures.h" | 47 #include "platform/RuntimeEnabledFeatures.h" |
48 #include "platform/UserGestureIndicator.h" | 48 #include "platform/UserGestureIndicator.h" |
49 #include "public/platform/Platform.h" | 49 #include "public/platform/Platform.h" |
50 #include "public/platform/WebSerializedOrigin.h" | 50 #include "public/platform/WebSerializedOrigin.h" |
51 #include "public/platform/WebString.h" | 51 #include "public/platform/WebString.h" |
52 #include "public/platform/modules/notifications/WebNotificationData.h" | 52 #include "public/platform/modules/notifications/WebNotificationData.h" |
53 #include "public/platform/modules/notifications/WebNotificationManager.h" | 53 #include "public/platform/modules/notifications/WebNotificationManager.h" |
| 54 #include "public/platform/modules/notifications/WebNotificationVibrationData.h" |
54 | 55 |
55 namespace blink { | 56 namespace blink { |
56 namespace { | 57 namespace { |
57 | 58 |
58 WebNotificationManager* notificationManager() | 59 WebNotificationManager* notificationManager() |
59 { | 60 { |
60 return Platform::current()->notificationManager(); | 61 return Platform::current()->notificationManager(); |
61 } | 62 } |
62 | 63 |
63 } // namespace | 64 } // namespace |
64 | 65 |
65 Notification* Notification::create(ExecutionContext* context, const String& titl
e, const NotificationOptions& options, ExceptionState& exceptionState) | 66 Notification* Notification::create(ExecutionContext* context, const String& titl
e, const NotificationOptions& options, ExceptionState& exceptionState) |
66 { | 67 { |
67 // The Web Notification constructor may be disabled through a runtime featur
e. The | 68 // The Web Notification constructor may be disabled through a runtime featur
e. The |
68 // behavior of the constructor is changing, but not completely agreed upon y
et. | 69 // behavior of the constructor is changing, but not completely agreed upon y
et. |
69 if (!RuntimeEnabledFeatures::notificationConstructorEnabled()) { | 70 if (!RuntimeEnabledFeatures::notificationConstructorEnabled()) { |
70 exceptionState.throwTypeError("Illegal constructor. Use ServiceWorkerReg
istration.showNotification() instead."); | 71 exceptionState.throwTypeError("Illegal constructor. Use ServiceWorkerReg
istration.showNotification() instead."); |
71 return nullptr; | 72 return nullptr; |
72 } | 73 } |
73 | 74 |
74 // The Web Notification constructor may not be used in Service Worker contex
ts. | 75 // The Web Notification constructor may not be used in Service Worker contex
ts. |
75 if (context->isServiceWorkerGlobalScope()) { | 76 if (context->isServiceWorkerGlobalScope()) { |
76 exceptionState.throwTypeError("Illegal constructor."); | 77 exceptionState.throwTypeError("Illegal constructor."); |
77 return nullptr; | 78 return nullptr; |
78 } | 79 } |
79 | 80 |
| 81 // If options’s silent is true, and options’s vibrate is present, throw a Ty
peError exception. |
| 82 if (options.hasVibrate() && options.silent()) { |
| 83 exceptionState.throwTypeError("If options's silent is true, options's vi
brate should not be presented"); |
| 84 return nullptr; |
| 85 } |
| 86 |
80 RefPtr<SerializedScriptValue> data; | 87 RefPtr<SerializedScriptValue> data; |
81 if (options.hasData()) { | 88 if (options.hasData()) { |
82 data = SerializedScriptValueFactory::instance().create(options.data(), n
ullptr, exceptionState, options.data().isolate()); | 89 data = SerializedScriptValueFactory::instance().create(options.data(), n
ullptr, exceptionState, options.data().isolate()); |
83 if (exceptionState.hadException()) | 90 if (exceptionState.hadException()) |
84 return nullptr; | 91 return nullptr; |
85 } | 92 } |
86 | 93 |
87 Notification* notification = new Notification(title, context); | 94 Notification* notification = new Notification(title, context); |
88 | 95 |
89 notification->setBody(options.body()); | 96 notification->setBody(options.body()); |
90 notification->setTag(options.tag()); | 97 notification->setTag(options.tag()); |
91 notification->setLang(options.lang()); | 98 notification->setLang(options.lang()); |
92 notification->setDir(options.dir()); | 99 notification->setDir(options.dir()); |
| 100 notification->setVibrate(options.vibrate()); |
93 notification->setSilent(options.silent()); | 101 notification->setSilent(options.silent()); |
94 notification->setSerializedData(data.release()); | 102 notification->setSerializedData(data.release()); |
95 if (options.hasIcon()) { | 103 if (options.hasIcon()) { |
96 KURL iconUrl = options.icon().isEmpty() ? KURL() : context->completeURL(
options.icon()); | 104 KURL iconUrl = options.icon().isEmpty() ? KURL() : context->completeURL(
options.icon()); |
97 if (!iconUrl.isEmpty() && iconUrl.isValid()) | 105 if (!iconUrl.isEmpty() && iconUrl.isValid()) |
98 notification->setIconUrl(iconUrl); | 106 notification->setIconUrl(iconUrl); |
99 } | 107 } |
100 | 108 |
101 String insecureOriginMessage; | 109 String insecureOriginMessage; |
102 UseCounter::Feature feature = context->securityOrigin()->canAccessFeatureReq
uiringSecureOrigin(insecureOriginMessage) | 110 UseCounter::Feature feature = context->securityOrigin()->canAccessFeatureReq
uiringSecureOrigin(insecureOriginMessage) |
103 ? UseCounter::NotificationSecureOrigin : UseCounter::NotificationInsecur
eOrigin; | 111 ? UseCounter::NotificationSecureOrigin : UseCounter::NotificationInsecur
eOrigin; |
104 UseCounter::count(context, feature); | 112 UseCounter::count(context, feature); |
105 | 113 |
106 notification->scheduleShow(); | 114 notification->scheduleShow(); |
107 notification->suspendIfNeeded(); | 115 notification->suspendIfNeeded(); |
108 return notification; | 116 return notification; |
109 } | 117 } |
110 | 118 |
111 Notification* Notification::create(ExecutionContext* context, const String& pers
istentId, const WebNotificationData& data) | 119 Notification* Notification::create(ExecutionContext* context, const String& pers
istentId, const WebNotificationData& data) |
112 { | 120 { |
113 Notification* notification = new Notification(data.title, context); | 121 Notification* notification = new Notification(data.title, context); |
114 | 122 |
115 notification->setPersistentId(persistentId); | 123 notification->setPersistentId(persistentId); |
116 notification->setDir(data.direction == WebNotificationData::DirectionLeftToR
ight ? "ltr" : "rtl"); | 124 notification->setDir(data.direction == WebNotificationData::DirectionLeftToR
ight ? "ltr" : "rtl"); |
117 notification->setLang(data.lang); | 125 notification->setLang(data.lang); |
118 notification->setBody(data.body); | 126 notification->setBody(data.body); |
119 notification->setTag(data.tag); | 127 notification->setTag(data.tag); |
120 notification->setSilent(data.silent); | 128 notification->setSilent(data.silent); |
121 | 129 |
| 130 if (data.vibrate.type == WebNotificationVibrationData::TypeUnsignedLong) { |
| 131 notification->setVibrate(UnsignedLongOrUnsignedLongSequence::fromUnsigne
dLong(data.vibrate.pattern[0])); |
| 132 } else if (data.vibrate.type == WebNotificationVibrationData::TypeUnsignedLo
ngSequence) { |
| 133 Vector<unsigned> pattern; |
| 134 pattern.appendRange(data.vibrate.pattern.begin(), data.vibrate.pattern.e
nd()); |
| 135 notification->setVibrate(UnsignedLongOrUnsignedLongSequence::fromUnsigne
dLongSequence(pattern)); |
| 136 } |
| 137 |
122 if (!data.icon.isEmpty()) | 138 if (!data.icon.isEmpty()) |
123 notification->setIconUrl(data.icon); | 139 notification->setIconUrl(data.icon); |
124 | 140 |
125 if (!data.data.isEmpty()) { | 141 if (!data.data.isEmpty()) { |
126 notification->setSerializedData(SerializedScriptValueFactory::instance()
.createFromWire(data.data)); | 142 notification->setSerializedData(SerializedScriptValueFactory::instance()
.createFromWire(data.data)); |
127 notification->serializedData()->registerMemoryAllocatedWithCurrentScript
Context(); | 143 notification->serializedData()->registerMemoryAllocatedWithCurrentScript
Context(); |
128 } | 144 } |
129 | 145 |
130 notification->setState(NotificationStateShowing); | 146 notification->setState(NotificationStateShowing); |
131 notification->suspendIfNeeded(); | 147 notification->suspendIfNeeded(); |
132 return notification; | 148 return notification; |
133 } | 149 } |
134 | 150 |
135 Notification::Notification(const String& title, ExecutionContext* context) | 151 Notification::Notification(const String& title, ExecutionContext* context) |
136 : ActiveDOMObject(context) | 152 : ActiveDOMObject(context) |
137 , m_title(title) | 153 , m_title(title) |
138 , m_dir("auto") | 154 , m_dir("auto") |
139 , m_silent(false) | 155 , m_silent(false) |
140 , m_state(NotificationStateIdle) | 156 , m_state(NotificationStateIdle) |
141 , m_asyncRunner(this, &Notification::show) | 157 , m_asyncRunner(this, &Notification::show) |
142 { | 158 { |
143 ASSERT(notificationManager()); | 159 ASSERT(notificationManager()); |
144 } | 160 } |
145 | 161 |
146 Notification::~Notification() | 162 Notification::~Notification() |
147 { | 163 { |
148 } | 164 } |
149 | 165 |
| 166 void Notification::vibrate(UnsignedLongOrUnsignedLongSequence& returnValue) |
| 167 { |
| 168 if (m_vibrate.isNull()) |
| 169 return; |
| 170 |
| 171 if (m_vibrate.isUnsignedLong()) |
| 172 returnValue.setUnsignedLong(m_vibrate.getAsUnsignedLong()); |
| 173 else |
| 174 returnValue.setUnsignedLongSequence(m_vibrate.getAsUnsignedLongSequence(
)); |
| 175 } |
| 176 |
150 void Notification::scheduleShow() | 177 void Notification::scheduleShow() |
151 { | 178 { |
152 ASSERT(m_state == NotificationStateIdle); | 179 ASSERT(m_state == NotificationStateIdle); |
153 ASSERT(!m_asyncRunner.isActive()); | 180 ASSERT(!m_asyncRunner.isActive()); |
154 | 181 |
155 m_asyncRunner.runAsync(); | 182 m_asyncRunner.runAsync(); |
156 } | 183 } |
157 | 184 |
158 void Notification::show() | 185 void Notification::show() |
159 { | 186 { |
160 ASSERT(m_state == NotificationStateIdle); | 187 ASSERT(m_state == NotificationStateIdle); |
161 if (Notification::checkPermission(executionContext()) != WebNotificationPerm
issionAllowed) { | 188 if (Notification::checkPermission(executionContext()) != WebNotificationPerm
issionAllowed) { |
162 dispatchErrorEvent(); | 189 dispatchErrorEvent(); |
163 return; | 190 return; |
164 } | 191 } |
165 | 192 |
166 SecurityOrigin* origin = executionContext()->securityOrigin(); | 193 SecurityOrigin* origin = executionContext()->securityOrigin(); |
167 ASSERT(origin); | 194 ASSERT(origin); |
168 | 195 |
169 // FIXME: Do CSP checks on the associated notification icon. | 196 // FIXME: Do CSP checks on the associated notification icon. |
170 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D
irectionRightToLeft : WebNotificationData::DirectionLeftToRight; | 197 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D
irectionRightToLeft : WebNotificationData::DirectionLeftToRight; |
171 | 198 |
172 // The lifetime and availability of non-persistent notifications is tied to
the page | 199 // The lifetime and availability of non-persistent notifications is tied to
the page |
173 // they were created by, and thus the data doesn't have to be known to the e
mbedder. | 200 // they were created by, and thus the data doesn't have to be known to the e
mbedder. |
174 String emptyDataAsWireString; | 201 String emptyDataAsWireString; |
175 WebNotificationData notificationData(m_title, dir, m_lang, m_body, m_tag, m_
iconUrl, m_silent, emptyDataAsWireString); | 202 WebNotificationData notificationData(m_title, dir, m_lang, m_body, m_tag, m_
iconUrl, convertFromVibrationData(m_vibrate), m_silent, emptyDataAsWireString); |
176 notificationManager()->show(WebSerializedOrigin(*origin), notificationData,
this); | 203 notificationManager()->show(WebSerializedOrigin(*origin), notificationData,
this); |
177 | 204 |
178 m_state = NotificationStateShowing; | 205 m_state = NotificationStateShowing; |
179 } | 206 } |
180 | 207 |
181 void Notification::close() | 208 void Notification::close() |
182 { | 209 { |
183 if (m_state != NotificationStateShowing) | 210 if (m_state != NotificationStateShowing) |
184 return; | 211 return; |
185 | 212 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 } | 322 } |
296 | 323 |
297 ScriptValue Notification::data(ScriptState* scriptState) const | 324 ScriptValue Notification::data(ScriptState* scriptState) const |
298 { | 325 { |
299 if (!m_serializedData) | 326 if (!m_serializedData) |
300 return ScriptValue::createNull(scriptState); | 327 return ScriptValue::createNull(scriptState); |
301 | 328 |
302 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i
solate())); | 329 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i
solate())); |
303 } | 330 } |
304 | 331 |
| 332 WebNotificationVibrationData Notification::convertFromVibrationData(const Unsign
edLongOrUnsignedLongSequence& vibrate) |
| 333 { |
| 334 WebNotificationVibrationData::Type vibrateType = WebNotificationVibrationDat
a::TypeNone; |
| 335 Vector<unsigned> vibratePattern; |
| 336 |
| 337 if (vibrate.isUnsignedLong()) { |
| 338 vibrateType = WebNotificationVibrationData::TypeUnsignedLong; |
| 339 vibratePattern.append(vibrate.getAsUnsignedLong()); |
| 340 } else if (vibrate.isUnsignedLongSequence()) { |
| 341 vibrateType = WebNotificationVibrationData::TypeUnsignedLongSequence; |
| 342 vibratePattern = vibrate.getAsUnsignedLongSequence(); |
| 343 } |
| 344 |
| 345 return WebNotificationVibrationData(vibrateType, vibratePattern); |
| 346 } |
| 347 |
| 348 |
305 DEFINE_TRACE(Notification) | 349 DEFINE_TRACE(Notification) |
306 { | 350 { |
307 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis
itor); | 351 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis
itor); |
308 ActiveDOMObject::trace(visitor); | 352 ActiveDOMObject::trace(visitor); |
309 } | 353 } |
310 | 354 |
311 } // namespace blink | 355 } // namespace blink |
OLD | NEW |