Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Call / Converter.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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. 
15  */
16
17  
18 #include "Converter.h"
19 #include <dpl/log/log.h>
20
21 #include <Commons/Exception.h>
22 #include <CommonsJavaScript/Validator.h>
23 #include <CommonsJavaScript/ScopedJSStringRef.h>
24 #include <CommonsJavaScript/JSUtils.h>
25 #include <CommonsJavaScript/JSCallbackManager.h>
26 #include "JSCallHistoryEntry.h"
27 #include "JSRemoteParty.h"
28 #include "JSCallService.h"
29 #include "JSCellularCallService.h"
30
31 #define CH_ENTRY_ID                             "entryId"
32 #define CH_SERVICE_ID                   "serviceId"
33 #define CH_CALL_TYPE                    "callType"
34 #define CH_TAGS                                 "tags"
35 #define CH_REMOTE_PARTIES               "remoteParties"
36 #define CH_FORWARDEDFROM                "forwardedFrom"
37 #define CH_START_TIME                   "startTime"
38 #define CH_DURATION                     "duration"
39 #define CH_END_REASON                   "endReason"
40 #define CH_DIRECTION                    "direction"
41 #define CH_RECORDING                    "recording"
42 #define CH_COST                                 "cost"
43 #define CH_CURRENCY                             "currency"
44
45 #define CH_REMOTE_PARTY         "remoteParty"
46 #define CH_DISPLAY_NAME         "displayName"
47 #define CH_CONTACT_ID                   "contactId"
48
49 #define CH_SERVICETYPE_ID               "serviceTypeId"
50 #define CH_SERVICENAME                  "serviceName"
51 #define CH_PROVIDER_ID                  "providerId"
52
53 using namespace WrtDeviceApis;
54 using namespace WrtDeviceApis::Commons;
55 using namespace WrtDeviceApis::CommonsJavaScript;
56 using namespace TizenApis::Api::Call;
57
58 namespace TizenApis {
59 namespace Tizen1_0 {
60 std::vector<std::string> Converter::m_allowedCallHistoryEntryProperties;
61 std::vector<std::string> Converter::m_allowedRemoteParty;
62 std::vector<std::string> Converter::m_allowedCallServiceFilter;
63
64 Converter::Converter(JSContextRef context) : WrtDeviceApis::CommonsJavaScript::Converter(context)
65 {
66         static bool init = initializeAllowedProperties();
67         (void) init;
68 }
69
70 std::vector<unsigned long> Converter::toVectorOfULongs(const JSValueRef& arg)
71 {
72     return toVectorOfT_(arg, &Converter::toULong);
73 }
74
75 CallHistoryEntryList Converter::toVectorOfCallHistoryEntryProperties(const JSValueRef& arg)
76 {
77         if (JSValueIsNull(m_context, arg) || JSValueIsUndefined(m_context, arg)) {
78                 ThrowMsg(Commons::InvalidArgumentException, "Undefined history entry");
79         }
80
81         if (!JSIsArrayValue(m_context, arg)) {
82                 ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
83         }
84
85         try {
86                 CallHistoryEntryList result;
87                 JSObjectRef objArg = toJSObjectRef(arg);
88                 for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
89                         JSValueRef element = JSGetArrayElement(m_context, objArg, i);
90                         result.push_back(toCallHistoryEntryProperties(element));
91                 }
92                 return result;
93         } catch (Commons::ConversionException& ex) {
94                 ThrowMsg(Commons::ConversionException, ex.GetMessage());
95         } catch (Commons::InvalidArgumentException& ex) {
96                 ThrowMsg(Commons::InvalidArgumentException, ex.GetMessage());
97         } catch (Commons::Exception& ex) {
98                 ThrowMsg(Commons::Exception, ex.GetMessage());
99         }
100
101 }
102
103 StringArrayPtr Converter::toStringArray(const JSValueRef &jsValue)
104 {
105         StringArrayPtr result(new StringArray());
106         try {
107                 if (!JSValueIsNull(m_context, jsValue)) {
108                         JSObjectRef jsObject = toJSObjectRef(jsValue);
109                         
110                         for (std::size_t i = 0; i < JSGetArrayLength(m_context, jsObject); ++i) {
111                                 JSValueRef element = JSGetArrayElement(m_context, jsObject, i);
112                                 result->push_back(toString(element));
113                         }
114                 }
115         } catch (Commons::Exception& ex) {
116                 LogError("Exception: " << ex.GetMessage());
117         }
118         return result;
119 }
120
121 RemotePartyListPtr Converter::toRemotePartyList(const JSValueRef &jsValue)
122 {
123         RemotePartyListPtr result(new RemotePartyList());
124         try {
125                 if (!JSValueIsNull(m_context, jsValue)) {
126                         JSObjectRef jsObject = toJSObjectRef(jsValue);
127                         
128                         for (std::size_t i = 0; i < JSGetArrayLength(m_context, jsObject); ++i) {
129                                 JSValueRef element = JSGetArrayElement(m_context, jsObject, i);
130                                 result->push_back(toRemoteParty(element));
131                         }
132                 }
133         } catch (Commons::Exception& ex) {
134                 LogError("Exception: " << ex.GetMessage());
135         }
136         return result;
137 }
138
139 RemotePartyPtr Converter::toRemoteParty(const JSValueRef &jsValue)
140 {
141         Validator validator(m_context);
142         if (!validator.checkArrayKeys(m_allowedRemoteParty, jsValue)) {
143                 ThrowMsg(Commons::InvalidArgumentException, "Wrong attribute of RemoteParty");
144         }
145
146         const ScopedJSStringRef remotePartyStr(JSStringCreateWithUTF8CString(CH_REMOTE_PARTY));
147         const ScopedJSStringRef displayNameStr(JSStringCreateWithUTF8CString(CH_DISPLAY_NAME));
148         const ScopedJSStringRef contactIdStr(JSStringCreateWithUTF8CString(CH_CONTACT_ID));
149
150         JSObjectRef jsObject = toJSObjectRef(jsValue);
151
152         JSValueRef jRemoteParty = JSObjectGetProperty(m_context, jsObject, remotePartyStr.get(), NULL);
153         JSValueRef jDisplayName = JSObjectGetProperty(m_context, jsObject, displayNameStr.get(), NULL);
154         JSValueRef jContactId = JSObjectGetProperty(m_context, jsObject, contactIdStr.get(), NULL);
155
156         std::string remoteParty;
157         std::string displayName;
158         std::string contactId;
159
160         RemotePartyPtr result(new RemoteParty());
161
162         if (!result) {
163                 Throw(Commons::ConversionException);
164         }
165
166         if (!JSValueIsUndefined(m_context, jRemoteParty)) {
167                 remoteParty = toString(jRemoteParty);
168                 result->setRemoteParty(remoteParty);
169         }
170
171         if (!JSValueIsUndefined(m_context, jDisplayName)) {
172                 displayName = toString(jDisplayName);
173                 result->setDisplayName(displayName);
174         }
175
176         if (!JSValueIsUndefined(m_context, jContactId)) {
177                 contactId = toString(jContactId);
178                 result->setContactId(contactId);
179         }
180
181         return result;
182 }
183
184 CallServiceFilterPtr Converter::toCallServiceFilter(const JSValueRef &jsValue)
185 {
186         Validator validator(m_context);
187         if (!validator.checkArrayKeys(m_allowedCallServiceFilter, jsValue)) {
188                 ThrowMsg(Commons::InvalidArgumentException, "Wrong attribute of RemoteParty");
189         }
190
191         const ScopedJSStringRef serviceTypeIdStr(JSStringCreateWithUTF8CString(CH_SERVICETYPE_ID));
192         const ScopedJSStringRef tagsStr(JSStringCreateWithUTF8CString(CH_TAGS));
193         const ScopedJSStringRef serviceNameStr(JSStringCreateWithUTF8CString(CH_SERVICENAME));
194         const ScopedJSStringRef providerIdStr(JSStringCreateWithUTF8CString(CH_PROVIDER_ID));
195
196         JSObjectRef jsObject = toJSObjectRef(jsValue);
197
198         JSValueRef jServiceTypeId = JSObjectGetProperty(m_context, jsObject, serviceTypeIdStr.get(), NULL);
199         JSValueRef jTags = JSObjectGetProperty(m_context, jsObject, tagsStr.get(), NULL);
200         JSValueRef jServiceName = JSObjectGetProperty(m_context, jsObject, serviceNameStr.get(), NULL);
201         JSValueRef jProviderId = JSObjectGetProperty(m_context, jsObject, providerIdStr.get(), NULL);
202
203         std::string serviceTypeId;
204         StringArrayPtr tags;
205         std::string serviceName;
206         std::string providerId;
207
208         CallServiceFilterPtr result(new CallServiceFilter());
209
210         if (!result) {
211                 Throw(Commons::ConversionException);
212         }
213
214         if (!JSValueIsUndefined(m_context, jServiceTypeId)) {
215                 serviceTypeId = toString(jServiceTypeId);
216                 result->setServiceTypeId(serviceTypeId);
217         }
218
219         if (!JSValueIsUndefined(m_context, jTags)) {
220                 tags = toStringArray(jProviderId);
221                 result->setTags(tags);
222         }
223
224         if (!JSValueIsUndefined(m_context, jServiceName)) {
225                 serviceName = toString(jServiceName);
226                 result->setServiceName(serviceName);
227         }
228
229         if (!JSValueIsUndefined(m_context, jProviderId)) {
230                 providerId = toString(jProviderId);
231                 result->setProviderId(providerId);
232         }
233
234         return result;
235 }
236
237 CallHistoryEntryPropertiesPtr Converter::toCallHistoryEntryProperties(const JSValueRef &jsValue)
238 {
239         Validator validator(m_context);
240         if (!validator.checkArrayKeys(m_allowedCallHistoryEntryProperties, jsValue)) {
241                 ThrowMsg(Commons::InvalidArgumentException, "Wrong attribute of call history entry");
242         }
243
244         const ScopedJSStringRef entryIdStr(JSStringCreateWithUTF8CString(CH_ENTRY_ID));
245         const ScopedJSStringRef serviceIdStr(JSStringCreateWithUTF8CString(CH_SERVICE_ID));
246         const ScopedJSStringRef callTypeStr(JSStringCreateWithUTF8CString(CH_CALL_TYPE));
247         const ScopedJSStringRef tagsStr(JSStringCreateWithUTF8CString(CH_TAGS));
248         const ScopedJSStringRef remotePartiesStr(JSStringCreateWithUTF8CString(CH_REMOTE_PARTIES));
249         const ScopedJSStringRef forwardedFromStr(JSStringCreateWithUTF8CString(CH_FORWARDEDFROM));
250         const ScopedJSStringRef startTimeStr(JSStringCreateWithUTF8CString(CH_START_TIME));
251         const ScopedJSStringRef durationStr(JSStringCreateWithUTF8CString(CH_DURATION));
252         const ScopedJSStringRef endReasonStr(JSStringCreateWithUTF8CString(CH_END_REASON));
253         const ScopedJSStringRef directionStr(JSStringCreateWithUTF8CString(CH_DIRECTION));
254         const ScopedJSStringRef recordingStr(JSStringCreateWithUTF8CString(CH_RECORDING));
255         const ScopedJSStringRef costStr(JSStringCreateWithUTF8CString(CH_COST));
256         const ScopedJSStringRef currencyStr(JSStringCreateWithUTF8CString(CH_CURRENCY));
257
258         JSObjectRef jsObject = toJSObjectRef(jsValue);
259
260         JSValueRef jEntryId = JSObjectGetProperty(m_context, jsObject, entryIdStr.get(), NULL);
261         JSValueRef jServiceId = JSObjectGetProperty(m_context, jsObject, serviceIdStr.get(), NULL);
262         JSValueRef jCallType = JSObjectGetProperty(m_context, jsObject, callTypeStr.get(), NULL);
263         JSValueRef jTags = JSObjectGetProperty(m_context, jsObject, tagsStr.get(), NULL);
264         JSValueRef jRemoteParties = JSObjectGetProperty(m_context, jsObject, remotePartiesStr.get(), NULL);
265         JSValueRef jForwardedFrom = JSObjectGetProperty(m_context, jsObject, forwardedFromStr.get(), NULL);
266         JSValueRef jStartTime = JSObjectGetProperty(m_context, jsObject, startTimeStr.get(), NULL);
267         JSValueRef jDuration = JSObjectGetProperty(m_context, jsObject, durationStr.get(), NULL);
268         JSValueRef jEndReason = JSObjectGetProperty(m_context, jsObject, endReasonStr.get(), NULL);
269         JSValueRef jDirection = JSObjectGetProperty(m_context, jsObject, directionStr.get(), NULL);
270         JSValueRef jRecording = JSObjectGetProperty(m_context, jsObject, recordingStr.get(), NULL);
271         JSValueRef jCost = JSObjectGetProperty(m_context, jsObject, costStr.get(), NULL);
272         JSValueRef jCurrency = JSObjectGetProperty(m_context, jsObject, currencyStr.get(), NULL);
273
274         unsigned long entryId;
275         std::string serviceId;
276         std::string callType;
277         StringArrayPtr tags;
278         RemotePartyListPtr remoteParties;
279         RemotePartyPtr forwardedFrom;
280         time_t startTime;
281         unsigned long duration;
282         std::string endReason;
283         std::string direction;
284         StringArrayPtr recording;
285         unsigned long cost;
286         std::string currency;
287
288         CallHistoryEntryPropertiesPtr result = CallHistoryEntryPropertiesPtr(new CallHistoryEntryProperties());
289
290         if (!result) {
291                 Throw(Commons::ConversionException);
292         }
293
294         if (!JSValueIsUndefined(m_context, jEntryId)) {
295                 entryId = toULong(jEntryId);
296                 result->setEntryId(entryId);
297         } else {
298                 ThrowMsg(Commons::InvalidArgumentException, "Undefined history entry");
299         }
300
301         if (!JSValueIsUndefined(m_context, jServiceId)) {
302                 serviceId = toString(jServiceId);
303                 result->setServiceId(serviceId);
304         }
305
306         if (!JSValueIsUndefined(m_context, jCallType)) {
307                 callType = toString(jCallType);
308                 result->setCallType(callType);
309         }
310
311         if (!JSValueIsUndefined(m_context, jTags)) {
312                 tags = toStringArray(jTags);
313                 result->setTags(tags);
314         }
315
316         if (!JSValueIsUndefined(m_context, jRemoteParties)) {
317                 remoteParties = toRemotePartyList(jRemoteParties);
318                 result->setRemoteParties(remoteParties);
319         } else {
320                 ThrowMsg(Commons::InvalidArgumentException, "Undefined history entry");
321         }
322
323         if (!JSValueIsUndefined(m_context, jForwardedFrom)) {
324                 forwardedFrom = toRemoteParty(jForwardedFrom);
325                 result->setForwardedFrom(forwardedFrom);
326         }
327
328         if (!JSValueIsUndefined(m_context, jStartTime)) {
329                 startTime = toDateTimeT(jStartTime);
330                 result->setStartTime(startTime);
331         }
332
333         if (!JSValueIsUndefined(m_context, jDuration)) {
334                 duration = toULong(jDuration);
335                 result->setDuration(duration);
336         }
337
338         if (!JSValueIsUndefined(m_context, jEndReason)) {
339                 endReason = toString(jEndReason);
340                 result->setEndReason(endReason);
341         }
342
343         if (!JSValueIsUndefined(m_context, jDirection)) {
344                 direction = toString(jDirection);
345                 result->setDirection(direction);
346         }
347
348         if (!JSValueIsUndefined(m_context, jRecording)) {
349                 recording = toStringArray(jRecording);
350                 result->setRecording(recording);
351         }
352
353         if (!JSValueIsUndefined(m_context, jCost)) {
354                 cost = toULong(jCost);
355                 result->setCost(cost);
356         }
357
358         if (!JSValueIsUndefined(m_context, jCurrency)) {
359                 currency = toString(jCurrency);
360                 result->setCurrency(currency);
361         }
362
363         return result;
364 }
365
366 EventCallHistoryListenerPrivateDataPtr 
367         Converter::toEventCallHistoryListenerPrivateData(JSValueRef successParam, JSContextRef context)
368 {
369         if (JSValueIsNull(m_context, successParam) || JSValueIsUndefined(m_context, successParam)
370                         || !JSValueIsObject(m_context, successParam))
371         {
372                 ThrowMsg(Commons::ConversionException, "CB is not a object");
373         }
374
375         JSObjectRef objectCallbacks = toJSObjectRef(successParam);
376         Validator validator(m_context);
377         CallHistoryChangeCB result;
378
379         result.onAdded = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, "onAdded");
380         result.onChanged = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, "onChanged");
381                         
382         if ((!validator.isNullOrUndefined(result.onAdded) && !validator.isCallback(result.onAdded)) ||
383                 (!validator.isNullOrUndefined(result.onChanged) && !validator.isCallback(result.onChanged)))
384         {
385                 ThrowMsg(Commons::InvalidArgumentException, "Invalid values error : CallHistoryChangeCB");
386         }
387
388         JSCallbackManagerPtr onAddedCbm = JSCallbackManager::createObject(context, result.onAdded, NULL);
389         JSCallbackManagerPtr onChangedCbm = JSCallbackManager::createObject(context, result.onChanged, NULL);
390
391         return EventCallHistoryListenerPrivateDataPtr(new EventCallHistoryListenerPrivateData(onAddedCbm, onChangedCbm));
392 }
393
394 JSValueRef Converter::toJSValueRef(const Api::Call::CallHistoryEntryListPtr& arg, JSContextRef context)
395 {
396         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
397         if (!jsResult) {
398                 ThrowMsg(Commons::ConversionException, "Could not create js array object");
399         }
400         Api::Call::CallHistoryEntryProperties tmpCallEntry;
401
402         for (size_t i = 0; i < (*arg).size(); i++) {
403                 tmpCallEntry = *((*arg)[i]);
404                 JSObjectRef jsObject = JSCallHistoryEntry::createJSObject(context, tmpCallEntry);
405                 if (!jsObject) {
406                         ThrowMsg(Commons::ConversionException, "Could not create JS object.");
407                 }
408
409                 if (!JSSetArrayElement(m_context, jsResult, i, jsObject)) {
410                         ThrowMsg(Commons::ConversionException, "Could not insert value into js array");
411                 }
412         }
413         return jsResult;
414 }
415
416 JSValueRef Converter::toJSValueRef(const Api::Call::StringArrayPtr &arg, JSContextRef context)
417 {
418         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
419         if (!jsResult) {
420                 ThrowMsg(Commons::ConversionException, "Could not create js array object");
421         }
422
423         for (size_t i = 0; i < (*arg).size(); i++) {
424                 if (!JSSetArrayElement(m_context, jsResult, i, toJSValueRef((*arg)[i]))) {
425                         ThrowMsg(Commons::ConversionException, "Could not insert value into js array");
426                 }
427         }
428
429         return jsResult;
430 }
431
432 JSValueRef Converter::toJSValueRef(const Api::Call::RemotePartyListPtr& arg, JSContextRef context)
433 {
434         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
435         if (!jsResult) {
436                 ThrowMsg(Commons::ConversionException, "Could not create js array object");
437         }
438
439         Api::Call::RemoteParty tmpRemoteParty;
440
441         for (size_t i = 0; i < (*arg).size(); i++) {
442                 tmpRemoteParty = *((*arg)[i]);
443                 JSObjectRef jsObject = JSRemoteParty::createJSObject(context, tmpRemoteParty);
444                 if (!jsObject) {
445                         ThrowMsg(Commons::ConversionException, "Could not create JS object.");
446                 }
447
448                 if (!JSSetArrayElement(m_context, jsResult, i, jsObject)) {
449                         ThrowMsg(Commons::ConversionException, "Could not insert value into js array");
450                 }
451         }
452         return jsResult;
453 }
454
455 JSValueRef Converter::toJSValueRef(const Api::Account::AccountServicesArrayPtr& arg, JSContextRef context)
456 {
457         std::vector<JSValueRef> callServiceList;
458
459         Api::Account::AccountServices tmpAccountServices;
460
461         for (size_t i = 0; i < (*arg).size(); i++) {
462                 tmpAccountServices = *((*arg)[i]);
463
464                 if (tmpAccountServices.getServiceTypeId().compare("tizen.tel") == 0) {
465                         callServiceList.push_back(JSCellularCallService::createJSObject(context, tmpAccountServices));
466                 } else {
467                         callServiceList.push_back(JSCallService::createJSObject(context, tmpAccountServices));
468                 }
469         }
470
471         return toJSValueRef(callServiceList);
472 }
473
474 bool Converter::initializeAllowedProperties()
475 {
476         m_allowedCallHistoryEntryProperties.push_back(CH_ENTRY_ID);
477         m_allowedCallHistoryEntryProperties.push_back(CH_SERVICE_ID);
478         m_allowedCallHistoryEntryProperties.push_back(CH_CALL_TYPE);
479         m_allowedCallHistoryEntryProperties.push_back(CH_TAGS);
480         m_allowedCallHistoryEntryProperties.push_back(CH_REMOTE_PARTIES);
481         m_allowedCallHistoryEntryProperties.push_back(CH_FORWARDEDFROM);
482         m_allowedCallHistoryEntryProperties.push_back(CH_START_TIME);
483         m_allowedCallHistoryEntryProperties.push_back(CH_DURATION);
484         m_allowedCallHistoryEntryProperties.push_back(CH_END_REASON);
485         m_allowedCallHistoryEntryProperties.push_back(CH_DIRECTION);
486         m_allowedCallHistoryEntryProperties.push_back(CH_RECORDING);
487         m_allowedCallHistoryEntryProperties.push_back(CH_COST);
488         m_allowedCallHistoryEntryProperties.push_back(CH_CURRENCY);
489         m_allowedRemoteParty.push_back(CH_REMOTE_PARTY);
490         m_allowedRemoteParty.push_back(CH_DISPLAY_NAME);
491         m_allowedRemoteParty.push_back(CH_CONTACT_ID);
492         m_allowedCallServiceFilter.push_back(CH_SERVICETYPE_ID);
493         m_allowedCallServiceFilter.push_back(CH_TAGS);
494         m_allowedCallServiceFilter.push_back(CH_SERVICENAME);
495         m_allowedCallServiceFilter.push_back(CH_PROVIDER_ID);
496
497         return true;
498 }
499
500 }
501 }
502