Merge "[Archive] Fix for retrieving virtual roots" into tizen
[platform/core/api/webapi-plugins.git] / src / alarm / alarm_api.js
1 /*
2  * Copyright (c) 2015 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 var T = xwalk.utils.type;
18 var Converter = xwalk.utils.converter;
19 var AV = xwalk.utils.validator;
20 var privUtils_ = xwalk.utils;
21
22 var native = new xwalk.utils.NativeManager(extension);
23
24 var AlarmManager = function () {
25     Object.defineProperties(this, {
26         PERIOD_MINUTE:  { value: 60, writable: false, enumerable: true},
27         PERIOD_HOUR:    { value: 3600, writable: false, enumerable: true},
28         PERIOD_DAY:     { value: 86400, writable: false, enumerable: true},
29         PERIOD_WEEK:    { value: 604800, writable: false, enumerable: true},
30     });
31 };
32
33 var EditManager = function() {
34     this.canEdit = false;
35 };
36
37 EditManager.prototype.allow = function() {
38     this.canEdit = true;
39 };
40
41 EditManager.prototype.disallow = function() {
42     this.canEdit = false;
43 };
44
45 var _edit = new EditManager();
46
47 function InternalData_(data) {
48     if (!(this instanceof InternalData_)) {
49         return new InternalData_(data);
50     }
51
52     for(var key in data) {
53         if (data.hasOwnProperty(key)) {
54             this[key] = data[key];
55         }
56     }
57 }
58
59 function UpdateInternalData_(internal, data) {
60     var values = InternalData_(data);
61
62     for(var key in data) {
63         if (values.hasOwnProperty(key) && internal.hasOwnProperty(key)) {
64             internal[key] = values;
65         }
66     }
67 }
68
69 var LogManager = function() {
70     this.enableLog = true;
71 };
72
73 LogManager.prototype.allow = function() {
74     this.enableLog = true;
75 };
76
77 LogManager.prototype.disallow = function() {
78     this.enableLog = false;
79 };
80
81 var _warningLogs = new LogManager();
82
83 //class AlarmManager ////////////////////////////////////////////////////
84 AlarmManager.prototype.add = function () {
85     var args = AV.validateMethod(arguments, [
86         {
87             name : 'alarm',
88             type : AV.Types.PLATFORM_OBJECT,
89             values : [tizen.AlarmRelative, tizen.AlarmAbsolute]
90         },
91         {
92             name : 'applicationId',
93             type : AV.Types.STRING,
94         },
95         {
96             name : 'appControl',
97             type : AV.Types.PLATFORM_OBJECT,
98             values : tizen.ApplicationControl,
99             optional : true,
100             nullable : true
101         },
102     ]);
103
104     var type = null, seconds = 0;
105     if (args.alarm instanceof tizen.AlarmRelative) {
106         type = 'AlarmRelative';
107     } else if (args.alarm instanceof tizen.AlarmAbsolute) {
108         type = 'AlarmAbsolute';
109         seconds = args.alarm.date.getTime();
110     }
111
112     var callArgs = {};
113     callArgs.alarm = args.alarm;
114     callArgs.applicationId = args.applicationId;
115     if (args.has.appControl) {
116         callArgs.appControl = args.appControl;
117     }
118
119     callArgs.type = type;
120     callArgs.seconds = Converter.toString(seconds);
121     callArgs.isPeriodSet = !T.isNullOrUndefined(args.alarm.period);
122
123     var result = native.callSync('AlarmManager_add', callArgs);
124     if (native.isFailure(result)) {
125         throw native.getErrorObject(result);
126     } else {
127         _edit.allow();
128         UpdateInternalData_(args.alarm, native.getResultObject(result));
129         _edit.disallow();
130     }
131 };
132
133 AlarmManager.prototype.addAlarmNotification = function() {
134     var args = AV.validateMethod(arguments, [
135     {
136         name: 'alarm',
137         type: AV.Types.PLATFORM_OBJECT,
138         values: [tizen.AlarmRelative, tizen.AlarmAbsolute]
139     }, {
140         name: 'notification',
141         type: AV.Types.PLATFORM_OBJECT,
142         values: [tizen.StatusNotification, tizen.UserNotification]
143     }]);
144
145     var type = null, milliseconds = 0;
146     if (args.alarm instanceof tizen.AlarmRelative) {
147         type = 'AlarmRelative';
148     } else if (args.alarm instanceof tizen.AlarmAbsolute) {
149         type = 'AlarmAbsolute';
150         milliseconds = args.alarm.date.getTime();
151     }
152
153     var callArgs = {};
154     callArgs.alarm = args.alarm;
155     callArgs.type = type;
156     callArgs.notification = args.notification;
157     callArgs.milliseconds = Converter.toString(milliseconds);
158     callArgs.isPeriodSet = !T.isNullOrUndefined(args.alarm.period);
159
160     //add marker for UserNotification implementation
161     callArgs.newImpl = (callArgs.notification instanceof tizen.UserNotification);
162
163     var result = native.callSync('AlarmManager_addAlarmNotification', callArgs);
164     if (native.isFailure(result)) {
165         throw native.getErrorObject(result);
166     }
167     else {
168         _edit.allow();
169         UpdateInternalData_(args.alarm, native.getResultObject(result));
170         _edit.disallow();
171     }
172 };
173
174 AlarmManager.prototype.remove = function () {
175     var args = AV.validateMethod(arguments, [
176         {
177             name : 'id',
178             type : AV.Types.STRING,
179         }
180     ]);
181
182     var result = native.callSync('AlarmManager_remove', {id: Number(args.id)});
183
184     if (native.isFailure(result)) {
185         throw native.getErrorObject(result);
186     }
187 };
188
189 AlarmManager.prototype.removeAll = function () {
190     var result = native.callSync('AlarmManager_removeAll', {});
191
192     if (native.isFailure(result)) {
193         throw native.getErrorObject(result);
194     }
195 };
196
197 AlarmManager.prototype.get = function () {
198     var args = AV.validateMethod(arguments, [
199         {
200             name : 'id',
201             type : AV.Types.STRING,
202         }
203     ]);
204
205     var result = native.callSync('AlarmManager_get', {id: Number(args.id)});
206
207     if (native.isFailure(result)) {
208         throw native.getErrorObject(result);
209     } else {
210         result = native.getResultObject(result);
211
212         var alarm;
213         _warningLogs.disallow();
214         if ('AlarmRelative' === result.type) {
215             alarm = new tizen.AlarmRelative(result.delay, result.period, InternalData_(result));
216         } else {
217             var date = new Date(result.year, result.month, result.day,
218                     result.hour, result.min, result.sec);
219
220             alarm = new tizen.AlarmAbsolute(date, result.second, InternalData_(result));
221         }
222         _warningLogs.allow();
223         return alarm;
224     }
225 };
226
227 function _prepareAppControl(noti) {
228   if (!noti || !noti.actions || !noti.actions.appControl) {
229     privUtils_.log("Do nothing - appControl is NOT present");
230     return;
231   }
232   if (!T.isNullOrUndefined(noti.actions.appControl.operation)) {
233     noti.actions.appControl = new tizen.ApplicationControl(
234         noti.actions.appControl.operation,
235         noti.actions.appControl.uri,
236         noti.actions.appControl.mime,
237         noti.actions.appControl.category,
238         noti.actions.appControl.data,
239         noti.actions.appControl.launchMode);
240   }
241 }
242
243 function _prepareDetailInfo(noti) {
244   if (!noti || !noti.textContents || !noti.textContents.detailInfo) {
245     console.log("Do nothing - detailInfo is NOT present");
246     return;
247   }
248   var detailInfo = noti.textContents.detailInfo;
249   if (T.isArray(detailInfo)) {
250     var _d = [];
251     for (var i = 0; i < detailInfo.length; ++i) {
252       _d.push(new tizen.NotificationDetailInfo(detailInfo[i].mainText,
253           detailInfo[i].subText || null));
254     }
255     noti.textContents.detailInfo = _d;
256   }
257 }
258
259 AlarmManager.prototype.getAlarmNotification = function () {
260     var args = AV.validateMethod(arguments, [
261         {
262             name : 'id',
263             type : AV.Types.STRING,
264         }
265     ]);
266
267     var result = native.callSync('AlarmManager_getAlarmNotification', {id: Number(args.id)});
268
269     if (native.isFailure(result)) {
270         throw native.getErrorObject(result);
271     } else {
272         var noti = native.getResultObject(result);
273         _prepareAppControl(noti);
274         _prepareDetailInfo(noti);
275         return new tizen.UserNotification(noti.userType, noti.title, noti);
276     }
277 };
278
279 AlarmManager.prototype.getAll = function () {
280     var result = native.callSync('AlarmManager_getAll', {});
281
282     if (native.isFailure(result)) {
283         throw native.getErrorObject(result);
284     } else {
285         var data = native.getResultObject(result);
286         var md = [];
287         _warningLogs.disallow();
288         data.forEach(function (i) {
289             if ('AlarmRelative'=== i.type) {
290                 md.push(new tizen.AlarmRelative(i.delay, i.period, InternalData_(i)));
291             } else {
292                 var date = new Date(i.year, i.month, i.day,
293                         i.hour, i.min, i.sec);
294                 md.push(new tizen.AlarmAbsolute(date, i.second, InternalData_(i)));
295             }
296         });
297         _warningLogs.allow();
298         return md;
299     }
300 };
301
302 //class Alarm //////////////////////////////////////////////////////////
303 function Alarm(id) {
304     var m_id = null;
305
306     if (!T.isNullOrUndefined(id) && id instanceof InternalData_) {
307         m_id = id.id;
308     }
309
310     var _internal = {
311         'id' : m_id
312     };
313
314     Object.defineProperties(this, {
315         id: {
316             get: function () {return _internal.id;},
317             set: function (value) {
318                 if (value instanceof InternalData_) {
319                     _internal.id = value.id;
320                 }
321             },
322             enumerable: true
323         }
324     });
325 }
326 //class AlarmRelative //////////////////////////////////////////////////
327
328 tizen.AlarmRelative = function(delay, period, internal) {
329     AV.validateConstructorCall(this, tizen.AlarmRelative);
330
331     var m_period = null;
332
333     var m_delay = Converter.toLong(delay);
334
335     if (arguments.length >= 2) {
336         if(!T.isNullOrUndefined(period)){
337             m_period = Converter.toLong(period, true);
338         }
339     }
340
341     Alarm.call(this, internal);
342
343     Object.defineProperties(this, {
344         delay: {
345             get: function() {
346                 return m_delay;
347             },
348             set: function(v) {
349                 if (_edit.canEdit && v) {
350                     m_delay = Converter.toLong(v.delay);
351                 }
352             },
353             enumerable: true
354         },
355         period: {
356             get: function() {
357                 return m_period;
358             },
359             set: function(v) {
360                 if (_edit.canEdit && v) {
361                     m_period = Converter.toLong(v.period);
362                 }
363             },
364             enumerable: true
365         }
366     });
367 };
368
369 tizen.AlarmRelative.prototype = new Alarm();
370
371 tizen.AlarmRelative.prototype.constructor = tizen.AlarmRelative;
372
373 tizen.AlarmRelative.prototype.getRemainingSeconds = function () {
374     var result = native.callSync('AlarmRelative_getRemainingSeconds', {id: Number(this.id)});
375
376     if (native.isFailure(result)) {
377         throw native.getErrorObject(result);
378     } else {
379         return Converter.toLong(native.getResultObject(result).seconds, true);
380     }
381 };
382
383 function makeDateConst(obj) {
384     privUtils_.log('Enter MakeConst');
385     obj.setDate = function() {};
386     obj.setFullYear = function() {};
387     obj.setHours = function() {};
388     obj.setMilliseconds = function() {};
389     obj.setMinutes = function() {};
390     obj.setMonth = function() {};
391     obj.setSeconds = function() {};
392     obj.setTime = function() {};
393     obj.setUTCDate = function() {};
394     obj.setUTCFullYear = function() {};
395     obj.setUTCHours = function() {};
396     obj.setUTCMilliseconds = function() {};
397     obj.setUTCMinutes = function() {};
398     obj.setUTCMonth = function() {};
399     obj.setUTCSeconds = function() {};
400     obj.setYear = function() {};
401     privUtils_.log('Leave MakeConst');
402 }
403
404 //class AlarmAbsolute //////////////////////////////////////////////////
405
406 tizen.AlarmAbsolute = function(date, second, internal) {
407     AV.validateConstructorCall(this, tizen.AlarmAbsolute);
408
409     var m_period = null, m_daysOfWeek = [], m_date;
410
411     if (T.isDate(date)) {
412         m_date = date;
413         if (arguments.length >= 2) {
414             if(T.isArray(second)){
415                 m_daysOfWeek = second;
416             } else {
417                 if(!T.isNullOrUndefined(second)){
418                     m_period = Converter.toLong(second);
419                     if(_warningLogs.enableLog){
420                         privUtils_.warn("This Constructor is deprecated since Tizen 4.0." +
421                         " Please consider using other constructors or other type of an alarm.");
422                     }
423                 }
424             }
425         }
426
427         Alarm.call(this, internal);
428     } else {
429         m_period = undefined;
430     }
431     makeDateConst(m_date);
432     Object.defineProperties(this, {
433         date: {
434             get: function() {
435                 return m_date;
436             },
437             set: function(v) {
438                 if (_edit.canEdit && T.isDate(v.date)) {
439                     m_date = v.date;
440                 }
441             },
442             enumerable: true
443         },
444         period: {
445             get: function() {
446                 return m_period;
447             },
448             set: function(v) {
449                 if (_edit.canEdit && v) {
450                     m_period = Converter.toLong(v.period);
451                 }
452             },
453             enumerable: true
454         },
455         daysOfTheWeek: {
456             get: function() {
457                 return m_daysOfWeek;
458             },
459             set: function(v) {
460                 if (_edit.canEdit && T.isArray(v.second)) {
461                     m_daysOfWeek = v.second;
462                 }
463             },
464             enumerable: true
465         }
466     });
467 };
468
469 tizen.AlarmAbsolute.prototype = new Alarm();
470
471 tizen.AlarmAbsolute.prototype.constructor = tizen.AlarmAbsolute;
472
473 tizen.AlarmAbsolute.prototype.getNextScheduledDate = function () {
474     var result = native.callSync('AlarmAbsolute_getNextScheduledDate', {id: Number(this.id)});
475
476     if (native.isFailure(result)) {
477         throw native.getErrorObject(result);
478     } else {
479         var d = native.getResultObject(result);
480         if (T.isNull(d.year)) {
481             return null;
482         } else {
483             var date = new Date(d.year, d.month, d.day, d.hour, d.min, d.sec);
484             return date;
485         }
486     }
487 };
488
489 // Singleton to check on which profile plugins are executed
490 var ProfileAlarm = (function() {
491     var m_profile = null;
492     function ProfileAlarm() {
493        if (m_profile == null) {
494            m_profile = privUtils_.checkProfile();
495        }
496        Object.defineProperties(this, {
497            profile: {
498                get: function() {
499                    return m_profile;
500                },
501                set: function() {},
502                enumerable: true
503            }
504        })
505     };
506
507     var instance;
508     return {
509         getInstance: function() {
510             if (instance == null) {
511                 instance = new ProfileAlarm();
512                 // Hide the constructor so the returned objected can't be new'd...
513                 instance.constructor = null;
514             }
515             return instance;
516         }
517    };
518 })();
519
520 var _profile = ProfileAlarm.getInstance().profile;
521
522 // Notifications feature are available on mobile and wearable profile
523 if (_profile != 'mobile' && _profile != 'wearable') {
524     delete AlarmManager.prototype.addAlarmNotification;
525     delete AlarmManager.prototype.getAlarmNotification;
526 }
527
528 //exports //////////////////////////////////////////////////////////////
529 exports = new AlarmManager();