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