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.
18 #include "JSFilesystemManager.h"
20 #include <dpl/log/log.h>
22 #include <Commons/Exception.h>
23 #include <API/Filesystem/EventResolve.h>
24 #include <API/Filesystem/IManager.h>
25 #include <API/Filesystem/IPath.h>
26 #include <API/Filesystem/EventGetStorage.h>
27 #include <API/Filesystem/EventListStorages.h>
28 #include <API/Filesystem/EventStorageStateChanged.h>
29 #include <CommonsJavaScript/JSCallbackManager.h>
30 #include <CommonsJavaScript/Utils.h>
31 #include <CommonsJavaScript/JSUtils.h>
32 #include <CommonsJavaScript/Validator.h>
33 #include <Tizen/Common/JSTizenExceptionFactory.h>
34 #include <Tizen/Common/JSTizenException.h>
35 #include <Tizen/Common/SecurityExceptions.h>
36 #include <Commons/WrtWrapper/WrtWrappersMgr.h>
37 #include <WidgetDB/WidgetDBMgr.h>
38 #include <WidgetDB/IWidgetDB.h>
41 #include "FilesystemUtils.h"
42 #include "Converter.h"
43 #include "EventGetNodeData.h"
44 #include "plugin_config.h"
45 #include "StorageStaticController.h"
46 #include "ResponseDispatcher.h"
48 using namespace WrtDeviceApis::Commons;
49 using namespace WrtDeviceApis::CommonsJavaScript;
50 using namespace TizenApis::Commons;
51 using namespace WrtDeviceApis;
52 using namespace TizenApis::Api::Filesystem;
56 const char* PLUGIN_NAME = "filesystem";
57 const char* PROPERTY_MAXPATHLENGTH = "maxPathLength";
59 JSValueRef getFunctionOrNull(JSContextRef ctx, JSValueRef arg)
61 if (Validator(ctx).isCallback(arg)) {
63 } else if (!JSValueIsNull(ctx, arg) && !JSValueIsUndefined(ctx, arg)) {
64 ThrowMsg(ConversionException, "Not a function nor JS null.");
70 JSValueRef getFunction(JSContextRef ctx, JSValueRef arg)
72 if (Validator(ctx).isCallback(arg)) {
74 } else if (JSValueIsNull(ctx, arg) || JSValueIsUndefined(ctx, arg)) {
75 ThrowMsg(InvalidArgumentException, "JS null passed as function.");
77 ThrowMsg(ConversionException, "Not a function nor JS null.");
87 JSClassRef JSFilesystemManager::m_classRef = 0;
89 JSClassDefinition JSFilesystemManager::m_classInfo = {
91 kJSClassAttributeNone,
109 JSStaticValue JSFilesystemManager::m_properties[] = {
110 { PROPERTY_MAXPATHLENGTH, getMaxPathLength, NULL, kJSPropertyAttributeReadOnly },
114 JSStaticFunction JSFilesystemManager::m_functions[] = {
115 { "resolve", JSFilesystemManager::resolve, kJSPropertyAttributeNone },
116 { "getStorage", JSFilesystemManager::getStorage, kJSPropertyAttributeNone },
117 { "listStorages", JSFilesystemManager::getStorageList, kJSPropertyAttributeNone },
118 { "addStorageStateChangeListener", JSFilesystemManager::addStorageStateListener, kJSPropertyAttributeNone },
119 { "removeStorageStateChangeListener", JSFilesystemManager::removeStorageStateListener, kJSPropertyAttributeNone },
123 const JSClassRef JSFilesystemManager::getClassRef()
126 m_classRef = JSClassCreate(&m_classInfo);
131 const JSClassDefinition* JSFilesystemManager::getClassInfo()
136 void JSFilesystemManager::initialize(JSContextRef context,
139 PrivateObject* privateObject = new PrivateObject(context);
140 if (!JSObjectSetPrivate(object, privateObject)) {
141 delete privateObject;
144 IWrtWrapperPtr wrt = WrtWrappersMgr::getInstance().getWrtWrapper(context);
145 WidgetDB::Api::IWidgetDBPtr widgetDB = WidgetDB::Api::getWidgetDB(wrt->getWidgetId());
147 Assert(wrt && "WrtWrapper not found, not a GLOBAL context supplied?");
149 LogDebug(widgetDB->getWidgetInstallationPath());
150 std::string wgtpackage = "wgt-package";
151 std::string wgtprivate = "wgt-private";
152 std::string wgtprivatetemp = "wgt-private-tmp";
154 Api::Filesystem::IManager::getInstance().addWidgetStorage(wgtpackage, widgetDB->getWidgetInstallationPath());
155 Api::Filesystem::IManager::getInstance().addWidgetStorage(wgtprivate, widgetDB->getWidgetPersistentStoragePath());
156 Api::Filesystem::IManager::getInstance().addWidgetStorage(wgtprivatetemp, widgetDB->getWidgetTemporaryStoragePath());
161 void JSFilesystemManager::finalize(JSObjectRef object)
163 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object));
165 JSObjectSetPrivate(object, NULL);
166 delete privateObject;
170 JSValueRef JSFilesystemManager::getMaxPathLength(JSContextRef context,
172 JSStringRef propertyName,
173 JSValueRef* exception)
175 ConverterPtr converter = ConverterFactory::getConverter(context);
177 return converter->toJSValueRef(Api::Filesystem::IManager::getInstance().getMaxPathLength());
178 } catch (const WrtDeviceApis::Commons::ConversionException& ex) {
179 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, "IO error");
181 return JSValueMakeUndefined(context);
184 JSValueRef JSFilesystemManager::getStorage(JSContextRef context,
186 JSObjectRef thisObject,
188 const JSValueRef argv[],
189 JSValueRef* exception)
191 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
192 if (!privateObject) {
193 return JSValueMakeUndefined(context);
197 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
200 JSContextRef globalContext = privateObject->getContext();
201 ConverterPtr converter = ConverterFactory::getConverter(globalContext);
205 JSValueRef onSuccess = getFunction(globalContext, argv[1]);
206 JSValueRef onError = NULL;
207 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext);
210 onError = getFunctionOrNull(globalContext, argv[2]);
213 cbm->setOnSuccess(onSuccess);
214 cbm->setOnError(onError);
216 if (JSValueIsNull(context, argv[0]) || JSValueIsUndefined(context, argv[0]) || !JSValueIsString(context, argv[0])) {
217 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid values error");
220 Api::Filesystem::EventGetStoragePtr event(new Api::Filesystem::EventGetStorage());
221 event->setLabel(converter->toString(argv[0]));
222 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
223 event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData > (cbm));
226 Api::Filesystem::IManager::getInstance().getStorage(event);
228 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
229 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
230 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
231 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
232 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
233 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
234 } catch(const WrtDeviceApis::Commons::Exception& ex) {
235 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
238 return JSValueMakeNull(context);
241 JSValueRef JSFilesystemManager::getStorageList(JSContextRef context,
243 JSObjectRef thisObject,
245 const JSValueRef argv[],
246 JSValueRef* exception)
248 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
249 if (!privateObject) {
250 return JSValueMakeUndefined(context);
254 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
258 JSContextRef globalContext = privateObject->getContext();
259 ConverterPtr converter = ConverterFactory::getConverter(globalContext);
263 JSValueRef onSuccess = getFunction(globalContext, argv[0]);
264 JSValueRef onError = NULL;
265 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext);
268 onError = getFunctionOrNull(globalContext, argv[1]);
271 cbm->setOnSuccess(onSuccess);
272 cbm->setOnError(onError);
275 Api::Filesystem::EventListStoragesPtr event(new Api::Filesystem::EventListStorages());
276 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
277 event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData > (cbm));
278 Api::Filesystem::IManager::getInstance().listStorages(event);
280 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
281 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
282 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
283 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
284 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
285 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
286 } catch(const WrtDeviceApis::Commons::Exception& ex) {
287 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
290 return JSValueMakeNull(context);
293 JSValueRef JSFilesystemManager::addStorageStateListener(JSContextRef context,
295 JSObjectRef thisObject,
297 const JSValueRef argv[],
298 JSValueRef* exception)
300 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
301 if (!privateObject) {
302 return JSValueMakeUndefined(context);
306 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
309 JSContextRef globalContext = privateObject->getContext();
310 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext);
311 ConverterPtr converter = ConverterFactory::getConverter(globalContext);
314 if (JSValueIsNull(context, argv[0]) || JSValueIsUndefined(context, argv[0])) {
315 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid values error"));
316 return JSValueMakeNull(context);
317 } else if (!JSObjectIsFunction(context, converter->toJSObjectRef(argv[0]))) {
318 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
320 cbm->setOnSuccess(argv[0]);
322 Api::Filesystem::EventStorageStateChangedEmitterPtr emitter(new Api::Filesystem::EventStorageStateChangedEmitter);
323 emitter->setListener(&StorageStaticController::getInstance());
324 emitter->setEventPrivateData(DPL::StaticPointerCast<Api::Filesystem::EventStorageStateChanged::PrivateDataType>(cbm));
325 long id = Api::Filesystem::IManager::getInstance().addStorageStateChangeListener(emitter);
326 return converter->toJSValueRefLong(id);
327 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
328 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
329 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
330 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
331 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
332 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
333 } catch(const WrtDeviceApis::Commons::Exception& ex) {
334 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
337 return JSValueMakeUndefined(context);
340 JSValueRef JSFilesystemManager::removeStorageStateListener(JSContextRef context,
342 JSObjectRef thisObject,
344 const JSValueRef argv[],
345 JSValueRef* exception)
347 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
348 if (!privateObject) {
349 return JSValueMakeUndefined(context);
353 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
356 if (!JSValueIsNumber(context, argv[0])) {
357 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
360 JSContextRef globalContext = privateObject->getContext();
361 ConverterPtr converter = ConverterFactory::getConverter(globalContext);
364 long id = static_cast<long>(converter->toLong(argv[0]));
367 Api::Filesystem::IManager::getInstance().removeStorageStateChangeListener(id);
369 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
370 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
371 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
372 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
373 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
374 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
375 } catch(const WrtDeviceApis::Commons::Exception& ex) {
376 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
379 return JSValueMakeUndefined(context);
382 JSValueRef JSFilesystemManager::resolve(JSContextRef context,
384 JSObjectRef thisObject,
386 const JSValueRef argv[],
387 JSValueRef* exception)
389 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
390 if (!privateObject) {
391 return JSValueMakeUndefined(context);
395 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
398 JSContextRef globalContext = privateObject->getContext();
399 ConverterPtr converter = ConverterFactory::getConverter(globalContext);
403 JSValueRef onSuccess = getFunction(globalContext, argv[1]);
404 JSValueRef onError = NULL;
405 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext);
408 onError = getFunctionOrNull(globalContext, argv[2]);
411 cbm->setOnSuccess(onSuccess);
412 cbm->setOnError(onError);
414 Api::Filesystem::IPathPtr path = Utils::fromVirtualPath(globalContext, converter->toString(argv[0]));
415 std::string virtualPath = converter->toString(argv[0]);
417 int permissions = Api::Filesystem::PERM_READ | Api::Filesystem::PERM_WRITE;
420 if (!JSValueIsNull(context, argv[3]) && !JSValueIsUndefined(context, argv[3])) {
421 std::string perms = converter->toString(argv[3]);
422 if (("r" != perms) && ("rw" != perms) && ("w" != perms) && ("a" != perms)) {
423 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid values error");
424 } else if ("r" == perms) {
425 permissions = Api::Filesystem::PERM_READ;
430 PermissionsAccessInfo perms(permissions, virtualPath);
431 AceSecurityStatus status = FILESYSTEM_PERMISSION_CHECK_ACCESS(
432 privateObject->getContext(),
433 FILESYSTEM_FUNCTION_API_MGR_RESOLVE_ID,
436 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
438 EventGetNodeDataPtr data(new EventGetNodeData(permissions, cbm));
439 Api::Filesystem::EventResolvePtr event(new Api::Filesystem::EventResolve(path));
440 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
441 event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData > (data));
442 Api::Filesystem::IManager::getInstance().getNode(event);
444 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
445 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
446 } catch(const WrtDeviceApis::Commons::NotFoundException& ex) {
447 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, ex.GetMessage());
448 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
449 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
450 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
451 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
452 } catch(const WrtDeviceApis::Commons::Exception& ex) {
453 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
456 return JSValueMakeNull(context);