wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / Package / JSPackageManager.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 <JSTizenExceptionFactory.h>
19 #include <JSTizenException.h>
20 #include <SecurityExceptions.h>
21
22 #include <ArgumentValidator.h>
23 #include <PlatformException.h>
24 #include <JSWebAPIException.h>
25
26 #include <CommonsJavaScript/Converter.h>
27 //#include <CommonsJavaScript/JSUtils.h>
28 //#include <CommonsJavaScript/Utils.h>
29
30 #include <JSUtil.h>
31 #include <GlobalContextManager.h>
32 #include <TimeTracer.h>
33
34 #include "JSPackageManager.h"
35 #include "JSPackageInformation.h"
36
37 #include "PackageManager.h"
38 #include "PackageInformation.h"
39 #include "plugin_config.h"
40 #include <Logger.h>
41
42 namespace DeviceAPI {
43 namespace Package {
44
45 using namespace std;
46 using namespace WrtDeviceApis::Commons;
47 using namespace WrtDeviceApis::CommonsJavaScript;
48 using namespace DeviceAPI::Common;
49
50 JSClassRef JSPackageManager::m_jsClassRef = NULL;
51
52 JSClassDefinition JSPackageManager::m_classInfo = {
53                 0,                                                                              // current (and only) version is 0
54                 kJSClassAttributeNone,                                  // attributes
55                 TIZEN_INTERFACE_PACKAGE_MANAGER,                // class name
56                 NULL,                                                                   // parent class
57                 NULL,                                                                   // static values
58                 m_function,                                                             // static functions
59                 initialize,                                                             // initialize
60                 finalize,                                                               // finalize
61                 NULL,                                                                   // hasProperty
62                 NULL,                                                                   // getProperty
63                 NULL,                                                                   // setProperty
64                 NULL,                                                                   // deleteProperty
65                 NULL,                                                                   // getPropertyNames
66                 NULL,                                                                   // callAsConstructor
67                 NULL,                                                                   // callAsConstructor
68                 NULL,                                                                   // hasInstance
69                 NULL                                                                    // convertToType
70 };
71
72 JSStaticFunction JSPackageManager::m_function[] = {
73                 { PACKAGE_FUNCTION_API_INSTALL, JSPackageManager::install, kJSPropertyAttributeNone },
74                 { PACKAGE_FUNCTION_API_UNINSTALL, JSPackageManager::uninstall, kJSPropertyAttributeNone },
75                 { PACKAGE_FUNCTION_API_GET_PACKAGE_INFO, JSPackageManager::getPackageInfo, kJSPropertyAttributeNone },
76                 { PACKAGE_FUNCTION_API_GET_PACKAGES_INFO, JSPackageManager::getPackagesInfo, kJSPropertyAttributeNone },
77                 { PACKAGE_FUNCTION_API_SET_PACKAGE_INFO_EVENT_LISTENER, JSPackageManager::setPackageInfoEventListener, kJSPropertyAttributeNone },
78                 { PACKAGE_FUNCTION_API_UNSET_PACKAGE_INFO_EVENT_LISTENER, JSPackageManager::unsetPackageInfoEventListener, kJSPropertyAttributeNone },
79                 { 0, 0, 0 }
80 };
81
82 const JSClassRef JSPackageManager::getClassRef() 
83 {
84         if (!m_jsClassRef) {
85                 m_jsClassRef = JSClassCreate(&m_classInfo);
86         }
87         
88         return m_jsClassRef;
89 }
90
91 const JSClassDefinition* JSPackageManager::getClassInfo()
92 {
93         return &m_classInfo;
94 }
95
96 void JSPackageManager::initialize(JSContextRef context, JSObjectRef object) 
97 {
98         // Do Nothing.
99 }
100
101 void JSPackageManager::finalize(JSObjectRef object) 
102 {
103         CallbackUserData *callback = static_cast<CallbackUserData*>(JSObjectGetPrivate(object));
104     if( callback != NULL ){
105         JSObjectSetPrivate(object, NULL);
106         delete callback;
107     }
108 }
109
110 JSValueRef JSPackageManager::install(JSContextRef context,
111         JSObjectRef object,
112         JSObjectRef thisObject,
113         size_t argumentCount,
114         const JSValueRef arguments[],
115         JSValueRef* exception)
116 {
117         LoggerD("entered");
118         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
119
120         AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_INSTALL);
121         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
122
123         try {
124                 ArgumentValidator validator(context, argumentCount, arguments);
125                 
126                 string path = validator.toString(0);
127
128                 JSObjectRef eventCBObj = validator.toCallbackObject(1, false, "onprogress", "oncomplete", NULL);
129                 JSObjectRef errCB = validator.toFunction(2, true);
130
131                 CallbackUserData *onprogressCb = NULL;
132                 CallbackUserData *oncompleteCb = NULL;
133                 CallbackUserData *onerrorCb = NULL;
134                 
135                 JSValueRef onprogress = JSUtil::getProperty(context, eventCBObj, "onprogress", exception);
136                 if (!JSValueIsUndefined(context, onprogress)) {
137                         onprogressCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
138                         onprogressCb->setSuccessCallback(onprogress);                   
139                 }
140
141                 JSValueRef oncomplete = JSUtil::getProperty(context, eventCBObj, "oncomplete", exception);
142                 if (!JSValueIsUndefined(context, oncomplete)) {
143                         oncompleteCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
144                         oncompleteCb->setSuccessCallback(oncomplete);                   
145                 }
146
147                 if (errCB) {
148                         onerrorCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
149                         onerrorCb->setSuccessCallback(errCB);
150                 }
151
152                 PackageInstallEventCallback *pkgInstallEventCB = new PackageInstallEventCallback(GlobalContextManager::getInstance()->getGlobalContext(context), onprogressCb, oncompleteCb, onerrorCb);
153                 
154                 PackageManager::getInstance()->install(path, pkgInstallEventCB);
155                 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
156                 return JSValueMakeUndefined(context);
157                 
158         } catch (const BasePlatformException &err) {
159         return JSWebAPIException::throwException(context, exception, err);
160     } catch (...) {
161         DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
162         return JSWebAPIException::throwException(context, exception, err);
163     }
164 }
165
166
167 JSValueRef JSPackageManager::uninstall(JSContextRef context,
168         JSObjectRef object,
169         JSObjectRef thisObject,
170         size_t argumentCount,
171         const JSValueRef arguments[],
172         JSValueRef* exception)
173 {
174         LoggerD("entered");
175         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
176
177         AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_INSTALL);
178         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
179
180         try {
181                 ArgumentValidator validator(context, argumentCount, arguments);
182                 
183                 string id = validator.toString(0);
184                 //JSObjectRef eventCBObj = validator.toObject(1, true);
185                 JSObjectRef eventCBObj = validator.toCallbackObject(1, false, "onprogress", "oncomplete", NULL);
186                 JSObjectRef errCB = validator.toFunction(2, true);
187
188                 CallbackUserData *onprogressCb = NULL;
189                 CallbackUserData *oncompleteCb = NULL;
190                 CallbackUserData *onerrorCb = NULL;     
191
192                 JSValueRef onprogress = JSUtil::getProperty(context, eventCBObj, "onprogress", exception);
193                 if (!JSValueIsUndefined(context, onprogress)) {
194                         onprogressCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
195                         onprogressCb->setSuccessCallback(onprogress);                   
196                 }
197
198                 JSValueRef oncomplete = JSUtil::getProperty(context, eventCBObj, "oncomplete", exception);
199                 if (!JSValueIsUndefined(context, oncomplete)) {
200                         oncompleteCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
201                         oncompleteCb->setSuccessCallback(oncomplete);                   
202                 }
203
204                 if (errCB) {
205                         onerrorCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
206                         onerrorCb->setSuccessCallback(errCB);
207                 }
208
209                 PackageInstallEventCallback *pkgInstallEventCB = new PackageInstallEventCallback(GlobalContextManager::getInstance()->getGlobalContext(context), onprogressCb, oncompleteCb, onerrorCb);
210
211                 PackageManager::getInstance()->uninstall(id, pkgInstallEventCB);
212                 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
213                 return JSValueMakeUndefined(context);
214                 
215         } catch (const BasePlatformException &err) {
216         return JSWebAPIException::throwException(context, exception, err);
217     } catch (...) {
218         DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
219         return JSWebAPIException::throwException(context, exception, err);
220     }
221 }
222
223
224 JSValueRef JSPackageManager::getPackagesInfo(JSContextRef context, 
225         JSObjectRef object, 
226         JSObjectRef thisObject, 
227         size_t argumentCount,
228         const JSValueRef arguments[], 
229         JSValueRef* exception) 
230 {
231         LoggerD("entered");
232         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
233
234         AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_GET_PACKAGES_INFO);
235         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
236
237         try {
238                 ArgumentValidator validator(context, argumentCount, arguments);
239                 JSObjectRef successCBObj = validator.toFunction(0);
240                 JSObjectRef errCB = validator.toFunction(1, true);
241         
242         PackageInfoCallbackData *callback = new PackageInfoCallbackData(GlobalContextManager::getInstance()->getGlobalContext(context));
243                 callback->setSuccessCallback(successCBObj);             
244                 if (argumentCount > 1) {
245                         callback->setErrorCallback(errCB);
246                 }
247
248                 PackageManager::getInstance()->getPackagesInfo(callback);
249                 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
250                 return JSValueMakeUndefined(context);
251                 
252         } catch (const BasePlatformException &err) {
253         return JSWebAPIException::throwException(context, exception, err);
254     } catch (...) {
255         DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
256         return JSWebAPIException::throwException(context, exception, err);
257     }
258 }
259
260 JSValueRef JSPackageManager::getPackageInfo(JSContextRef context, 
261         JSObjectRef object, 
262         JSObjectRef thisObject, 
263         size_t argumentCount,
264         const JSValueRef arguments[], 
265         JSValueRef* exception) 
266 {
267         LoggerD("entered");
268         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
269
270         AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_GET_PACKAGE_INFO);
271         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
272
273         try {
274                 ArgumentValidator validator(context, argumentCount, arguments);
275                 string id = validator.toString(0, true);
276                 //LoggerD("id = " << id);
277                 
278                 PackageInformation* pkgInfo = PackageManager::getInstance()->getPackageInfo(id);
279                 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
280                 return JSPackageInformation::createJSObject(context, pkgInfo);
281
282         } catch (const BasePlatformException &err) {
283         return JSWebAPIException::throwException(context, exception, err);
284     } catch (...) {
285         DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
286         return JSWebAPIException::throwException(context, exception, err);
287     }
288 }
289
290
291 JSValueRef JSPackageManager::setPackageInfoEventListener(JSContextRef context, 
292         JSObjectRef object, 
293         JSObjectRef thisObject, 
294         size_t argumentCount,
295         const JSValueRef arguments[], 
296         JSValueRef* exception) 
297 {
298         LoggerD("entered");
299         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
300
301         AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_SET_PACKAGE_INFO_EVENT_LISTENER);
302         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
303
304         try {
305                 ArgumentValidator validator(context, argumentCount, arguments);
306
307                 JSObjectRef eventCBObj = validator.toCallbackObject(0, false, "oninstalled", "onupdated", "onuninstalled", NULL);
308
309                 CallbackUserData *oninstalledCb = NULL;
310                 CallbackUserData *onupdatedCb = NULL;
311                 CallbackUserData *onuninstalledCb = NULL;
312
313                 JSValueRef oninstalled = JSUtil::getProperty(context, eventCBObj, "oninstalled", exception);
314                 if (!JSValueIsUndefined(context, oninstalled)) {
315                         oninstalledCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
316                         oninstalledCb->setSuccessCallback(oninstalled);                 
317                 }
318                 
319                 JSValueRef onupdated = JSUtil::getProperty(context, eventCBObj, "onupdated", exception);
320                 if (!JSValueIsUndefined(context, onupdated)) {
321                         onupdatedCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
322                         onupdatedCb->setSuccessCallback(onupdated);             
323                 }
324                 
325                 JSValueRef onuninstalled = JSUtil::getProperty(context, eventCBObj, "onuninstalled", exception);
326                 if (!JSValueIsUndefined(context, onuninstalled)) {
327                         onuninstalledCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
328                         onuninstalledCb->setSuccessCallback(onuninstalled);
329                 }
330
331                 PackageInfoEventCallback *pkginfoEventCB = new PackageInfoEventCallback(oninstalledCb, onupdatedCb, onuninstalledCb);
332
333                 PackageManager::getInstance()->setPackageInfoEventListener(pkginfoEventCB);
334                 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
335                 return JSValueMakeUndefined(context);
336                 
337         } catch (const BasePlatformException &err) {
338         return JSWebAPIException::throwException(context, exception, err);
339     } catch (...) {
340         DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
341         return JSWebAPIException::throwException(context, exception, err);
342     }
343 }
344
345 JSValueRef JSPackageManager::unsetPackageInfoEventListener(JSContextRef context,
346         JSObjectRef object,
347         JSObjectRef thisObject,
348         size_t argumentCount,
349         const JSValueRef arguments[],
350         JSValueRef* exception)
351 {
352         LoggerD("entered");
353         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
354
355         AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_UNSET_PACKAGE_INFO_EVENT_LISTENER);
356         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
357
358         try {
359                 PackageManager::getInstance()->unsetPackageInfoEventListener();
360                 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
361                 return JSValueMakeUndefined(context);
362
363         } catch(const BasePlatformException& err) {
364                 return JSWebAPIException::throwException(context, exception, err);
365         }
366 }
367
368
369 #if 0
370 JSValueRef JSPackageManager::move(JSContextRef context,
371         JSObjectRef object,
372         JSObjectRef thisObject,
373         size_t argumentCount,
374         const JSValueRef arguments[],
375         JSValueRef* exception)
376 {
377         LoggerD("entered");
378
379         //AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_MOVE);
380         //TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
381
382         Try {
383         Converter converter(context);
384         JSValueRef checkedArguments[4];
385                 
386         ArgumentValidationChecker::check(context, argumentCount, arguments, 4, checkedArguments, 
387             ArgumentValidationChecker::MANDATORY, ArgumentValidationChecker::String,
388             ArgumentValidationChecker::MANDATORY, ArgumentValidationChecker::String,
389             ArgumentValidationChecker::MANDATORY | ArgumentValidationChecker::NULLABLE, ArgumentValidationChecker::Object,
390             ArgumentValidationChecker::OPTIONAL | ArgumentValidationChecker::NULLABLE, ArgumentValidationChecker::Function,
391             ArgumentValidationChecker::END);
392
393                 string id = converter.toString(checkedArguments[0]);
394                 string storage = converter.toString(checkedArguments[1]);
395                 if ((storage.compare("EXTERNAL") != 0) && (storage.compare("INTERNAL") != 0)) {
396                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong second parameter type");
397                 }
398                 
399                 JSObjectRef eventCBObj = converter.toJSObjectRef(arguments[2]);
400                 JSValueRef onprogress = JSUtils::getJSPropertyOrUndefined(context, eventCBObj, "onprogress");
401                 JSValueRef oncomplete = JSUtils::getJSPropertyOrUndefined(context, eventCBObj, "oncomplete");   
402
403                 if (!JSObjectIsFunction(context, converter.toJSObjectRef(onprogress)) ||
404                         !JSObjectIsFunction(context, converter.toJSObjectRef(oncomplete))) {
405                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong third parameter type");
406                 }
407
408                 CallbackUserData *onprogressCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
409                 onprogressCb->setSuccessCallback(onprogress);
410
411                 CallbackUserData *oncompleteCb = new CallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context));
412                 oncompleteCb->setSuccessCallback(oncomplete);
413
414                 if (argumentCount > 2) {
415                         oncompleteCb->setErrorCallback(checkedArguments[3]);
416                 }
417
418                 PackageInstallEventCallback *pkgInstallEventCB = new PackageInstallEventCallback(onprogressCb, oncompleteCb);
419
420                 PackageManager::getInstance()->move(id, storage, pkgInstallEventCB);            
421
422         } Catch (NotFoundException) {
423         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
424         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
425         } Catch (ConversionException) {
426         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
427                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
428         } Catch (Exception) {
429         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
430                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
431         }
432
433         return JSValueMakeUndefined(context);
434 }
435
436
437 JSValueRef JSPackageManager::isInstalled(JSContextRef context, 
438         JSObjectRef object, 
439         JSObjectRef thisObject, 
440         size_t argumentCount,
441         const JSValueRef arguments[], 
442         JSValueRef* exception) 
443 {
444         LoggerD("entered");
445
446         //AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_IS_INSTALLED);
447         //TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
448
449         // Should I change first parameter to "undefined" or throw exception???
450         if (argumentCount < 1) {
451                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "wrong parameter");
452         }       
453
454         Try {
455                 WrtDeviceApis::CommonsJavaScript::Converter converter(context);
456                 string id = converter.toString(arguments[0]);
457
458                 return converter.toJSValueRef(PackageManager::getInstance()->isInstalled(id));
459     } Catch (NotFoundException) {
460         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
461         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
462         } Catch (ConversionException) {
463         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
464                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
465         } Catch (Exception) {
466         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
467                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
468         }
469
470         return false;
471 }
472
473 JSValueRef JSPackageManager::getPackageIdFromAppId(JSContextRef context,
474         JSObjectRef object,
475         JSObjectRef thisObject,
476         size_t argumentCount,
477         const JSValueRef arguments[],
478         JSValueRef* exception)
479 {
480         LoggerD("entered");
481
482         //AceSecurityStatus status = PACKAGE_CHECK_ACCESS(PACKAGE_FUNCTION_API_GET_PACKAGE_ID_FROM_APP_ID);
483         //TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
484
485         Try {
486                 WrtDeviceApis::CommonsJavaScript::Converter converter(context);
487                 string id;
488                 if (argumentCount > 0) {
489                         id = converter.toString(arguments[0]);
490                 } else {
491                         id = "undefined";
492                 }
493
494                 return converter.toJSValueRef(PackageManager::getInstance()->getPackageIdFromAppId(id));
495     } Catch (NotFoundException) {
496         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
497         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
498         } Catch (ConversionException) {
499         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
500                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
501         } Catch (Exception) {
502         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
503                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
504         }
505
506         return JSValueMakeUndefined(context);
507 }
508
509 #endif
510
511
512 }
513 }