Update change log and spec for wrt-plugins-tizen_0.4.43
[platform/framework/web/wrt-plugins-tizen.git] / src / Notification / JSStatusNotification.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <SecurityExceptions.h>
19
20 #include <JSUtil.h>
21 #include <ArgumentValidator.h>
22 #include <GlobalContextManager.h>
23 #include <MultiCallbackUserData.h>
24 #include <PlatformException.h>
25 #include <JSWebAPIErrorFactory.h>
26 #include <FilesystemUtils.h>
27 #include "plugin_config.h"
28
29 #include "JSStatusNotification.h"
30 #include "JSNotificationDetailInfo.h"
31
32 using namespace WrtDeviceApis::Commons;
33 using namespace DeviceAPI::Common;
34
35 namespace DeviceAPI {
36 namespace Notification {
37
38 #define NOTIFICATION_TYPE_VALUE "STATUS"
39
40 JSClassDefinition JSStatusNotification::m_classInfo = {
41     0,
42     kJSClassAttributeNone,
43     "StatusNotification",
44     NULL, //ParentClass
45     m_property, //StaticValues
46     NULL, //StaticFunctions
47     initialize, //Initialize
48     finalize, //Finalize
49     NULL, //HasProperty,
50     NULL, //GetProperty,
51     NULL, //SetProperty,
52     NULL, //DeleteProperty,
53     NULL, //GetPropertyNames,
54     NULL, //CallAsFunction,
55     NULL, //CallAsConstructor,
56     NULL, //HasInstance,
57     NULL //ConvertToType
58 };
59
60 JSStaticValue JSStatusNotification::m_property[] = 
61 {
62         {STATUS_NOTIFICATION_PROGRESS_TYPE,  JSStatusNotification::getProperty, JSStatusNotification::setProperty,      kJSPropertyAttributeNone },
63         {STATUS_NOTIFICATION_PROGRESS_VALUE,  JSStatusNotification::getProperty, JSStatusNotification::setProperty,     kJSPropertyAttributeNone },
64         {0, 0, 0, 0}
65 };
66
67 bool JSStatusNotification::setProperty(JSContextRef context,
68         JSObjectRef object,
69         JSStringRef propertyName,
70         JSValueRef value,
71         JSValueRef* exception)
72 {
73
74     StatusNotification *priv = static_cast<StatusNotification*>(JSObjectGetPrivate(object));
75     LoggerD("statusNotification :" << priv);
76     if (!priv) {
77         throw TypeMismatchException("StatusNotification's private object is NULL.");
78     }
79
80         try {
81                     std::string property;
82                     size_t jsSize = JSStringGetMaximumUTF8CStringSize(propertyName);
83                     if (jsSize > 0) {
84                         jsSize = jsSize + 1;
85                         char* buffer = new char[jsSize];        
86                         size_t written = JSStringGetUTF8CString(propertyName, buffer, jsSize);
87                         if (written > jsSize) {
88                             throw InvalidValuesException("Conversion could not be fully performed.");
89                         }
90                         property = buffer;
91                         delete[] buffer;
92                     }
93
94                    LoggerI("property =" << property);
95
96                    if ( property == STATUS_NOTIFICATION_PROGRESS_TYPE)
97                    {
98                         std::string strProgressType = JSUtil::JSValueToString(context, value);
99                         LoggerI("Progress Type : " << strProgressType);
100
101                         NotificationProgressType progType = NOTI_PROGRESS_TYPE_NONE;
102                         if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE) == 0)
103                             progType = NOTI_PROGRESS_TYPE_PERCENTAGE;
104                         else if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_BYTE) == 0)
105                             progType = NOTI_PROGRESS_TYPE_SIZE;
106                         else
107                             throw InvalidValuesException("Invalid Progress Type.");
108                         
109                         priv->setProgressType(progType);        //set progress Type
110
111                         return true;
112                    }
113                    else if ( property == STATUS_NOTIFICATION_PROGRESS_VALUE)
114                    {
115                             // progressValue
116                             unsigned long progressVal = JSUtil::JSValueToULong(context, value);
117                             LoggerI("Progress Value : " << progressVal);
118                                 
119                             if ( priv->getProgressType() == NOTI_PROGRESS_TYPE_PERCENTAGE)
120                             {
121                                 if ( 100 < progressVal )
122                                                 throw InvalidValuesException("The percentage progress value must be between 0 and 100");
123                                 priv->setProgressValue((double)progressVal/(double)100);
124                             }
125                             else 
126                             {
127                                 priv->setProgressValue((double)progressVal);
128                             }
129
130                             return true;
131                    }
132
133     }
134     catch ( const BasePlatformException& err) 
135     {
136         LoggerW(" notification convertion is failed. "   << err.getName().c_str() << ":"  << err.getMessage().c_str());
137     }
138         
139
140     return false;
141 }
142
143 JSValueRef JSStatusNotification::getProperty(JSContextRef context,
144                                                                                 JSObjectRef object,
145                                                                                 JSStringRef propertyName,
146                                                                                 JSValueRef* exception)
147 {
148
149         StatusNotification *priv = static_cast<StatusNotification*>(JSObjectGetPrivate(object));
150         LoggerD("statusNotification :" << priv);
151         if (!priv) {
152                 throw TypeMismatchException("StatusNotification's private object is NULL.");
153         }
154
155         try {
156                     std::string property;
157                     size_t jsSize = JSStringGetMaximumUTF8CStringSize(propertyName);
158                     if (jsSize > 0) {
159                         jsSize = jsSize + 1;
160                         char* buffer = new char[jsSize];        
161                         size_t written = JSStringGetUTF8CString(propertyName, buffer, jsSize);
162                         if (written > jsSize) {
163                             throw InvalidValuesException("Conversion could not be fully performed.");
164                         }
165                         property = buffer;
166                         delete[] buffer;
167                     }
168
169                    LoggerI("property =" << property);
170                    if ( property == STATUS_NOTIFICATION_PROGRESS_TYPE)
171                    {
172                         std::string type;
173                         if ( NOTI_PROGRESS_TYPE_PERCENTAGE ==  priv->getProgressType())
174                         {
175                                 type = TIZEN_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE;
176                         }
177                         else if ( NOTI_PROGRESS_TYPE_SIZE==   priv->getProgressType())
178                         {
179                                 type = TIZEN_NOTIFICATION_PROGRESS_TYPE_BYTE;
180                         }
181                    
182                         return JSUtil::toJSValueRef(context, type);
183                    
184                    }
185                    else if ( property == STATUS_NOTIFICATION_PROGRESS_VALUE)
186                    {                            
187                         // progressValue
188                         LoggerI("Progress Type=" << priv->getProgressType());
189                         
190                            // progressValue
191                         unsigned long progressVal = 0;  
192                         if ( NOTI_PROGRESS_TYPE_PERCENTAGE ==  priv->getProgressType())
193                         {
194                                 progressVal = (unsigned long)( (priv->getProgressValue()*100) );
195                         }
196                         else if ( NOTI_PROGRESS_TYPE_SIZE==   priv->getProgressType())
197                         {
198                                 progressVal = (unsigned long)priv->getProgressValue();
199                         }
200                         
201                         LoggerI("Progress Value=" << progressVal);
202
203                         if( priv->getNotiType() != NOTI_TYPE_PROGRESS && progressVal == 0)
204                         {
205                                 return JSValueMakeNull(context);
206                         }
207                         else
208                         {                                  
209                                 return  JSUtil::toJSValueRef(context, progressVal);
210                         }
211                    }
212
213     }
214     catch ( const BasePlatformException& err) 
215     {
216         LoggerW(" notification convertion is failed. "   << err.getName().c_str() << ":"  << err.getMessage().c_str());
217         return NULL;
218     }
219
220    return NULL;
221 }
222
223
224 JSClassRef JSStatusNotification::m_jsClassRef = JSClassCreate(JSStatusNotification::getClassInfo());
225
226 const JSClassRef JSStatusNotification::getClassRef()
227 {
228     if (!m_jsClassRef) {
229         m_jsClassRef = JSClassCreate(&m_classInfo);
230     }
231     return m_jsClassRef;
232 }
233
234 const JSClassDefinition* JSStatusNotification::getClassInfo()
235 {
236     return &m_classInfo;
237 }
238
239 void JSStatusNotification::initialize(JSContextRef context, JSObjectRef object)
240 {
241         LoggerD("JSStatusNotification::initialize, nothing ");
242 }
243
244 void JSStatusNotification::finalize(JSObjectRef object)
245 {
246     StatusNotification *priv = static_cast<StatusNotification*>(JSObjectGetPrivate(object));
247     if (priv) {
248         JSObjectSetPrivate(object, NULL);
249         delete priv;
250     }
251 }
252
253 JSObjectRef JSStatusNotification::constructor(JSContextRef context,
254     JSObjectRef constructor,
255     size_t argumentCount,
256     const JSValueRef arguments[],
257     JSValueRef* exception)
258 {
259     ArgumentValidator validator(context, argumentCount, arguments);
260
261     //get StatusType
262     JSObjectRef obj = JSObjectMake(context, getClassRef(), NULL);
263            
264     JSStringRef ctorName = JSStringCreateWithUTF8CString("constructor");
265     JSObjectSetProperty(context, obj, ctorName, constructor,
266                 kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete | kJSPropertyAttributeDontEnum, NULL);
267     JSStringRelease(ctorName);
268         
269     try {
270         //Status Notification Type.
271         NotificationType notiType = NOTI_TYPE_NONE;
272         std::string strStatusType = validator.toString(0, false, "");
273         LoggerI("Notification Type : " << strStatusType);
274         
275         if( strStatusType.compare(TIZEN_STATUS_NOTIFICATION_TYPE_SIMPLE) == 0)
276             notiType = NOTI_TYPE_SIMPLE;
277         else if( strStatusType.compare(TIZEN_STATUS_NOTIFICATION_TYPE_THUMBNAIL) == 0)
278             notiType = NOTI_TYPE_THUMBNAIL;
279         else if( strStatusType.compare(TIZEN_STATUS_NOTIFICATION_TYPE_ONGOING) == 0)
280             notiType = NOTI_TYPE_ONGOING;
281         else if( strStatusType.compare(TIZEN_STATUS_NOTIFICATION_TYPE_PROGRESS) == 0)
282             notiType = NOTI_TYPE_PROGRESS;
283         else
284             throw TypeMismatchException("notification status type mismatch.");
285         
286         StatusNotification *priv = new StatusNotification(notiType);
287         
288         priv->setTitle(validator.toString(1, false, ""));    //title
289         
290         JSObjectRef notiInitDict = validator.toObject(2, true);
291         
292         if (notiInitDict)
293         {
294             LoggerI("Set Notification Init Dictionary");
295             //content
296             JSValueRef contentValue = JSUtil::getProperty(context, notiInitDict, NOTIFICATION_CONTENT);
297             if (!(JSValueIsUndefined(context, contentValue) || JSValueIsNull(context, contentValue)))
298             {   
299                 priv->setContent(JSUtil::JSValueToString(context, contentValue));
300             }
301                     
302             //icon
303             try {                  
304                 JSValueRef iconValue = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_ICON_PATH);
305                 if (!JSValueIsUndefined(context, iconValue))
306                 {
307                     DeviceAPI::Filesystem::IPathPtr path = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, iconValue));
308                     priv->setIconPath(path->getFullPath());
309                 }
310             }
311             catch (...)
312             {
313                 throw InvalidValuesException("Icon file path is invaild");
314             }
315 #if 0                   
316             catch ( const BasePlatformException& err) 
317             {
318                 LoggerW("notification's icon path convertion is failed."  << err.getMessage());
319             }
320 #endif
321             
322             //sound
323             try {                  
324                 JSValueRef soundValue   = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_SOUND_PATH);      
325                 if (!JSValueIsUndefined(context, soundValue))
326                 {
327                     DeviceAPI::Filesystem::IPathPtr path = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, soundValue));
328                     priv->setSoundPath(path->getFullPath());
329                 }
330             }
331             catch (...)
332             {
333                  throw InvalidValuesException("sound file path is invaild");
334             }
335        
336             //vibration
337             JSValueRef vibrationValue = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_VIBRATION);
338             priv->setDefaultVibration(JSUtil::JSValueToBoolean(context, vibrationValue));
339             
340             //appControl
341             JSValueRef appControlValue  = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_APP_CONTROL);
342             if (!JSValueIsUndefined(context, appControlValue))
343                 priv->setApplicationControl(DeviceAPI::Application::JSApplicationControl::getApplicationControl(context, JSUtil::JSValueToObject(context, appControlValue) ));
344             
345             //appID                
346             JSValueRef appIdValue = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_APP_ID);
347             if (!JSValueIsUndefined(context, appIdValue))
348                 priv->setApplicationId(JSUtil::JSValueToString(context, appIdValue));
349                            
350             //progressType
351             NotificationProgressType progressType = NOTI_PROGRESS_TYPE_PERCENTAGE;
352
353             JSStringRef propertyName = JSStringCreateWithUTF8CString(STATUS_NOTIFICATION_PROGRESS_TYPE);
354             bool has = JSObjectHasProperty(context, notiInitDict, propertyName);
355             JSStringRelease(propertyName);
356             if (has)
357             {
358                 JSValueRef progressTypeValue = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_PROGRESS_TYPE);
359                 std::string strProgressType = JSUtil::JSValueToString(context, progressTypeValue);
360                 LoggerI("==Progress Type : " << strProgressType);       
361                 if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE) == 0)
362                         progressType = NOTI_PROGRESS_TYPE_PERCENTAGE;
363                 else if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_BYTE) == 0)
364                         progressType = NOTI_PROGRESS_TYPE_SIZE;
365                 else
366                         throw TypeMismatchException("Invalid Progress Type.");          
367             }
368             priv->setProgressType(progressType);
369
370 #if 0                   
371             JSValueRef progressTypeValue = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_PROGRESS_TYPE);
372             if (progressTypeValue)
373             {
374
375             }
376             if (!JSValueIsUndefined(context, progressTypeValue))
377             {      
378                     std::string strProgressType = JSUtil::JSValueToString(context, progressTypeValue);
379                     LoggerI("==Progress Type : " << strProgressType);   
380                     if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE) == 0)
381                            progressType = NOTI_PROGRESS_TYPE_PERCENTAGE;
382                     else if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_BYTE) == 0)
383                             progressType = NOTI_PROGRESS_TYPE_SIZE;
384                     else
385                             throw TypeMismatchException("Invalid Progress Type.");
386             }
387             priv->setProgressType(progressType);
388 #endif                                          
389             //ProgressValue
390             JSValueRef progressValue    = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_PROGRESS_VALUE);          
391             if (!JSValueIsUndefined(context, progressValue))
392             {
393                 if ( progressType == NOTI_PROGRESS_TYPE_PERCENTAGE)
394                {
395                     if ( 100 < JSUtil::JSValueToULong(context, progressValue) )
396                         throw TypeMismatchException("The percentage progress value must be between 0 and 100");
397                     priv->setProgressValue((double)JSUtil::JSValueToULong(context, progressValue)/(double)100);
398                 }
399                 else 
400                {
401                     priv->setProgressValue((double)JSUtil::JSValueToULong(context, progressValue));
402                }
403             }
404              
405             //DetailInfo
406             JSValueRef detailInfoValue  = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_DETAIL_INFO);
407
408             std::vector<NotificationDetailInfo*> detailInfos;
409             if (JSIsArrayValue(context, detailInfoValue))
410             {
411                 JSObjectRef arrayobj = JSUtil::JSValueToObject(context, detailInfoValue);
412                 for(std::size_t i = 0; i < JSGetArrayLength(context, arrayobj); ++i)
413                 {
414                     JSValueRef element = JSGetArrayElement(context, arrayobj, i);
415                     JSObjectRef object = JSUtil::JSValueToObject(context, element);
416                     if (object)
417                     {
418                         NotificationDetailInfo* item = static_cast<NotificationDetailInfo*>(JSObjectGetPrivate(object));
419                         std::string main = item->getMainText();
420                         std::string sub = item->getSubText();
421                         LoggerI("Main : " << main << " Sub : " << sub);
422              
423                         NotificationDetailInfo *detailinfo = new NotificationDetailInfo(NULL, (int)i, main, sub);
424                         detailInfos.push_back(detailinfo);      
425                     }
426                 }
427             }
428             priv->setDetailInfos(detailInfos);  
429     
430             //backgroundimage
431             try {                  
432                 JSValueRef backgroundImageValue = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_BACKGROUND_IMAGE_PATH);
433                 if (!JSValueIsUndefined(context, backgroundImageValue))
434                 {
435                     DeviceAPI::Filesystem::IPathPtr path = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, backgroundImageValue));
436                     priv->setBackground(path->getFullPath());
437                 }
438             }
439             catch(...)
440             {
441                  throw TypeMismatchException("The backgound image path is invalid : ");
442             }
443         
444             //number
445             JSValueRef numberValue  = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_NUMBER);
446             if (!JSValueIsUndefined(context, numberValue))
447             {
448                  priv->setNumber(JSUtil::JSValueToLong(context, numberValue));
449             }
450            
451             //thumbnail
452             try {                  
453                 JSValueRef thumbnailsValue  = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_THUMBNAILS);
454                 if (!JSValueIsUndefined(context, thumbnailsValue))
455                 {
456
457                     std::vector<std::string> thumbnailPaths;
458                     if( JSIsArrayValue(context, thumbnailsValue)){
459                         JSObjectRef arrayobj = JSUtil::JSValueToObject(context, thumbnailsValue);        
460                         for (std::size_t i = 0; i < JSGetArrayLength(context, arrayobj); ++i) {
461                                  JSValueRef element = JSGetArrayElement(context, arrayobj, i);
462                                          DeviceAPI::Filesystem::IPathPtr thumbnailPath = 
463                                                  DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, element));
464                                          LoggerI("thumbnail Path = " << thumbnailPath->getFullPath());
465                                          thumbnailPaths.push_back(thumbnailPath->getFullPath());
466                         }
467                     }           
468                     priv->setThumbnails(thumbnailPaths);                
469                 }
470             }
471             catch ( ... ) 
472             {
473                 throw TypeMismatchException("thumbnail path convertion is failed.");
474             }
475
476             //subIconPath
477             try {                  
478                 JSValueRef subIconPathValue = JSUtil::getProperty(context, notiInitDict, STATUS_NOTIFICATION_SUB_ICON_PATH);
479                 if (!JSValueIsUndefined(context, subIconPathValue))
480                 {
481                     DeviceAPI::Filesystem::IPathPtr path = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, subIconPathValue));
482                     priv->setSubIconPath( path->getFullPath());
483                 }
484             }
485             catch (...) 
486             {
487                 throw TypeMismatchException("subIcon path convertion is failed.");
488             }
489                     
490         }
491                
492         setPrivateObject(context, obj, priv);
493                 
494     } 
495      catch ( const BasePlatformException& err) 
496     {
497         LoggerW(" notification convertion is failed. "   << err.getName().c_str() << ":"  << err.getMessage().c_str());
498         JSObjectRef error = JSWebAPIErrorFactory::makeErrorObject(context, err);
499         *exception = error;
500         return error;
501     }
502
503     return obj;      
504
505 }
506
507 StatusNotification* JSStatusNotification::getPrivateObject(JSContextRef context, JSObjectRef object)
508 {
509     LoggerD("get object :" << object);
510
511     StatusNotification *priv = static_cast<StatusNotification*>(JSObjectGetPrivate(object));
512     LoggerD("statusNotification :" << priv);
513     if (!priv) {
514         throw TypeMismatchException("StatusNotification's private object is NULL.");
515     }
516
517     //type
518     JSValueRef type = JSUtil::getProperty(context, object, NOTIFICATION_TYPE);
519     if ((JSUtil::JSValueToString(context, type)).compare(NOTIFICATION_TYPE_VALUE) )
520     {
521         throw TypeMismatchException("StatusNotification's type is mismatched");
522     }
523      
524     //Title
525     JSValueRef title = JSUtil::getProperty(context, object, NOTIFICATION_TITLE);
526     priv->setTitle( JSUtil::JSValueToString(context, title));
527
528     //Content
529     JSValueRef contents = JSUtil::getProperty(context, object, NOTIFICATION_CONTENT);
530     if (!JSValueIsNull(context, contents))
531     {
532         priv->setContent( JSUtil::JSValueToString(context, contents));
533     }
534
535     // iconPath
536     JSValueRef iconPath = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_ICON_PATH);
537     if ( !JSValueIsNull(context, contents) )
538     {
539         DeviceAPI::Filesystem::IPathPtr icon = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, iconPath));
540         priv->setIconPath(icon->getFullPath());
541     }
542     //else
543     //{
544     //    priv->setIconPath("");
545     //}
546
547     // subIconPath
548     JSValueRef subIconPath = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_SUB_ICON_PATH);
549     if (!JSValueIsNull(context, subIconPath))
550     {
551         DeviceAPI::Filesystem::IPathPtr subIcon = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, subIconPath));
552         priv->setSubIconPath(subIcon->getFullPath());
553     }
554     //else
555     //{
556     //    priv->setSubIconPath("");
557     //}
558
559     // number
560     JSValueRef number = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_NUMBER);
561     priv->setNumber(JSUtil::JSValueToLong(context, number));
562
563     // detailInfo
564     JSValueRef detailInfo = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_DETAIL_INFO);
565     std::vector<NotificationDetailInfo*> detailInfos;
566     if (JSIsArrayValue(context, detailInfo))
567     {
568         JSObjectRef arrayobj = JSUtil::JSValueToObject(context, detailInfo);
569         for(std::size_t i = 0; i < JSGetArrayLength(context, arrayobj); ++i)
570         {
571             JSValueRef element = JSGetArrayElement(context, arrayobj, i);
572             JSObjectRef object = JSUtil::JSValueToObject(context, element);
573             if (object)
574             {
575                 NotificationDetailInfo* detailinfo = static_cast<NotificationDetailInfo*>(JSObjectGetPrivate(object));
576                 detailInfos.push_back(detailinfo);      
577             }
578         }
579     }
580     priv->setDetailInfos(detailInfos);
581     
582     // backgroundImagePath
583     JSValueRef backgroundImagePath = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_BACKGROUND_IMAGE_PATH);
584     if (!JSValueIsNull(context, backgroundImagePath))
585     {
586         DeviceAPI::Filesystem::IPathPtr backgroundImage = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, backgroundImagePath));
587         priv->setBackground(backgroundImage->getFullPath());
588     }
589     //else
590     //{
591     //    priv->setBackground("");
592     //}
593     
594     // thumbnails
595     JSValueRef thumbnails = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_THUMBNAILS);
596
597     std::vector<std::string> thumbnailPaths;
598     if( JSIsArrayValue(context, thumbnails)){
599         JSObjectRef arrayobj = JSUtil::JSValueToObject(context, thumbnails);     
600          for (std::size_t i = 0; i < JSGetArrayLength(context, arrayobj); ++i) {
601                  JSValueRef element = JSGetArrayElement(context, arrayobj, i);
602                  DeviceAPI::Filesystem::IPathPtr thumbnailPath = 
603                      DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, element));
604                  LoggerI("thumbnail Path = " << thumbnailPath->getFullPath());
605                  thumbnailPaths.push_back(thumbnailPath->getFullPath());
606          }
607     }           
608     priv->setThumbnails(thumbnailPaths);
609     
610     // soundPath
611     JSValueRef soundPath = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_SOUND_PATH);
612     if (!JSValueIsNull(context, soundPath))
613     {
614         DeviceAPI::Filesystem::IPathPtr sound = DeviceAPI::Filesystem::Utils::fromVirtualPath(context, JSUtil::JSValueToString(context, soundPath));
615         priv->setSoundPath(sound->getFullPath());
616     }
617     //else
618     //{
619     //    priv->setSoundPath("");
620     //}
621     
622     // vibration
623     JSValueRef vibration = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_VIBRATION);
624     priv->setDefaultVibration(JSUtil::JSValueToBoolean(context, vibration));
625
626     // appControl
627     JSValueRef appControl = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_APP_CONTROL);
628     if (!JSValueIsUndefined(context, appControl) && !JSValueIsNull(context, appControl))
629         priv->setApplicationControl(DeviceAPI::Application::JSApplicationControl::getApplicationControl(context, JSUtil::JSValueToObject(context,appControl)));
630
631     // appId
632     JSValueRef appId = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_APP_ID);
633     if (!JSValueIsNull(context, appId))
634         priv->setApplicationId(JSUtil::JSValueToString(context, appId));
635
636 #if 0
637     // progressType
638     JSValueRef progressType = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_PROGRESS_TYPE);
639     std::string strProgressType = JSUtil::JSValueToString(context, progressType);
640     LoggerI("Progress Type : " << strProgressType);
641     
642     NotificationProgressType progType = NOTI_PROGRESS_TYPE_NONE;
643     if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE) == 0)
644         progType = NOTI_PROGRESS_TYPE_PERCENTAGE;
645     else if( strProgressType.compare(TIZEN_NOTIFICATION_PROGRESS_TYPE_BYTE) == 0)
646         progType = NOTI_PROGRESS_TYPE_SIZE;
647     else
648         throw InvalidValuesException("Invalid Progress Type.");
649     priv->setProgressType(progType);
650     
651     // progressValue
652     JSValueRef progressValue = JSUtil::getProperty(context, object, STATUS_NOTIFICATION_PROGRESS_VALUE);
653     LoggerI(" Progress Value in Private Object = " << JSUtil::JSValueToULong(context, progressValue));
654     if ( progType == NOTI_PROGRESS_TYPE_PERCENTAGE)
655     {
656         if ( 100 < JSUtil::JSValueToULong(context, progressValue) )
657                         throw InvalidValuesException("The percentage progress value must be between 0 and 100");
658         priv->setProgressValue((double)JSUtil::JSValueToULong(context, progressValue)/(double)100);
659     }
660     else 
661     {
662         priv->setProgressValue((double)JSUtil::JSValueToULong(context, progressValue));
663     }
664  #endif   
665     return priv;
666 }
667
668 void JSStatusNotification::setPrivateObject(JSContextRef context, JSObjectRef object, StatusNotification *priv)
669 {
670     if (priv) {
671         JSObjectSetPrivate(object, static_cast<void*>(priv));
672     }
673     else
674         throw TypeMismatchException("StatusNotification object is invaild.");
675
676     //type
677     std::string typeVal(NOTIFICATION_TYPE_VALUE);
678     JSUtil::setProperty(context, object, NOTIFICATION_TYPE,
679             JSUtil::toJSValueRef(context, typeVal), kJSPropertyAttributeReadOnly);
680         
681     std::string type;
682     
683     //statusType
684     if ( NOTI_TYPE_SIMPLE ==  priv->getNotiType())
685         type = TIZEN_STATUS_NOTIFICATION_TYPE_SIMPLE;
686     else if ( NOTI_TYPE_ONGOING ==  priv->getNotiType())
687         type = TIZEN_STATUS_NOTIFICATION_TYPE_ONGOING;
688     else if ( NOTI_TYPE_PROGRESS ==  priv->getNotiType())
689         type = TIZEN_STATUS_NOTIFICATION_TYPE_PROGRESS; 
690     else if ( NOTI_TYPE_THUMBNAIL ==  priv->getNotiType())
691         type = TIZEN_STATUS_NOTIFICATION_TYPE_THUMBNAIL;
692     else
693         throw TypeMismatchException("status type mismatch.");
694         
695     JSUtil::setProperty(context, object, STATUS_NOTIFICATION_STATUS_TYPE,
696             JSUtil::toJSValueRef(context, type), kJSPropertyAttributeReadOnly);
697     //id
698     if (priv->getID() >= 0)
699     {
700             std::stringstream stream;
701             stream << priv->getID();
702             
703             if(stream.fail())
704                throw TypeMismatchException("Notification's ID conversion is failed.");
705
706             JSUtil::setProperty(context, object, NOTIFICATION_ID,
707                 JSUtil::toJSValueRef(context, stream.str()), kJSPropertyAttributeReadOnly);        
708     }
709     else
710     {
711             JSUtil::setProperty(context, object, NOTIFICATION_ID,
712                     JSValueMakeNull(context), kJSPropertyAttributeReadOnly);
713     }
714
715     //postedTime
716     if (priv->getPostedTime() > 0)
717     {
718             JSUtil::setProperty(context, object, NOTIFICATION_POSTED_TIME,
719                 JSUtil::makeDateObject(context,priv->getPostedTime()), kJSPropertyAttributeReadOnly);  
720     }
721     else
722     {
723             JSUtil::setProperty(context, object, NOTIFICATION_POSTED_TIME,
724                     JSValueMakeNull(context), kJSPropertyAttributeReadOnly);
725     }    
726
727     //title
728     JSUtil::setProperty(context, object, NOTIFICATION_TITLE,
729             JSUtil::toJSValueRef(context, priv->getTitle()), kJSPropertyAttributeNone);
730
731     //content
732     if (priv->getStrContent())
733         JSUtil::setProperty(context, object, NOTIFICATION_CONTENT,
734                   JSUtil::toJSValueRef(context, priv->getContent()), kJSPropertyAttributeNone);
735     else
736         JSUtil::setProperty(context, object, NOTIFICATION_CONTENT, JSValueMakeNull(context), kJSPropertyAttributeNone);   
737
738     //iconPath
739     if (!priv->getIconPath().empty())
740         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_ICON_PATH,
741                 JSUtil::toJSValueRef(context, DeviceAPI::Filesystem::Utils::toVirtualPath(context, priv->getIconPath())), kJSPropertyAttributeNone);
742     else
743          JSUtil::setProperty(context, object, STATUS_NOTIFICATION_ICON_PATH, JSValueMakeNull(context), kJSPropertyAttributeNone);
744
745     //subIconPath
746     if ( !priv->getSubIconPath().empty())
747         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_SUB_ICON_PATH,
748                JSUtil::toJSValueRef(context, DeviceAPI::Filesystem::Utils::toVirtualPath(context, priv->getSubIconPath())), kJSPropertyAttributeNone);
749     else 
750         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_SUB_ICON_PATH,  JSValueMakeNull(context), kJSPropertyAttributeNone);
751
752     //number
753     if (priv->getStrNumber()){
754         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_NUMBER,
755             JSUtil::toJSValueRef(context, priv->getNumber()), kJSPropertyAttributeNone);        
756     }
757     else
758         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_NUMBER, JSValueMakeNull(context), kJSPropertyAttributeNone);                   
759
760      // backgroundImagePath
761     if ( !priv->getBackground().empty()) 
762         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_BACKGROUND_IMAGE_PATH,
763             JSUtil::toJSValueRef(context, DeviceAPI::Filesystem::Utils::toVirtualPath(context, priv->getBackground())), kJSPropertyAttributeNone);
764     else
765         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_BACKGROUND_IMAGE_PATH, JSValueMakeNull(context), kJSPropertyAttributeNone);
766         
767     // thumbnails
768     std::vector<std::string> thumbnails = priv->getThumbnails();
769     LoggerI("Thumbnail Size : " << thumbnails.size());
770      JSValueRef tumbnailvalueArray[thumbnails.size()];
771     for( unsigned int i = 0 ; i < thumbnails.size(); i++) {
772             if (!thumbnails[i].empty())
773             {
774                 LoggerI("Thumbnail :" << thumbnails[i]);
775                 tumbnailvalueArray[i] =  JSUtil::toJSValueRef(context, DeviceAPI::Filesystem::Utils::toVirtualPath(context, thumbnails[i]));
776             }
777     }
778
779     JSValueRef exception = NULL;
780     JSObjectRef jsThumbnails = JSObjectMakeArray(context, thumbnails.size(), tumbnailvalueArray, &exception);
781     if (exception != NULL) {
782         throw DeviceAPI::Common::UnknownException("Make Object Array failed.");
783     }
784
785     JSUtil::setProperty(context, object, STATUS_NOTIFICATION_THUMBNAILS,
786            jsThumbnails, kJSPropertyAttributeNone);
787
788     // soundPath
789     if ( !priv->getSoundPath().empty() )
790         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_SOUND_PATH,
791             JSUtil::toJSValueRef(context, DeviceAPI::Filesystem::Utils::toVirtualPath(context, priv->getSoundPath())), kJSPropertyAttributeNone);
792     else
793         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_SOUND_PATH, JSValueMakeNull(context), kJSPropertyAttributeNone);
794
795     // vibration
796     JSUtil::setProperty(context, object, STATUS_NOTIFICATION_VIBRATION,
797             JSUtil::toJSValueRef(context, priv->getDefaultVibration()), kJSPropertyAttributeNone);
798
799     // appId
800     if (!priv->getApplicationId().empty())
801         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_APP_ID,
802             JSUtil::toJSValueRef(context, priv->getApplicationId()), kJSPropertyAttributeNone);
803     else
804         JSUtil::setProperty(context, object, STATUS_NOTIFICATION_APP_ID, JSValueMakeNull(context), kJSPropertyAttributeNone);
805
806 #if 0
807     // progressType   & Value
808     LoggerI("Progress Type=" << priv->getProgressType());
809
810        // progressValue
811     unsigned long progressVal = 0;      
812     if ( NOTI_PROGRESS_TYPE_PERCENTAGE ==  priv->getProgressType())
813     {
814         type = TIZEN_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE;
815         progressVal = (unsigned long)( (priv->getProgressValue()*100) );
816     }
817     else if ( NOTI_PROGRESS_TYPE_SIZE==   priv->getProgressType())
818     {
819         type = TIZEN_NOTIFICATION_PROGRESS_TYPE_BYTE;
820         progressVal = (unsigned long)priv->getProgressValue();
821     }
822
823     LoggerI("Progress Type=" << type);
824     JSUtil::setProperty(context, object, STATUS_NOTIFICATION_PROGRESS_TYPE,
825             JSUtil::toJSValueRef(context, type), kJSPropertyAttributeNone);
826                 
827     LoggerI("Progress Value =" << progressVal); 
828     JSUtil::setProperty(context, object, STATUS_NOTIFICATION_PROGRESS_VALUE,                
829             JSUtil::toJSValueRef(context, progressVal), kJSPropertyAttributeNone);
830 #endif
831     // detailInfo
832     std::vector<NotificationDetailInfo*> detailInfo = priv->getDetailInfos();
833     LoggerI("detail Info Size : " << detailInfo.size());
834     JSObjectRef valueArray[detailInfo.size()];
835     for( unsigned int i = 0 ; i < detailInfo.size(); i++) {
836             if (detailInfo[i])
837             {
838                 LoggerI("Main = " << detailInfo[i]->getMainText() << " Sub = " << detailInfo[i]->getSubText());
839                 valueArray[i] = JSObjectMake(GlobalContextManager::getInstance()->getGlobalContext(context), JSNotificationDetailInfo::getClassRef(), static_cast<void*>(detailInfo[i]));
840                 JSNotificationDetailInfo::setPrivateObject(context, valueArray[i], detailInfo[i]);
841                 LoggerI("make Object : " << valueArray[i]);
842             }
843     }
844
845     exception = NULL;
846     JSObjectRef jsResult = JSObjectMakeArray(GlobalContextManager::getInstance()->getGlobalContext(context), detailInfo.size(), valueArray, &exception);
847     if (exception != NULL) {
848         throw DeviceAPI::Common::UnknownException("Make Object Array failed.");
849     }
850
851        // detailInfo
852     JSUtil::setProperty(context, object, STATUS_NOTIFICATION_DETAIL_INFO,
853            jsResult, kJSPropertyAttributeNone);
854
855     // appControl
856     if (  !(priv->getApplicationControl())->getOperation().empty())
857     {   
858             DeviceAPI::Application::JSApplicationControlPriv *appCtrlPriv = new DeviceAPI::Application::JSApplicationControlPriv(context, priv->getApplicationControl());
859             JSObjectRef jsAppCtrl = JSObjectMake(context, DeviceAPI::Application::JSApplicationControl::getClassRef(), appCtrlPriv);
860             JSUtil::setProperty(context, object, STATUS_NOTIFICATION_APP_CONTROL,  jsAppCtrl, kJSPropertyAttributeNone);
861     }
862     else
863            JSUtil::setProperty(context, object, STATUS_NOTIFICATION_APP_CONTROL,   JSValueMakeNull(context), kJSPropertyAttributeNone);
864   
865 }
866
867
868 } // Notification
869 } // DeviceAPI