vfs: check userland buffers before reading them.
[haiku.git] / src / kits / app / Notification.cpp
blobcac84b2218fd71b59ca511c26d9c64b90e1cdb93
1 /*
2 * Copyright 2010-2017, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
7 * Stephan Aßmus, superstippi@gmx.de
8 * Brian Hill, supernova@tycho.email
9 */
12 #include <Notification.h>
14 #include <new>
16 #include <stdlib.h>
17 #include <string.h>
19 #include <notification/Notifications.h>
21 #include <Bitmap.h>
22 #include <Message.h>
23 #include <NodeInfo.h>
24 #include <Path.h>
25 #include <Roster.h>
28 BNotification::BNotification(notification_type type)
30 BArchivable(),
31 fInitStatus(B_OK),
32 fType(type),
33 fProgress(0.f),
34 fFile(NULL),
35 fBitmap(NULL)
37 team_info teamInfo;
38 get_team_info(B_CURRENT_TEAM, &teamInfo);
39 app_info appInfo;
40 be_roster->GetRunningAppInfo(teamInfo.team, &appInfo);
42 int32 iconSize = B_LARGE_ICON;
43 fBitmap = new BBitmap(BRect(0, 0, iconSize - 1, iconSize - 1), 0, B_RGBA32);
44 if (fBitmap) {
45 if (BNodeInfo::GetTrackerIcon(&appInfo.ref, fBitmap,
46 icon_size(iconSize)) != B_OK) {
47 delete fBitmap;
48 fBitmap = NULL;
51 fSourceSignature = appInfo.signature;
52 BPath path(&appInfo.ref);
53 if (path.InitCheck() == B_OK)
54 fSourceName = path.Leaf();
58 BNotification::BNotification(BMessage* archive)
60 BArchivable(archive),
61 fInitStatus(B_OK),
62 fProgress(0.0f),
63 fFile(NULL),
64 fBitmap(NULL)
66 BString appName;
67 if (archive->FindString("_appname", &appName) == B_OK)
68 fSourceName = appName;
70 BString signature;
71 if (archive->FindString("_signature", &signature) == B_OK)
72 fSourceSignature = signature;
74 int32 type;
75 if (archive->FindInt32("_type", &type) == B_OK)
76 fType = (notification_type)type;
77 else
78 fInitStatus = B_ERROR;
80 BString group;
81 if (archive->FindString("_group", &group) == B_OK)
82 SetGroup(group);
84 BString title;
85 if (archive->FindString("_title", &title) == B_OK)
86 SetTitle(title);
88 BString content;
89 if (archive->FindString("_content", &content) == B_OK)
90 SetContent(content);
92 BString messageID;
93 if (archive->FindString("_messageID", &messageID) == B_OK)
94 SetMessageID(messageID);
96 float progress;
97 if (type == B_PROGRESS_NOTIFICATION
98 && archive->FindFloat("_progress", &progress) == B_OK)
99 SetProgress(progress);
101 BString onClickApp;
102 if (archive->FindString("_onClickApp", &onClickApp) == B_OK)
103 SetOnClickApp(onClickApp);
105 entry_ref onClickFile;
106 if (archive->FindRef("_onClickFile", &onClickFile) == B_OK)
107 SetOnClickFile(&onClickFile);
109 entry_ref onClickRef;
110 int32 index = 0;
111 while (archive->FindRef("_onClickRef", index++, &onClickRef) == B_OK)
112 AddOnClickRef(&onClickRef);
114 BString onClickArgv;
115 index = 0;
116 while (archive->FindString("_onClickArgv", index++, &onClickArgv) == B_OK)
117 AddOnClickArg(onClickArgv);
119 status_t ret = B_OK;
120 BMessage icon;
121 if ((ret = archive->FindMessage("_icon", &icon)) == B_OK) {
122 BBitmap bitmap(&icon);
123 ret = bitmap.InitCheck();
124 if (ret == B_OK)
125 ret = SetIcon(&bitmap);
130 BNotification::~BNotification()
132 delete fFile;
133 delete fBitmap;
135 for (int32 i = fRefs.CountItems() - 1; i >= 0; i--)
136 delete (entry_ref*)fRefs.ItemAtFast(i);
138 for (int32 i = fArgv.CountItems() - 1; i >= 0; i--)
139 free(fArgv.ItemAtFast(i));
143 /*! \brief Returns initialization status.
145 status_t
146 BNotification::InitCheck() const
148 return fInitStatus;
152 /*! \brief Returns a new BNotification object from @archive.
154 Returns a new BNotification object, allocated by new and created
155 with the version of the constructor that takes BMessage archive.
156 However, if the message doesn't contain an archived data for a
157 BNotification object, this method returns NULL.
159 \return BNotification object from @archive or NULL if it doesn't
160 contain a valid BNotification object.
162 BArchivable*
163 BNotification::Instantiate(BMessage* archive)
165 if (validate_instantiation(archive, "BNotification"))
166 return new(std::nothrow) BNotification(archive);
168 return NULL;
172 /*! \brief Archives the BNotification in the BMessages @archive.
174 \sa BArchivable::Archive(), Instantiate() static function.
175 \return
176 - \c B_OK: Everything went fine.
177 - \c Other errors: Archiving has failed.
179 status_t
180 BNotification::Archive(BMessage* archive, bool deep) const
182 status_t status = BArchivable::Archive(archive, deep);
184 if (status == B_OK)
185 status = archive->AddString("_appname", fSourceName);
187 if (status == B_OK)
188 status = archive->AddString("_signature", fSourceSignature);
190 if (status == B_OK)
191 status = archive->AddInt32("_type", (int32)fType);
193 if (status == B_OK && Group() != NULL)
194 status = archive->AddString("_group", Group());
196 if (status == B_OK && Title() != NULL)
197 status = archive->AddString("_title", Title());
199 if (status == B_OK && Content() != NULL)
200 status = archive->AddString("_content", Content());
202 if (status == B_OK && MessageID() != NULL)
203 status = archive->AddString("_messageID", MessageID());
205 if (status == B_OK && Type() == B_PROGRESS_NOTIFICATION)
206 status = archive->AddFloat("_progress", Progress());
208 if (status == B_OK && OnClickApp() != NULL)
209 status = archive->AddString("_onClickApp", OnClickApp());
211 if (status == B_OK && OnClickFile() != NULL)
212 status = archive->AddRef("_onClickFile", OnClickFile());
214 if (status == B_OK) {
215 for (int32 i = 0; i < CountOnClickRefs(); i++) {
216 status = archive->AddRef("_onClickRef", OnClickRefAt(i));
217 if (status != B_OK)
218 break;
222 if (status == B_OK) {
223 for (int32 i = 0; i < CountOnClickArgs(); i++) {
224 status = archive->AddString("_onClickArgv", OnClickArgAt(i));
225 if (status != B_OK)
226 break;
230 if (status == B_OK) {
231 const BBitmap* icon = Icon();
232 if (icon != NULL) {
233 BMessage iconArchive;
234 status = icon->Archive(&iconArchive);
235 if (status == B_OK)
236 archive->AddMessage("_icon", &iconArchive);
240 return status;
244 /*! \brief Returns source application signature.
246 \return Source application signature.
248 const char*
249 BNotification::SourceSignature() const
251 return fSourceSignature;
255 /*! \brief Returns source application name.
257 \return Source application name.
259 const char*
260 BNotification::SourceName() const
262 return fSourceName;
266 /*! \brief Notification's type.
268 \return A value of the notification_type enum that represents
269 notification type.
271 notification_type
272 BNotification::Type() const
274 return fType;
278 /*! \brief Returns notification's group.
280 \return Notification's group.
282 const char*
283 BNotification::Group() const
285 if (fGroup == "")
286 return NULL;
287 return fGroup;
291 /*! \brief Sets notification's group.
293 Notifications can be grouped together setting the same group.
295 void
296 BNotification::SetGroup(const BString& group)
298 fGroup = group;
302 /*! \brief Returns notification's title.
304 \return Notification's title.
306 const char*
307 BNotification::Title() const
309 if (fTitle == "")
310 return NULL;
311 return fTitle;
315 /*! \brief Set notification's title.
317 void
318 BNotification::SetTitle(const BString& title)
320 fTitle = title;
324 /*! \brief Returns notification's message.
326 \return Notification's message.
328 const char*
329 BNotification::Content() const
331 if (fContent == "")
332 return NULL;
333 return fContent;
337 /*! \brief Sets notification's message.
339 void
340 BNotification::SetContent(const BString& content)
342 fContent = content;
346 /*! \brief Returns notification's message identifier.
348 \return Notification's message identifier.
350 const char*
351 BNotification::MessageID() const
353 if (fID == "")
354 return NULL;
355 return fID;
359 /*! \brief Sets notification's message identifier.
361 void
362 BNotification::SetMessageID(const BString& id)
364 fID = id;
368 /*! \brief Returns progress information.
370 If notification's type is \c B_PROGRESS_NOTIFICATION, returns a value
371 between 0.0 and 1.0 that represent progress percentage.
373 If notification's type is not \c B_PROGRESS_NOTIFICATION, returns -1.
375 \return Percentage if notification's type is B_PROGRESS_NOTIFICATION
376 or otherwise -1.
378 float
379 BNotification::Progress() const
381 if (fType != B_PROGRESS_NOTIFICATION)
382 return -1;
383 return fProgress;
387 /*! \brief Sets progress information.
389 Sets progress percentage, this information will be used only
390 if notification's type is \c B_PROGRESS_NOTIFICATION.
392 The value of @progress must be between 0.0 and 1.0.
394 void
395 BNotification::SetProgress(float progress)
397 if (progress < 0)
398 fProgress = 0;
399 else if (progress > 1)
400 fProgress = 1;
401 else
402 fProgress = progress;
406 const char*
407 BNotification::OnClickApp() const
409 if (fApp == "")
410 return NULL;
411 return fApp;
415 void
416 BNotification::SetOnClickApp(const BString& app)
418 fApp = app;
422 const entry_ref*
423 BNotification::OnClickFile() const
425 return fFile;
429 status_t
430 BNotification::SetOnClickFile(const entry_ref* file)
432 delete fFile;
434 if (file != NULL) {
435 fFile = new(std::nothrow) entry_ref(*file);
436 if (fFile == NULL)
437 return B_NO_MEMORY;
438 } else
439 fFile = NULL;
441 return B_OK;
445 status_t
446 BNotification::AddOnClickRef(const entry_ref* ref)
448 if (ref == NULL)
449 return B_BAD_VALUE;
451 entry_ref* clonedRef = new(std::nothrow) entry_ref(*ref);
452 if (clonedRef == NULL || !fRefs.AddItem(clonedRef))
453 return B_NO_MEMORY;
455 return B_OK;
459 int32
460 BNotification::CountOnClickRefs() const
462 return fRefs.CountItems();
466 const entry_ref*
467 BNotification::OnClickRefAt(int32 index) const
469 return (entry_ref*)fArgv.ItemAt(index);
473 status_t
474 BNotification::AddOnClickArg(const BString& arg)
476 char* clonedArg = strdup(arg.String());
477 if (clonedArg == NULL || !fArgv.AddItem(clonedArg))
478 return B_NO_MEMORY;
480 return B_OK;
484 int32
485 BNotification::CountOnClickArgs() const
487 return fArgv.CountItems();
491 const char*
492 BNotification::OnClickArgAt(int32 index) const
494 return (char*)fArgv.ItemAt(index);
498 /*! \brief Notification's icon.
500 \return Notification's icon.
502 const BBitmap*
503 BNotification::Icon() const
505 return fBitmap;
509 /*! \brief Sets notification's icon.
511 Sets notification's icon.
512 This method does not assume ownership of @icon.
514 \param icon Icon
515 \return
516 - \c B_OK: Everything went fine.
517 - \c B_NO_MEMORY: Allocation of @icon copy has failed.
518 - \c Other errors: Creation of @icon copy failed for some reason.
520 status_t
521 BNotification::SetIcon(const BBitmap* icon)
523 delete fBitmap;
525 if (icon != NULL) {
526 fBitmap = new(std::nothrow) BBitmap(icon);
527 if (fBitmap == NULL)
528 return B_NO_MEMORY;
529 return fBitmap->InitCheck();
532 fBitmap = NULL;
533 return B_OK;
537 /*! \brief Sends a notification to the notification_server.
539 The notification is delivered asynchronously to the notification_server,
540 which will display it according to its settings and filters.
542 \param timeout Microseconds after the message fades out.
543 \return
544 - \c B_OK: Everything went fine.
545 - \c B_BAD_PORT_ID: A connection to notification_server could not be
546 established or the server is not up and running anymore.
547 - \c Other errors: Building the message from the notification failed.
549 status_t
550 BNotification::Send(bigtime_t timeout)
552 BMessage msg(kNotificationMessage);
554 // Archive notification
555 status_t ret = Archive(&msg);
557 // Custom time out
558 if (ret == B_OK && timeout > 0)
559 ret = msg.AddInt64("timeout", timeout);
561 // Send message
562 if (ret == B_OK) {
563 BMessenger server(kNotificationServerSignature);
564 ret = server.SendMessage(&msg);
567 return ret;
571 void BNotification::_ReservedNotification1() {}
572 void BNotification::_ReservedNotification2() {}
573 void BNotification::_ReservedNotification3() {}
574 void BNotification::_ReservedNotification4() {}
575 void BNotification::_ReservedNotification5() {}
576 void BNotification::_ReservedNotification6() {}
577 void BNotification::_ReservedNotification7() {}
578 void BNotification::_ReservedNotification8() {}