2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <CommonsJavaScript/Converter.h>
20 #include <CommonsJavaScript/Validator.h>
21 #include <CommonsJavaScript/JSUtils.h>
22 #include <CommonsJavaScript/JSCallbackManager.h>
23 #include <CommonsJavaScript/Utils.h>
24 #include <Tizen/Common/SecurityExceptions.h>
25 #include <Commons/Exception.h>
26 #include <Tizen/Common/JSTizenExceptionFactory.h>
27 #include <Tizen/Common/JSTizenException.h>
28 #include <API/Application/ApplicationFactory.h>
29 #include <API/Application/EventListInstalledApplications.h>
30 #include <API/Application/EventGetApplication.h>
31 #include <API/Application/EventLaunchService.h>
32 #include "plugin_config.h"
33 #include "ApplicationAnswerReceiver.h"
34 #include "ApplicationListener.h"
35 #include "JSApplication.h"
36 #include "ApplicationConverter.h"
37 #include "ApplicationServiceReplyCallback.h"
38 #include "LaunchServicePrivateData.h"
39 #include "JSApplicationServiceRequest.h"
40 #include "JSApplicationServiceReply.h"
45 namespace Application {
49 using namespace TizenApis::Api::Application;
50 using namespace TizenApis::Commons;
52 using namespace WrtDeviceApis;
53 using namespace WrtDeviceApis::Commons;
54 using namespace WrtDeviceApis::CommonsJavaScript;
56 JSClassRef JSApplication::m_jsClassRef = NULL;
58 JSClassDefinition JSApplication::m_classInfo = {
60 kJSClassAttributeNone,
70 NULL, //deleteProperty,Geolocation
71 NULL, //getPropertyNames,
78 JSStaticFunction JSApplication::m_function[] = {
79 { "listInstalledApplications",JSApplication::listInstalledApplications,kJSPropertyAttributeNone },
80 { "listRunningApplications",JSApplication::listRunningApplications,kJSPropertyAttributeNone },
81 { "getApplicationInformation",JSApplication::getApplicationInformation,kJSPropertyAttributeNone },
82 { "addApplicationListChangeListener",JSApplication::addApplicationListChangeListener,kJSPropertyAttributeNone },
83 { "removeApplicationListChangeListener",JSApplication::removeApplicationListChangeListener,kJSPropertyAttributeNone },
84 { "launchService",JSApplication::launchService,kJSPropertyAttributeNone },
88 const JSClassRef JSApplication::getClassRef() {
90 m_jsClassRef = JSClassCreate(&m_classInfo);
95 const JSClassDefinition* JSApplication::getClassInfo() {
99 void JSApplication::initialize(JSContextRef context, JSObjectRef object) {
100 JSApplicationPriv* priv = static_cast<JSApplicationPriv*>(JSObjectGetPrivate(object));
101 assert(!priv && "Invalid object creation.");
102 IApplicationPtr applications(ApplicationFactory::getInstance().createApplication());
103 priv = new JSApplicationPriv(context, applications);
104 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
105 LogError("Object can't store private data.");
110 void JSApplication::finalize(JSObjectRef object) {
111 JSApplicationPriv* priv = static_cast<JSApplicationPriv*> (JSObjectGetPrivate(object));
112 JSObjectSetPrivate(object, NULL);
116 bool JSApplication::hasInstance(JSContextRef context,
117 JSObjectRef constructor,
118 JSValueRef possibleInstance,
119 JSValueRef* exception)
121 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
124 JSValueRef JSApplication::listInstalledApplications(JSContextRef context,
126 JSObjectRef thisObject,
127 size_t argumentCount,
128 const JSValueRef arguments[],
129 JSValueRef* exception)
131 JSApplicationPriv *priv = static_cast<JSApplicationPriv*> (JSObjectGetPrivate(thisObject));
132 assert(priv && "Invalid private pointer.");
133 JSContextRef gContext = priv->getContext();
135 AceSecurityStatus status = APPLICATION_CHECK_ACCESS(
137 APPLICATION_FUNCTION_API_LIST_INSTALLED_APPLICATIONS);
138 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
140 ApplicationConverterFactory::ConverterType converter = ApplicationConverterFactory::getConverter(context);
142 if ((argumentCount == 0) ||
143 (JSValueIsNull(context,
145 JSValueIsUndefined(context,
147 !JSObjectIsFunction(context,
148 converter->toJSObjectRef(arguments[0]))) ||
149 (argumentCount > 1 &&
150 !JSValueIsNull(context,
152 !JSValueIsUndefined(context,
154 !JSObjectIsFunction(context,
155 converter->toJSObjectRef(arguments[1])))) {
156 LogError("Wrong callbacks parameters");
157 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
160 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
161 callbackManager->setOnSuccess(arguments[0]);
162 if (argumentCount > 1)
163 callbackManager->setOnError(arguments[1]);
165 EventListInstalledApplicationsPtr event(new EventListInstalledApplications());
167 IApplicationPtr applications(priv->getObject());
168 event->setEventType(EventListInstalledApplications::APPMANAGER_LIST_INSTALLED_APPLICATIONS);
169 event->setPrivateData(StaticPointerCast<IEventPrivateData>(callbackManager));
170 event->setForAsynchronousCall(new ApplicationAnswerReceiver(callbackManager));
171 applications->listApplications(event);
172 }Catch (WrtDeviceApis::Commons::ConversionException){
173 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
174 }Catch (WrtDeviceApis::Commons::PendingOperationException){
175 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::INVALID_VALUES_ERROR,"Pending operation failed"));
176 return JSValueMakeUndefined(context);
177 }Catch (WrtDeviceApis::Commons::InvalidArgumentException){
178 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::INVALID_VALUES_ERROR,"Invalid value error"));
179 return JSValueMakeUndefined(context);
180 }Catch (WrtDeviceApis::Commons::NullPointerException){
181 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::UNKNOWN_ERROR,"Unknown error"));
182 return JSValueMakeUndefined(context);
183 }Catch(WrtDeviceApis::Commons::Exception){
184 LogError("Exception: " << _rethrown_exception.GetMessage() << " Code: " << _rethrown_exception.getCode());
185 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
187 return JSValueMakeUndefined(context);
190 JSValueRef JSApplication::listRunningApplications(JSContextRef context,
192 JSObjectRef thisObject,
193 size_t argumentCount,
194 const JSValueRef arguments[],
195 JSValueRef* exception)
197 JSApplicationPriv *priv = static_cast<JSApplicationPriv*> (JSObjectGetPrivate(thisObject));
199 assert(priv && "Invalid private pointer.");
200 JSContextRef gContext = priv->getContext();
202 AceSecurityStatus status = APPLICATION_CHECK_ACCESS(
204 APPLICATION_FUNCTION_API_LIST_RUNNING_APPLICATIONS);
205 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
207 ApplicationConverterFactory::ConverterType converter = ApplicationConverterFactory::getConverter(context);
209 if ((argumentCount == 0) ||
210 (JSValueIsNull(context,
212 JSValueIsUndefined(context,
214 !JSObjectIsFunction(context,
215 converter->toJSObjectRef(arguments[0]))) ||
216 (argumentCount > 1 &&
217 !JSValueIsNull(context,
219 !JSValueIsUndefined(context,
221 !JSObjectIsFunction(context,
222 converter->toJSObjectRef(arguments[1])))) {
223 LogError("Wrong callbacks parameters");
224 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
227 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
228 callbackManager->setOnSuccess(arguments[0]);
229 if (argumentCount > 1)
230 callbackManager->setOnError(arguments[1]);
232 EventListInstalledApplicationsPtr event(new EventListInstalledApplications());
234 IApplicationPtr applications(priv->getObject());
235 event->setEventType(EventListInstalledApplications::APPMANAGER_LIST_RUNNING_APPLICATIONS);
236 event->setPrivateData(StaticPointerCast<IEventPrivateData>(callbackManager));
237 event->setForAsynchronousCall(new ApplicationAnswerReceiver(callbackManager));
238 applications->listApplications(event);
239 }Catch (WrtDeviceApis::Commons::ConversionException){
240 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
241 }Catch (WrtDeviceApis::Commons::PendingOperationException){
242 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::INVALID_VALUES_ERROR,"Pending operation failed"));
243 return JSValueMakeUndefined(context);
244 }Catch (WrtDeviceApis::Commons::InvalidArgumentException){
245 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::INVALID_VALUES_ERROR,"Invalid value error"));
246 return JSValueMakeUndefined(context);
247 }Catch (WrtDeviceApis::Commons::NullPointerException){
248 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::UNKNOWN_ERROR,"Unknown error"));
249 return JSValueMakeUndefined(context);
250 }Catch(WrtDeviceApis::Commons::Exception){
251 LogError("Exception: " << _rethrown_exception.GetMessage() << " Code: " << _rethrown_exception.getCode());
252 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
254 return JSValueMakeUndefined(context);
257 JSValueRef JSApplication::getApplicationInformation(JSContextRef context,
259 JSObjectRef thisObject,
260 size_t argumentCount,
261 const JSValueRef arguments[],
262 JSValueRef* exception)
264 JSApplicationPriv *priv = static_cast<JSApplicationPriv*> (JSObjectGetPrivate(thisObject));
266 assert(priv && "Invalid private pointer.");
267 AceSecurityStatus status = APPLICATION_CHECK_ACCESS(
269 APPLICATION_FUNCTION_API_GET_APPLICATION_INFORMATION);
270 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
271 ApplicationConverterFactory::ConverterType converter = ApplicationConverterFactory::getConverter(context);
273 if(JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0])){
274 LogError("Wrong package " << JSValueIsNull(context, arguments[0]) <<", "<<JSValueIsUndefined(context, arguments[0]));
275 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
278 EventGetApplicationPtr event(new EventGetApplication());
279 JSValueRef jsobj = NULL;
287 package = converter->toString( arguments[0] );
288 IApplicationPtr applications(priv->getObject());
289 event->setForSynchronousCall();
290 event->setPackage(package);
291 applications->getApplicationInformation(event);
292 if (event->getExceptionCode() == WrtDeviceApis::Commons::ExceptionCodes::NotFoundException) {
293 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::NOT_FOUND_ERROR, "Given package is not found");
295 jsobj = converter->toJSValueRef(event->getApplicationInformation());
296 }Catch (WrtDeviceApis::Commons::ConversionException){
297 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
298 }Catch (WrtDeviceApis::Commons::InvalidArgumentException){
299 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::INVALID_VALUES_ERROR,"Invalid value error");
300 }Catch (WrtDeviceApis::Commons::NullPointerException){
301 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
302 }Catch(WrtDeviceApis::Commons::Exception){
303 LogError("Exception: " << _rethrown_exception.GetMessage() << " Code: " << _rethrown_exception.getCode());
304 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
309 JSValueRef JSApplication::addApplicationListChangeListener(JSContextRef context,
311 JSObjectRef thisObject,
312 size_t argumentCount,
313 const JSValueRef arguments[],
314 JSValueRef* exception)
316 JSApplicationPriv *priv = static_cast<JSApplicationPriv*> (JSObjectGetPrivate(thisObject));
318 assert(priv && "Invalid private pointer.");
319 AceSecurityStatus status = APPLICATION_CHECK_ACCESS(
321 APPLICATION_FUNCTION_API_ADD_APPLICATION_LIST_CHANGE_LISTENER);
322 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
323 CommonsJavaScript::Converter converter(context);
325 if ((argumentCount == 0) ||
326 (JSValueIsNull(context,
328 JSValueIsUndefined(context,
330 !JSObjectIsFunction(context,
331 converter.toJSObjectRef(arguments[0]))) ||
332 (argumentCount > 1 &&
333 !JSValueIsNull(context,
335 !JSValueIsUndefined(context,
337 !JSObjectIsFunction(context,
338 converter.toJSObjectRef(arguments[1])))) {
339 LogError("Wrong callbacks parameters");
340 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
342 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(priv->getContext());
343 callbackManager->setOnSuccess(arguments[0]);
344 if (argumentCount >= 2)
345 callbackManager->setOnError(arguments[1]);
348 IApplicationPtr applications(priv->getObject());
349 EventInstalledApplicationChangedEmitterPtr emitter(new EventInstalledApplicationChangedEmitter);
350 emitter->setListener(&ApplicationListener::getInstance());
351 emitter->setEventPrivateData(StaticPointerCast<EventInstalledApplicationChanged::PrivateDataType>(callbackManager));
352 unsigned long id = applications->addApplicationListChangeListener(emitter);
353 LogInfo("id = "<<id);
355 Throw(WrtDeviceApis::Commons::UnsupportedException);
357 return converter.toJSValueRef(id);
358 }Catch (WrtDeviceApis::Commons::ConversionException){
359 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
360 }Catch (WrtDeviceApis::Commons::UnsupportedException){
361 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::NOT_SUPPORTED_ERROR, "Not supported or already registered");
362 }Catch (WrtDeviceApis::Commons::InvalidArgumentException){
363 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::INVALID_VALUES_ERROR,"Invalid value error"));
364 return JSValueMakeUndefined(context);
365 }Catch (WrtDeviceApis::Commons::NullPointerException){
366 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::UNKNOWN_ERROR,"Unknown error"));
367 return JSValueMakeUndefined(context);
368 }Catch(WrtDeviceApis::Commons::Exception){
369 LogError("Exception: " << _rethrown_exception.GetMessage() << " Code: " << _rethrown_exception.getCode());
370 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
374 JSValueRef JSApplication::removeApplicationListChangeListener(JSContextRef context,
376 JSObjectRef thisObject,
377 size_t argumentCount,
378 const JSValueRef arguments[],
379 JSValueRef* exception)
381 JSApplicationPriv *priv = static_cast<JSApplicationPriv*>(JSObjectGetPrivate(thisObject));
382 assert(priv && "Invalid private pointer.");
383 AceSecurityStatus status = APPLICATION_CHECK_ACCESS(
385 APPLICATION_FUNCTION_API_REMOVE_APPLICATION_LIST_CHANGE_LISTENER);
386 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
387 CommonsJavaScript::Converter converter(context);
390 IApplicationPtr applications = priv->getObject();
391 assert(applications && "Application object not present.");
393 if (argumentCount < 1) {
394 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
397 long id = converter.toLong(arguments[0]);
398 applications->removeApplicationListChangeListener(id);
399 }Catch (WrtDeviceApis::Commons::InvalidArgumentException){
400 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
401 }Catch (WrtDeviceApis::Commons::ConversionException){
402 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
403 }Catch (WrtDeviceApis::Commons::NullPointerException){
404 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
405 }Catch(WrtDeviceApis::Commons::Exception){
406 LogError("Exception: " << _rethrown_exception.GetMessage() << " Code: " << _rethrown_exception.getCode());
407 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
409 return JSValueMakeUndefined(context);
412 JSValueRef JSApplication::launchService(JSContextRef context,
414 JSObjectRef thisObject,
415 size_t argumentCount,
416 const JSValueRef arguments[],
417 JSValueRef* exception)
419 LogInfo("launchService <<<");
420 LogDebug("argumentConunt:" << argumentCount);
421 JSApplicationPriv *priv = static_cast<JSApplicationPriv*> (JSObjectGetPrivate(thisObject));
422 assert(priv && "Invalid private pointer.");
423 AceSecurityStatus status = APPLICATION_CHECK_ACCESS(
425 APPLICATION_FUNCTION_API_LAUNCH_SERVICE);
426 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
427 JSContextRef gContext = priv->getContext();
429 ApplicationConverterFactory::ConverterType converter = ApplicationConverterFactory::getConverter(context);
431 if ((argumentCount < 2) ||
432 (JSValueIsNull(context,
434 JSValueIsUndefined(context,
436 JSValueIsNull(context,
438 JSValueIsUndefined(context,
440 !JSObjectIsFunction(context,
441 converter->toJSObjectRef(arguments[1]))) ||
442 (argumentCount > 2 &&
443 !JSValueIsNull(context,
445 !JSValueIsUndefined(context,
447 !JSObjectIsFunction(context,
448 converter->toJSObjectRef(arguments[2])))) {
449 LogError("Wrong parameters");
450 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
453 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
454 callbackManager->setOnSuccess(arguments[1]);
455 if (argumentCount > 2)
456 callbackManager->setOnError(arguments[2]);
459 ApplicationServiceRequestPtr appService;
460 ApplicationConverterFactory::ConverterType converter = ApplicationConverterFactory::getConverter(context);
461 appService = converter->toApplicationServiceRequest(arguments[0]);
463 LogDebug("after toApplicationServiceRequest()");
464 // arguments[3] : optional , onsuccess, onfail, oncancel
465 JSCallbackManagerPtr replyCallbackManager;
466 JSCallbackManagerPtr replyCancelCallbackManager;
467 if( argumentCount >3)
469 CommonsJavaScript::Validator validator(gContext);
470 ApplicationServiceReplyCallback result;
472 JSObjectRef obj = JSValueToObject(context, arguments[3],NULL);
474 result.onsuccess = JSUtils::getJSProperty(
475 context, obj, "onsuccess");
476 if (!validator.isNullOrUndefined(result.onsuccess) &&
477 !validator.isCallback(result.onsuccess)) {
478 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
481 result.onfail = JSUtils::getJSProperty(
482 context, obj, "onfail");
483 if (!validator.isNullOrUndefined(result.onfail) &&
484 !validator.isCallback(result.onfail)) {
485 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
488 result.oncancel = JSUtils::getJSProperty(
489 context, obj, "oncancel");
490 if (!validator.isNullOrUndefined(result.oncancel) &&
491 !validator.isCallback(result.oncancel)) {
492 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
495 if(result.onsuccess || result.onfail)
497 replyCallbackManager = JSCallbackManager::createObject(priv->getContext(),
498 result.onsuccess, result.onfail);
503 replyCancelCallbackManager = JSCallbackManager::createObject(priv->getContext(),
504 result.oncancel, NULL);
509 LogDebug("replyCallback, replyCancel"<<callbackManager<<replyCallbackManager<<replyCancelCallbackManager);
511 LaunchServicePrivateDataPtr privateData(
512 new LaunchServicePrivateData(callbackManager,replyCallbackManager,replyCancelCallbackManager));
515 LogDebug("after LaunchServicePrivateData()");
518 EventLaunchServicePtr event(new EventLaunchService());
520 IApplicationPtr applications(priv->getObject());
522 event->setPrivateData(StaticPointerCast<IEventPrivateData> (privateData));
523 event->setServiceRequest(appService);
524 event->setForAsynchronousCall(new ApplicationAnswerReceiver(privateData));
526 applications->launchService(event);
527 }Catch (WrtDeviceApis::Commons::ConversionException){
528 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::TYPE_MISMATCH_ERROR, "Type mistmatch error");
529 }Catch (WrtDeviceApis::Commons::UnsupportedException){
530 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::NOT_SUPPORTED_ERROR, "Not supported");
531 }Catch (WrtDeviceApis::Commons::InvalidArgumentException){
532 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::INVALID_VALUES_ERROR,"Invalid value error"));
533 return JSValueMakeUndefined(context);
534 }Catch (WrtDeviceApis::Commons::NullPointerException){
535 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context,JSTizenException::UNKNOWN_ERROR,"Unknown error"));
536 return JSValueMakeUndefined(context);
537 }Catch(WrtDeviceApis::Commons::Exception){
538 LogError("Exception: " << _rethrown_exception.GetMessage() << " Code: " << _rethrown_exception.getCode());
539 return JSTizenExceptionFactory::postException(context, exception,JSTizenException::UNKNOWN_ERROR, "Unknown error");
542 return JSValueMakeUndefined(context);