1 /*
  2  * This is signage cordova_plugin (TV specific API).
  3  * Apache License (2004). See http://www.apache.org/licenses/LICENSE-2.0
  4  *
  5  * Copyright (c) 2014, LG Electronics, Inc.
  6  */
  7 
  8 /**
  9  * This represents the signage API itself, and provides a global namespace for operating signage service.
 10  * @class
 11  */
 12 cordova.define('cordova/plugin/signage', function (require, exports, module) { // jshint ignore:line
 13     var service;
 14     function log(msg) {
 15         //	//console.log//will be removed // jshint ignore:line
 16     }
 17 
 18 
 19     if (window.PalmSystem) { // jshint ignore:line
 20         log("Window.PalmSystem Available");
 21         service = require('cordova/plugin/webos/service');
 22     }
 23     else {
 24         log("Window.PalmSystem is NOT Available");
 25         service = {
 26             Request: function (uri, params) {
 27                 log(uri + " invoked. But I am a dummy because PalmSystem is not available");
 28                 if (typeof params.onFailure === 'function') {
 29                     params.onFailure({
 30                         returnValue: false, errorCode: "CORDOVA_ERR",
 31                         errorText: "PalmSystem Not Available. Cordova is not installed?"
 32                     });
 33                 }
 34             }
 35         };
 36     }
 37 
 38     var version = null;
 39     var platformInfoObj = {}; 
 40     function checkPlatformVersion(cb) {
 41 
 42         if (version === null) {
 43 
 44             service.Request('luna://com.webos.service.tv.systemproperty', {
 45                 method: 'getSystemInfo',
 46                 parameters: {
 47                     keys: ["sdkVersion", "boardType"]
 48                 },
 49                 onSuccess: function(result) {
 50                     log("getPlatformInfo: onSuccess");
 51                     log("version : " + result.sdkVersion);
 52 
 53                     var temp = result.sdkVersion.split('.');
 54                     if (temp.length >= 1 && temp[0] === '1') {
 55                         platformInfoObj = {
 56                             webOSVer: 1,
 57                             chipset: result.boardType.split("_")[0]
 58                         };
 59                     } else if (temp.length >= 1 && temp[0] === '2') {
 60                         platformInfoObj = {
 61                             webOSVer: 2,
 62                             chipset: result.boardType.split("_")[0]
 63                         };
 64                     } else if (temp.length >= 1 && temp[0] === '3') {
 65                         platformInfoObj = {
 66                             webOSVer: 3,
 67                             chipset: result.boardType.split("_")[0]
 68                         };
 69                     } else {
 70                         platformInfoObj = {
 71                             webOSVer: 0,
 72                             chipset: ""
 73                         };
 74                     }
 75                     version = platformInfoObj.webOSVer;
 76                     cb(platformInfoObj);
 77                 },
 78                 onFailure: function(error) {
 79                     log("getPlatformInfo: onFailure");
 80                     platformInfoObj = {
 81                         webOSVer: 0,
 82                         chipset: ""
 83                     }
 84                     cb(platformInfoObj);
 85                 }
 86             });
 87 
 88         } else {
 89             cb(platformInfoObj);
 90         }
 91     }
 92     
 93 
 94     var removeSignageEventListener = function (event) {
 95         var monitorObj = _gSystemMonitoringSetup[event];
 96         log(JSON.stringify(monitorObj, null, 3));
 97         if (monitorObj && monitorObj.getEvent === true) {
 98             if (_gSystemMonitoringSetup[event].listenerObj) {
 99                 _gSystemMonitoringSetup[event].listenerObj.cancel();
100                 _gSystemMonitoringSetup[event].getEvent = false;
101                 _gSystemMonitoringSetup[event].listenerObj = null;
102             }
103         }
104     };
105     var addSignageEventListener = function (key, callbackfunction) {
106 		/*	fan : {
107 			getEvent:false,
108 			listenerObj : null,
109 			createListenr : monitorFan
110 		},
111 		 */
112         var monitorSetup = _gSystemMonitoringSetup[key];
113         if (monitorSetup && typeof monitorSetup.createListener === 'function') {
114             monitorSetup.listenerObj = monitorSetup.createListener(callbackfunction);
115             monitorSetup.getEvent = true;
116         }
117     };
118 
119     function getInputValue(inputUri) {
120         if (inputUri.substring(0, "ext://".length) !== "ext://") {
121             log("Bad prefix: " + inputUri);
122             return false;
123         }
124 
125         var body = inputUri.substring("ext://".length);
126         log("body is: " + body);
127 
128         var splited = body.split(":");
129 
130         if (splited.length === 2) {
131             return splited[0] + splited[1];
132         }
133 
134         else if (splited.length === 1) {
135             return splited[0];
136         }
137 
138         else {
139             log("Bad Syntax: " + inputUri);
140             return false;
141         }
142     }
143 
144     function isValidEnum(arr, value) {
145         for (var key in arr) {
146             if (arr[key] === value) {
147                 return true;
148             }
149         }
150 
151         return false;
152     }
153 
154 
155     var SETTINGS_KEY = {
156         FAILOVER_MODE: "failover",
157         FAILOVER_BACKUPVIASTORAGE_MODE: "backupViaStorage",
158         FAILOVER_PRIORITY: "failoverPriority",
159         IR_OPERATION_MODE: "enableIrRemote",
160         LOCALKEY_OPERATION_MODE: "enableLocalKey",
161         OSD_PORTRAIT_MODE: "osdPortraitMode",
162         TILE_MODE: "tileMode",
163         TILE_ID: "tileId",
164         TILE_ROW: "tileRow",
165         TILE_COLUME: "tileCol",
166         TILE_NATURALMODE: "naturalMode",
167         DPM_MODE: "dpmMode",
168         AUTOMATIC_STANDBY_MODE: "autoSB",
169         ISM_METHOD: "ismmethod",
170         SES_MODE: "smartEnergy",
171         DO_15OFF_MODE: "15off",
172         MONITOR_FAN: "monitorFan",
173         MONITOR_SIGNAL: "monitorSignal",
174         MONITOR_LAMP: "monitorLamp",
175         MONITOR_SCREEN: "monitorScreen",
176         MONITOR_AUDIO: "monitorAudio",
177         AUDIO_SOURCE_HDMI1: "audioSourceHdmi1",
178         AUDIO_SOURCE_HDMI2: "audioSourceHdmi2",
179         AUDIO_SOURCE_DP: "audioSourceDp"
180     };
181 
182     var monitorTemperature = function (callbackfunction) {
183         log("Create Listener for monitorTemperature");
184         var subscribed = service.Request("luna://com.webos.service.commercial.signage.storageservice", {
185             method: "systemMonitor/getTemperature",
186             parameters: {
187                 subscribe: true
188             },
189             onSuccess: function (result) {
190                 log("temperature : " + JSON.stringify(result, null, 3));
191 
192                 if (result.returnValue === true) {
193                     var returnData = {
194                         source: Signage.MonitoringSource.THERMOMETER,
195                         type: Signage.EventType.CURRENT_TEMPERATURE,
196                         data: {
197                             temperature: result.temperature
198                         }
199                     };
200                     if (typeof callbackfunction === 'function') {
201                         callbackfunction(returnData);
202                     }
203                 }
204             },
205             onFailure: function (result) {
206                 log("monitor_temperature : FAIL " + JSON.stringify(result, null, 3));
207 
208             }
209         });
210         return subscribed;
211     };
212 
213     var monitorFan = function (callbackfunction) {
214         log("Create Listener for monitorFan");
215 
216         var subscribed = service.Request("luna://com.webos.service.commercial.signage.storageservice", {
217             method: "systemMonitor/getFanEvent",
218             parameters: {
219                 subscribe: true
220             },
221             onSuccess: function (result) {
222                 log("monitor_fan : " + JSON.stringify(result, null, 3));
223 
224                 if (result.returnValue === true) {
225                     var returnData = {
226                         source: Signage.MonitoringSource.FAN,
227                         type: Signage.EventType.FAN_STATUS,
228                         data: {
229                             status: result.fanFault
230                         }
231                     };
232                     if (typeof callbackfunction === 'function') {
233                         callbackfunction(returnData);
234                     }
235                 }
236             },
237             onFailure: function (result) {
238                 log("monitor_fan : FAIL " + JSON.stringify(result, null, 3));
239 
240             }
241         });
242         return subscribed;
243     };
244 
245     var monitorLamp = function (callbackfunction) {
246         log("Create Listener for monitorLamp");
247 
248         var subscribed = service.Request("luna://com.webos.service.commercial.signage.storageservice", {
249             method: "systemMonitor/getLampEvent",
250             parameters: {
251                 subscribe: true
252             },
253             onSuccess: function (result) {
254                 log("monitor_lamp : " + JSON.stringify(result, null, 3));
255 
256                 if (result.returnValue === true) {
257                     var returnData = {
258                         source: Signage.MonitoringSource.LAMP,
259                         type: Signage.EventType.LAMP_STATUS,
260                         data: {
261                             status: result.lampFault
262                         }
263                     };
264                     if (typeof callbackfunction === 'function') {
265                         callbackfunction(returnData);
266                     }
267                 }
268             },
269             onFailure: function (result) {
270                 log("monitor_lamp : FAIL " + JSON.stringify(result, null, 3));
271 
272             }
273         });
274         return subscribed;
275     };
276 
277     var monitorSignal = function (callbackfunction) {
278         log("Create Listener for monitorSignal");
279 
280         var subscribed = service.Request("luna://com.webos.service.commercial.signage.storageservice", {
281             method: "systemMonitor/getSignalEvent",
282             parameters: {
283                 subscribe: true
284             },
285             onSuccess: function (result) {
286                 log("monitor_signal : " + JSON.stringify(result, null, 3));
287 
288                 if (result.returnValue === true) {
289                     var returnData = {
290                         type: Signage.EventType.SIGNAL_STATUS,
291                         source: Signage.MonitoringSource.SIGNAL,
292 
293                         data: {}
294                     };
295                     if (result.noSignal === true) {
296                         returnData.data.status = "no_signal";
297                     }
298                     else {
299                         returnData.data.status = "signal_available";
300                     }
301 
302                     if (typeof callbackfunction === 'function') {
303                         callbackfunction(returnData);
304                     }
305                 }
306             },
307             onFailure: function (result) {
308                 log("monitor_signal : FAIL " + JSON.stringify(result, null, 3));
309             }
310         });
311 
312         return subscribed;
313     };
314 
315     var monitorScreen = function (callbackfunction) {
316         log("Create Listener for monitorScreen");
317 
318         var subscribed = service.Request("luna://com.webos.service.commercial.signage.storageservice", {
319             method: "systemMonitor/getScreenEvent",
320             parameters: {
321                 subscribe: true
322             },
323             onSuccess: function (result) {
324                 log("monitor_screen : " + JSON.stringify(result, null, 3));
325 
326                 if (result.returnValue === true) {
327                     var returnData = {
328                         source: Signage.MonitoringSource.SCREEN,
329                         type: Signage.EventType.SCREEN_STATUS,
330                         data: {
331                             status: result.screen
332                         }
333                     };
334 
335                     if (typeof callbackfunction === 'function') {
336                         callbackfunction(returnData);
337                     }
338                 }
339             },
340             onFailure: function (result) {
341                 log("monitor_screen FAIL : " + JSON.stringify(result, null, 3));
342             }
343         });
344 
345         return subscribed;
346     };
347 
348     function addSubscriptionEventInfo(eventName, instanceOfSubscription, eventlistener) {
349 
350         if (_gSubscriptionEventInfo.hasOwnProperty(eventName) === false) {
351             _gSubscriptionEventInfo[eventName]                        = {};
352             _gSubscriptionEventInfo[eventName].instanceOfSubscription = instanceOfSubscription;
353             _gSubscriptionEventInfo[eventName].eventListener          = eventlistener;
354         } else {
355             _gSubscriptionEventInfo[eventName].instanceOfSubscription = instanceOfSubscription;
356             _gSubscriptionEventInfo[eventName].eventListener          = eventlistener;
357         }
358 
359         return true;
360     }
361 
362     function removeSubscriptionEventInfo(eventName) {
363 
364         if (_gSubscriptionEventInfo.hasOwnProperty(eventName) === false) {
365             return false;
366         } else if (_gSubscriptionEventInfo[eventName].instanceOfSubscription === null) {
367             return false;
368         } else {
369             _gSubscriptionEventInfo[eventName].instanceOfSubscription.cancel();
370             _gSubscriptionEventInfo[eventName].instanceOfSubscription = null;
371             _gSubscriptionEventInfo[eventName].eventListener = null;
372 
373             return true;
374         }
375     }
376 
377     function getSubscriptionEventInfo(eventName) {
378 
379         if (_gSubscriptionEventInfo.hasOwnProperty(eventName) === false) {
380             return false;
381         } else {
382             return _gSubscriptionEventInfo[eventName];
383         }
384     }
385 
386     var monitorRS232C = function (successCallback, errorCallback, eventListener) {
387         log("Create Listener for monitorRS232C");
388 
389         var req = service.Request("luna://com.webos.service.commercial.signage.storageservice", {
390             method: "systemMonitor/startMonitorRS232C",
391             parameters: {
392                 subscribe: true
393             },
394             onSuccess: function (result) {
395                 log("monitorRS232C success : " + JSON.stringify(result, null, 3));
396                 
397                 if (result.returnValue === true) {
398                     //first response on request
399                     if (Object.keys(result).length === 1) {
400                         addSubscriptionEventInfo('RS232C', req, eventListener);
401 
402                         successCallback();
403                     } else if (result.hasOwnProperty('data') === true) {
404                         var subEventInfo = getSubscriptionEventInfo('RS232C');
405                         if (subEventInfo === false) {
406                             errorCallback({
407                                 errorCode: "INTERNAL_ERROR",
408                                 errorText: "There is not subscriptionEventInfo"
409                             });
410                         } else {
411                             if (typeof subEventInfo.eventListener === 'function') {
412                                 subEventInfo.eventListener({
413                                     data: result.data
414                                 });
415                             }
416                         }
417                     } else {
418                         errorCallback({
419                             errorCode: "INTERNAL_ERROR",
420                             errorText: "Unknown return value"
421                         });
422                     }
423                     return;
424                 }
425             },
426             onFailure: function (result) {
427                 log("monitorRS232C fail : " + JSON.stringify(result, null, 3));
428     
429                 errorCallback({
430                     errorCode: "LUNA_ERROR",
431                     errorText: "Failed to request getRS232CEvent to system"
432                 });
433             }
434         });        
435     };
436 
437     var _gSystemMonitoringSetup = {
438         fan: {
439             getEvent: false,
440             listenerObj: null,
441             createListener: monitorFan
442         },
443         screen: {
444             getEvent: false,
445             listenerObj: null,
446             createListener: monitorScreen
447         },
448         temperature: {
449             getEvent: false,
450             listenerObj: null,
451             createListener: monitorTemperature
452         },
453         signal: {
454             getEvent: false,
455             listenerObj: null,
456             createListener: monitorSignal
457         },
458         lamp: {
459             getEvent: false,
460             listenerObj: null,
461             createListener: monitorLamp
462         }
463     };
464 
465     var _gSubscriptionEventInfo = {
466         RS232C: {
467             instanceOfSubscription : null,
468             eventListener : null
469         }
470     };
471 
472     var _gTileInfo = {
473         row: 0,
474         col: 0
475     };
476 
477 	/**
478 	 * signage interface
479 	 */
480     var Signage = function () {
481     };
482 
483 	/**
484 	 * This value is returned when requested data is not defined.
485 	 */
486     Signage.UNDEFINED = '___undefined___';
487 
488 
489 	/**
490 	 * @namespace Signage.FailoverMode
491 	 */
492     Signage.OsdPortraitMode = {
493         /**
494          * Rotate 90 or 270 degree. It depends on the model specific.
495          * @since 1.0
496          * @constant
497          */
498         ON: "90",
499         /**
500          * Do not use portrait mode.
501          * @since 1.0
502          * @constant
503          */
504         OFF: "off"
505     };
506 
507     /**
508      * @namespace Signage.ImgResolution
509      */
510     Signage.ImgResolution = {
511         /**
512          * HD Resolution
513          * @since 1.4.1
514          * @constant
515          */
516         HD: "HD",
517         /**
518          * FHD Resolution
519          * @since 1.4.1
520          * @constant
521          */
522         FHD: "FHD",             
523     };
524 
525 	/**
526 	 * @namespace Signage.AutomaticStandbyMode
527 	 */
528     Signage.AutomaticStandbyMode = {
529         /**
530          * Do not use automatic standby mode.
531          * @since 1.0
532          * @constant
533          */
534         OFF: "off",
535         /**
536          * automatic standby in 4 hours.
537          * @since 1.0
538          * @constant
539          */
540         STANDBY_4HOURS: "4hours"
541     };
542     
543 	/**
544 	 * @namespace Signage.ISMMethod
545 	 */
546     Signage.IsmMethod = {
547         /**
548          * ISM Method Normal
549          * @since 1.0
550          * @constant
551          */
552         NORMAL: "NORMAL",
553         /**
554          * ISM Method Orbiter
555          * @since 1.0
556          * @constant
557          */
558         ORBITER: "ORBITER",
559         /**
560          * ISM Method Inversion
561          * @since 1.0
562          * @constant
563          */
564         INVERSION: "INVERSION",
565         /**
566          * ISM Method Color Wash
567          * @since 1.0
568          * @constant
569          */
570         COLORWASH: "COLORWASH",
571         /**
572          * ISM Method White Wash
573          * @since 1.0
574          * @constant
575          */
576         WHITEWASH: "WHITEWASH",
577         /**
578          * Washing Bar
579          * @since 1.2
580          * @constant
581          */
582         WASHING_BAR: "WASHINGBAR",
583         /**
584          * User Image
585          * @since 1.2
586          * @constant
587          */
588         USER_IMAGE: "USERIMAGE",			
589         /**
590          * User Image
591          * @since 1.2
592          * @constant
593          */
594         USER_VIDEO: "USERVIDEO"
595     };
596     
597 	/**
598 	 * @namespace Signage.FailoverMode
599 	 */
600     Signage.FailoverMode = {
601         /**
602          * Do not use failover mode.
603          * @since 1.0
604          * @constant
605          */
606         OFF: "off",
607         /**
608          * Use machine default setting. It differs model by model. <br>
609          * For LS55A, it is (HDMI1 > HDMI2 > DP > DVI > Internal Memory)
610          * @since 1.0
611          * @constant
612          */
613         AUTO: "auto",
614         /**
615          * Use priority set by the user.
616          * @since 1.0
617          * @constant
618          */
619         MANUAL: "manual"
620     };
621 
622 	/**
623 	 * @namespace Signage.DigitalAudioInput
624 	 */
625     Signage.DigitalAudioInput = {
626         /**
627          * HDMI or display port
628          * @since 1.0
629          * @constant
630          */
631         HDMI_DP: "hdmi",
632         /**
633          * AUDIO_IN
634          * @since 1.0
635          * @constant
636          */
637         AUDIO_IN: "audioIn"
638     };
639     
640 	/**
641 	 * @namespace Signage.DpmMode
642 	 */
643     Signage.DpmMode = {
644         /**
645          * Do not use DPM
646          * @since 1.0
647          * @constant
648          */
649         OFF: "off",
650         /**
651          * POWER_OFF_5SECONDS
652          * @since 1.0
653          * @constant
654          */
655         POWER_OFF_5SECOND: "5sec",
656         /**
657          * POWER_OFF_10SECONDS
658          * @since 1.0
659          * @constant
660          */
661         POWER_OFF_10SECOND: "10sec",
662         /**
663          * POWER_OFF_15SECONDS
664          * @since 1.0
665          * @constant
666          */
667         POWER_OFF_15SECOND: "15sec",
668         /**
669          * POWER_OFF_1MINUTE
670          * @since 1.0
671          * @constant
672          */
673         POWER_OFF_1MINUTE: "1min",
674         /**
675          * POWER_OFF_3MINUTE
676          * @since 1.0
677          * @constant
678          */
679         POWER_OFF_3MINUTE: "3min",
680         /**
681          * POWER_OFF_5MINUTE
682          * @since 1.0
683          * @constant
684          */
685         POWER_OFF_5MINUTE: "5min",
686 
687         /**
688          * POWER_OFF_10MINUTE
689          * @since 1.0
690          * @constant
691          */
692         POWER_OFF_10MINUTE: "10min"
693     };
694     
695 	/**
696 	 * @namespace Signage.KeyOperationMode
697 	 */
698     Signage.KeyOperationMode = {
699         /**
700          * ALLOW_ALL
701          * @since 1.0
702          * @constant
703          */
704         ALLOW_ALL: "normal",
705         /**
706          * POWER_ONLY
707          * @since 1.0
708          * @constant
709          */
710         POWER_ONLY: "usePwrOnly",
711         /**
712          * BLOCK_ALL
713          * @since 1.0
714          * @constant
715          */
716         BLOCK_ALL: "blockAll"
717     };
718     
719 	/**
720 	 * @namespace Signage.EventType
721 	 */
722     Signage.EventType = {
723         /**
724          * Temperature Event.
725          * Corresponding data includes:
726          * <div align=left>
727          * <table class="hcap_spec" width=400>
728          *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
729          *   <tbody>
730          *       <tr><th>temperature</th><th>Number</th><th>Current Temperature</th><th>required</th></tr>
731          *   </tbody>
732          * </table>
733          * </div>
734          * @since 1.0
735          * @constant
736          */
737         CURRENT_TEMPERATURE: "CURRENT_TEMPERATURE",
738 
739         /**
740          * Current fan status.
741          * Corresponding data includes:
742          * <div align=left>
743          * <table class="hcap_spec" width=400>
744          *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
745          *   <tbody>
746          *       <tr><th>status</th><th>String</th><th>Fan status. ('ok'|'fault'|'na')</th><th>required</th></tr>
747          *   </tbody>
748          * </table>
749          * </div>
750          * @since 1.0
751          * @constant
752          */
753         FAN_STATUS: "FAN_STATUS",
754 
755         /**
756          * Current lamp status.
757          * Corresponding data includes:
758          * <div align=left>
759          * <table class="hcap_spec" width=400>
760          *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
761          *   <tbody>
762          *       <tr><th>status</th><th>String</th><th>Lamp status. ('ok'|'fault'|'na')</th><th>required</th></tr>
763          *   </tbody>
764          * </table>
765          * </div>
766          * @since 1.0
767          * @constant
768          */
769         LAMP_STATUS: "LAMP_STATUS",
770 
771         /**
772          * Current screen status.
773          * Corresponding data includes:
774          * <div align=left>
775          * <table class="hcap_spec" width=400>
776          *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
777          *   <tbody>
778          *       <tr><th>status</th><th>String</th><th>screen status. ('ok'|'ng')</th><th>required</th></tr>
779          *   </tbody>
780          * </table>
781          * </div>
782          * @since 1.0
783          * @constant
784          */
785         SCREEN_STATUS: "SCREEN_STATUS",
786 
787         /**
788          * Current signal status.
789          * Corresponding data includes:
790          * <div align=left>
791          * <table class="hcap_spec" width=400>
792          *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
793          *   <tbody>
794          *       <tr><th>status</th><th>String</th><th>signal status. ('no_signal'|'signal_available')</th><th>required</th></tr>
795          *   </tbody>
796          * </table>
797          * </div>
798          * 
799          * @since 1.0
800          * @constant
801          */
802         SIGNAL_STATUS: "SIGNAL_STATUS"
803 
804     };
805 
806 	/**
807 	 * @namespace Signage.MonitoringSource
808 	 */
809     Signage.MonitoringSource = {
810         /**
811          * FAN 
812          * @since 1.0
813          * @constant
814          */
815         FAN: "FAN",
816         /**
817          * LAMP
818          * @since 1.0
819          * @constant
820          */
821         LAMP: "LAMP",
822         /**
823          * SIGNAL
824          * @since 1.0
825          * @constant
826          */
827         SIGNAL: "SIGNAL",
828         /**
829          * SCREEN
830          * @since 1.0
831          * @constant
832          */
833         SCREEN: "SCREEN",
834         /**
835          * THERMOMETER
836          * @since 1.0
837          * @constant
838          */
839         THERMOMETER: "THERMOMETER"
840 
841     };
842 
843     function checkErrorCodeNText(result, errorCode, errorText) {
844         
845         if (result.errorCode === undefined || result.errorCode === null ) {
846             result.errorCode = errorCode;
847         }
848         if (result.errorText === undefined || result.errorText === null) {
849             result.errorText = errorText;
850         }
851     }
852     
853     function getSystemSettings(category, keys, cbObjectGetter, successCallback, errorCallback) {
854         var params = {
855             category: category,
856             keys: keys
857         };
858 
859         service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
860             method: "get",
861             parameters: params,
862             onSuccess: function (result) {
863                 log("On Success");
864                 if (result.returnValue === true) {
865                     var cbObj = cbObjectGetter(result.settings);
866                     if (cbObj === false) {
867                         if (typeof errorCallback === 'function') {
868                             errorCallback({
869                                 errorText: "Invalid DB value",
870                                 errorCode: "DB_ERROR"
871                             });
872                         }
873                     }
874                     else {
875                         if (typeof successCallback === 'function') {
876                             log("successCallback");
877                             successCallback(cbObj);
878                         }
879                         else {
880                             log("successCallback not registered or is not a function: " + successCallback);
881                         }
882                     }
883                 }
884                 else {
885                     log("Settings Failed:  " + JSON.stringify(result, null, 3));
886 
887                     if (typeof errorCallback === 'function') {
888                         errorCallback({
889                             errorText: "Invalid DB value : " + result.errorText,
890                             errorCode: "DB_ERROR"
891                         });
892                     }
893 
894                 }
895             },
896             onFailure: function (result) {
897                 log("On Failure");
898                 delete result.returnValue;
899                 // See if any salvagable data
900                 if (result.settings) {
901                     log("settings = " + JSON.stringify(result.settings, null, 3));
902 
903                     var cbObject = cbObjectGetter(result.settings);
904 
905                     log("errorKey = " + JSON.stringify(result.errorKey, null, 3));
906 
907                     for (var i = 0; i < result.errorKey.length; ++i) {
908                         cbObject[result.errorKey[i]] = Signage.UNDEFINED;
909                     }
910 
911                     log("cbObj = " + JSON.stringify(cbObject, null, 3));
912                     if (typeof successCallback === 'function') {
913                         log("successCallback");
914                         successCallback(cbObject);
915                     }
916                 }
917                 else {
918                     if (typeof errorCallback === 'function') {
919                         errorCallback({
920                             errorText: ((typeof result.errorText === 'undefined') ? "DB Failure" : result.errorText),
921                             errorCode: "DB_ERROR"
922                         });
923                     }
924                 }
925             }
926         });
927 
928         log("Requested Service: " + "luna://com.webos.service.commercial.signage.storageservice/settings/");
929         log("params : " + JSON.stringify(params));
930     }
931 
932     function setSystemSettings(category, settings, successCallback, errorCallback) {
933         var params = {
934             category: category,
935             settings: settings
936         };
937 
938         log("settings : " + JSON.stringify(settings, null, 3));
939         var hasKey = false;
940         for (var key in settings) {
941             if (key) {
942                 log("has key : " + key);
943                 hasKey = true;
944                 break;
945             }
946         }
947         if (hasKey === false) {
948             log("Nothing to set");
949             successCallback();
950             return;
951         }
952 
953         service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
954             method: "set",
955             parameters: params,
956             onSuccess: function () {
957                 log("On Success");
958                 if (typeof successCallback === 'function') {
959                     log("SUCCEES CALLBACK");
960                     successCallback();
961                 }
962             },
963             onFailure: function (result) {
964                 log("On Failure");
965                 delete result.returnValue;
966                 if (typeof errorCallback === 'function') {
967                     log("ERROR CALLBACK");
968                     errorCallback(result);
969                 }
970             }
971         });
972 
973         log("Requested Service: " + "luna://com.webos.service.commercial.signage.storageservice/settings/");
974         log("params : " + JSON.stringify(params));
975     }
976 
977 
978 
979 
980 	/**
981 	 * <p>
982 	 * Sets Portrait Mode.
983 	 * </p>
984 	 * 
985 	 * @example 
986 	 * 
987 	 * function setPortraitMode() {
988 	 * 
989 	 *    var options = { 
990 	 *      portraitMode: Signage.OsdPortraitMode.ON
991 	 *    };
992 	 * 
993 	 *    var successCb = function (){
994 	 *      console.log("Portrait Mode successfully Set");
995 	 *    }; 
996 	 * 
997 	 *    var failureCb = function(cbObject){ 
998 	 *      var errorCode = cbObject.errorCode;
999 	 *      var errorText = cbObject.errorText;
1000 	 *       
1001 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
1002 	 *    };
1003 	 *   
1004 	 *    var signage = new Signage();         
1005 	 *    signage.setPortraitMode(successCb, failureCb, options);
1006 	 * }
1007 	 * 
1008 	 * @class Signage
1009 	 * @param {Function}
1010 	 *            successCallback success callback function.
1011 	 * @param {Function}
1012 	 *            errorCallback failure callback function.
1013 	 * @param {Object}
1014 	 *            options Input Parameters
1015 	 * @param {Signage.OsdPortraitMode}
1016 	 *            options.portraitMode Portrait mode. 
1017 	 * @returns
1018 	 *            <p>
1019 	 *            After the method is successfully executed, successCallback is called without any parameter.</br>
1020 	 *            If an error occurs, errorCallback is called with errorCode and errorText.
1021 	 *            </p>
1022 	 * 
1023 	 * @since 1.0
1024 	 */
1025     Signage.prototype.setPortraitMode = function (successCallback, errorCallback, options) {
1026         var settings = {};
1027 
1028         var errorMessage;
1029         function checkOptions(options) {
1030             if (options.portraitMode) {
1031                 for (var key in Signage.OsdPortraitMode) {
1032                     if (options.portraitMode === Signage.OsdPortraitMode[key]) {
1033                         return true;
1034                     }
1035                 }
1036 
1037                 errorMessage = "Signage.setPortraitMode: Unrecognized OsdPortraintMode : " + options.portraitMode;
1038                 return false;
1039             }
1040             else {
1041                 errorMessage = "Signage.setPortraitMode: portraitMode does not exist.";
1042                 return false;
1043             }
1044         }
1045         if (checkOptions(options)) {
1046             var portraintModeStr = options.portraitMode;
1047             settings[SETTINGS_KEY.OSD_PORTRAIT_MODE] = portraintModeStr;
1048 
1049 
1050             service.Request("luna://com.webos.service.commercial.signage.storageservice", {
1051                 method: "setOsdPortraitMode",
1052                 parameters: {
1053                     osdPortraitMode: options.portraitMode
1054                 },
1055                 onSuccess: function (result) {
1056                     successCallback();
1057                 },
1058                 onFailure: function (error) {
1059                     // If setOsdPortraitMode is not exists in storageservice (old firmware), call previous function
1060                     if (error.errorText.indexOf('Unknown method') !== -1) {
1061                         setSystemSettings("commercial", settings, successCallback, errorCallback);
1062                     }
1063                     // Else other error is occured. Call errorCallback.
1064                     else {
1065                         errorCallback({
1066                             errorCode: error.errorCode,
1067                             errorText: error.errorText
1068                         });
1069                     }
1070                 }
1071             });
1072 
1073             //setSystemSettings("commercial", settings, successCallback, errorCallback);
1074 
1075             log("setPortraitMode Done");
1076         }
1077         else { 
1078             errorCallback({
1079                 errorCode: "BAD_PARAMETER",
1080                 errorText: errorMessage
1081             });
1082         }        
1083     };
1084 
1085 
1086 	/**
1087 	 * <p>Sets Failover mode.
1088 	 *  When Failover Mode is set, monitor will automatically switch to the input source when the input signal fails, according to the predefined priorities set in the menu. </p>
1089 	 *  
1090 	 * <p>IMPORTANT NOTE!!!!</p>
1091 	 * 
1092 	 * <p>
1093 	 * When failover is triggered due to lost signal, the signage application will 
1094 	 * yield to the next priority input source set in the failover mode and run in the background. 
1095 	 * </p>
1096 	 * <p>
1097 	 * If the signage application should always be running in the foreground, failover mode should be set to OFF.
1098 	 * </p>
1099 	 *  
1100 	 * @example 
1101 	 * 
1102 	 * function setFailoverMode() {
1103 	 * 
1104 	 *    //Available input types and number of input ports for each input types may differ model by model. 
1105 	 *    var options = { 
1106 	 *      failoverMode : {
1107 	 *         mode: Signage.FailoverMode.MANUAL,
1108 	 *         priority : [
1109 	 *            'ext://hdmi:1',
1110 	 *            'ext://hdmi:2',
1111 	 *            'ext://dvi:1',
1112 	 *            'ext://internal_memory',
1113 	 *            'ext://dp:1'
1114 	 *         ]
1115 	 *      }
1116 	 *    }; 
1117 	 *     
1118 	 *    var successCb = function (){
1119 	 *      console.log('Successfully set Failover Mode');
1120 	 *    }; 
1121 	 *         
1122 	 *    var failureCb = function(cbObject){ 
1123 	 *      var errorCode = cbObject.errorCode; 
1124 	 *      var errorText = cbObject.errorText; 
1125 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
1126 	 *    }; 
1127 	 * 
1128 	 *    var signage = new Signage();
1129 	 *    signage.setFailoverMode(successCallback, errorCallback, options);
1130 	 * }
1131 	 * 
1132 	 * @class Signage
1133 	 * @param {Function} successCallback success callback function.
1134 	 * @param {Function} errorCallback failure callback function.
1135 	 * @param {Object} options Input Parameters
1136 	 * @param {Object} options.failoverMode Failover mode. Only attributes that exist will be set.
1137 	 * 
1138 	 * <div align=left>
1139 	 * <table class="hcap_spec" width=400>
1140 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
1141 	 *   <tbody>
1142 	 *       <tr><th>mode</th><th><a href="Signage.FailoverMode.html#constructor">Signage.FailoverMode</a></th><th>Failover mode</th><th>required</th></tr>
1143 	 *       <tr class="odd"><th>priority</th><th>Array</th><th>Input priority that will be used when mode is MANUAL.<br> 
1144 	 *       This parameter should be present only when mode is set to MANUAL(error is returned otherwise).</th><th>optional</th></tr>
1145 	 *   </tbody>
1146 	 * </table>
1147 	 * </div>
1148 	 * 
1149 	 * Input source can be one of the following. Some of the input type may not be supported for a specific model. 
1150 	 * <div align=left>
1151 	 * <table class="hcap_spec" width=400>
1152 	 *   <thead><tr><th>Name</th><th>Description</th></tr></thead>
1153 	 *   <tbody>
1154 	 *       <tr><th>ext://hdmi:[index]</th><th>HDMI Input</th></tr>
1155 	 *       <tr class="odd"><th>ext://dvi:[index]</th><th>DVI Input</th></tr>
1156 	 *       <tr><th>ext://rgb:[index]</th><th>RGB input</th></tr>
1157 	 *       <tr class="odd"><th>ext://dp:[index]</th><th>Display port Input</th></tr>
1158 	 *       <tr><th>ext://ops:[index]</th><th>OPS input</th></tr>
1159 	 *       <tr class="odd"><th>ext://internal_memory</th><th>Internal Storage</th></tr>
1160 	 *       <tr><th>ext://usb:[index]</th><th>External USB storage at usb port [index]</th></tr>
1161 	 *       <tr class="odd"><th>ext://sdCard:[index]</th><th>External sd card Storage at sd card port [index]</th></tr>
1162 	 *   </tbody>
1163 	 * </table>
1164 	 * </div>
1165 	 * @returns  <p>After the method is successfully executed, successCallback is called without any parameter.</p>
1166 	 *  <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
1167 	 * 
1168 	 * @since 1.0
1169 	 */
1170     Signage.prototype.setFailoverMode = function (successCallback, errorCallback, options) {
1171         var settings = {};
1172 
1173         var errorMessage;
1174         function checkOptions(options) {
1175             log("options:" + JSON.stringify(options, null, 3));
1176             var failoverMode = options.failoverMode;
1177             if (failoverMode) {
1178 
1179                 if (failoverMode.mode) {
1180                     // If manual, see if priority is defined.
1181                     if (failoverMode.mode === Signage.FailoverMode.MANUAL) {
1182                         if (failoverMode.priority) {
1183                             if (failoverMode.priority.length === 0 || typeof failoverMode.priority.length === 'undefined') {
1184                                 return false;
1185                             }
1186                             else {
1187                                 return true;
1188                             }
1189                         }
1190                         else {
1191                             errorMessage = "priority should be present when mode is MANUAL.";
1192                             return false;
1193                         }
1194                     }
1195                     else {
1196                         // if not manual, return error if priority is defined.
1197                         if (failoverMode.priority) {
1198                             errorMessage = "This priority is available only if mode is : Signage.FailoverMode.MANUAL";
1199                             return false;
1200                         }
1201                         else {
1202                             var found = false;
1203                             // Should be one of the FailoverMode
1204                             log("Mode is: " + failoverMode.mode);
1205                             for (var key in Signage.FailoverMode) {
1206                                 if (failoverMode.mode === Signage.FailoverMode[key]) {
1207                                     log("Matched with: " + Signage.FailoverMode[key]);
1208                                     found = true;
1209                                 }
1210                             }
1211 
1212                             if (!found) {
1213                                 log("Unrecognized failoverMode : " + failoverMode.mode);
1214                                 errorMessage = "Unrecognized failoverMode : " + failoverMode.mode;
1215                                 return false;
1216                             }
1217                             else {
1218                                 return true;
1219                             }
1220 
1221                         }
1222                     }
1223                 }
1224                 else {
1225                     if (!failoverMode.priority) {
1226                         return true;
1227                     }
1228                     else {
1229                         log("Unrecognized failoverMode : " + failoverMode.mode);
1230                         errorMessage = "Unrecognized failoverMode : " + failoverMode.mode;
1231                         return false;
1232                     }
1233                 }
1234             }
1235             else {
1236                 errorMessage = "Fail over mode not set : ";
1237                 return false;
1238             }
1239 
1240         }
1241 
1242         if (checkOptions(options)) {
1243             var failoverMode = options.failoverMode;
1244             if (!failoverMode.mode && !failoverMode.priority) {
1245                 successCallback();
1246             }
1247             else if (failoverMode.mode === Signage.FailoverMode.MANUAL) {
1248                 /*
1249 				var priority = failoverMode.priority;
1250 				log("priority: " + failoverMode.priority);
1251 				for(var i=0;i<5; ++i){
1252                     var attrName = SETTINGS_KEY.FAILOVER_PRIORITY + (i+1);
1253                     log("attrName: " + attrName);
1254                     var inputValue = "";
1255                     if(i<priority.length) {
1256                         var inputUri = priority[i];
1257                         log("input: " + inputUri);
1258                         inputValue = getInputValue(inputUri);
1259                         if(inputValue === false){
1260                             var cbObj = {
1261                                 errorCode : 'API_ERROR',
1262                                 errorText : inputUri + " is not valid"
1263                             };
1264                             errorCallback(cbObj);
1265                             return;
1266                         }
1267 				    }
1268 				    else {
1269 				        log("No more input URI");
1270 				    }
1271 				    log("inputValue: " + inputValue);
1272 				    settings[attrName] = inputValue;
1273 				}
1274 
1275 				settings[SETTINGS_KEY.FAILOVER_MODE] = failoverMode.mode;
1276                 */
1277                 service.Request("luna://com.webos.service.commercial.signage.storageservice", {
1278                     method: "setManualFailoverPrioirty",
1279                     parameters: {
1280                         priority: failoverMode.priority
1281                     },
1282                     onSuccess: function (result) {
1283                         log("onSuccess");
1284                         if (result.returnValue) {
1285                             successCallback();
1286                         }
1287                         else {
1288                             log("FAILED: " + result.errorText);
1289                             errorCallback({
1290                                 errorCode: result.errorCode,
1291                                 errorText: result.errorText
1292                             });
1293                         }
1294                     },
1295                     onFailure: function (result) {
1296                         log("onFailure");
1297                         log("FAILED: " + result.errorText);
1298                         errorCallback({
1299                             errorCode: result.errorCode,
1300                             errorText: result.errorText
1301                         });
1302                     }
1303                 });
1304 
1305             }
1306             else if (failoverMode.mode) {
1307                 var modeStr = failoverMode.mode;
1308                 log("mode: " + failoverMode.mode);
1309                 settings[SETTINGS_KEY.FAILOVER_MODE] = modeStr;
1310                 settings[SETTINGS_KEY.FAILOVER_BACKUPVIASTORAGE_MODE] = modeStr;
1311                 log("Set: " + JSON.stringify(settings, null, 3));
1312 
1313                 setSystemSettings("commercial", settings, successCallback, errorCallback);
1314 
1315                 log("setFailoverMode Done");
1316             }
1317             else {
1318                 var errorObj = {
1319                     errorCode: "BAD_PARAMETER",
1320                     errorText: "Mode should be set."
1321                 };
1322                 errorCallback(errorObj);
1323             }
1324         }
1325         else {
1326             var errorObj2 = {
1327                 errorCode: "BAD_PARAMETER",
1328                 errorText: errorMessage
1329             };
1330             errorCallback(errorObj2);
1331         }
1332     };
1333 
1334 	/**
1335 	 * <p>Gets Failover mode.
1336 	 *  When Failover Mode is set, monitor will automatically switch to the input source when the input signal fails, according to the predefined priorities set in the menu. </p>
1337 	 *  
1338 	 * <p>IMPORTANT NOTE!!!!</p>
1339 	 * <br>
1340 	 * When failover is triggered due to lost signal, the signage application will not
1341 	 * yield to the next priority input source set in the failover mode. When the signage application is destroyed, failover mode will be triggered.  
1342 	 *  
1343 	 * @example
1344 	 * function getFailoverMode() {
1345 	 * 
1346 	 *    var successCb = function (cbObject){
1347 	 *      var mode = cbObject.mode;
1348 	 *      var priority = cbObject.priority
1349 	 *      
1350 	 *      console.log('Failover Mode : ' + mode);
1351 	 *      console.log('Priority : ' + priority);
1352 	 *    }; 
1353 	 *         
1354 	 *    var failureCb = function(cbObject){ 
1355 	 *      var errorCode = cbObject.errorCode; 
1356 	 *      var errorText = cbObject.errorText;
1357 	 *       
1358 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
1359 	 *    }; 
1360 	 * 
1361 	 *    var signage = new Signage();
1362 	 *    signage.getFailoverMode(successCb, failureCb);
1363 	 * }
1364 	 * 
1365 	 * @class Signage
1366 	 * @param {Function} successCallback success callback function.
1367 	 * @param {Function} errorCallback failure callback function.
1368 	 * @returns  <p>After the method is successfully executed, successCallback is called with the following parameters</p>
1369 	 * <div align=left>
1370 	 * <table class="hcap_spec" width=400>
1371 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
1372 	 *   <tbody>
1373 	 *       <tr><th>mode</th><th><a href="Signage.FailoverMode.html#constructor">Signage.FailoverMode</a> | Signage.UNDEFINED</th><th>Failover mode. Signage.UNDEFINED is returned when this item is not set.</th></tr>
1374 	 *       <tr class="odd"><th>priority</th><th>Array</th><th>Input priority, as an ordered array of input source URI. Only valid when mode is set to MANUAL.</th></tr>
1375 	 *   </tbody>
1376 	 * </table>
1377 	 * </div>
1378 	 * 
1379 	 * Input source can be : 
1380 	 * <div align=left>
1381 	 * <table class="hcap_spec" width=400>
1382 	 *   <thead><tr><th>Name</th><th>Description</th></tr></thead>
1383 	 *   <tbody>
1384 	 *       <tr><th>ext://hdmi:[index]</th><th>HDMI Input</th></tr>
1385 	 *       <tr class="odd"><th>ext://dvi:[index]</th><th>DVI Input</th></tr>
1386 	 *       <tr><th>ext://internal_memory</th><th>Internal Storage</th></tr>
1387 	 *       <tr class="odd"><th>ext://dp:[index]</th><th>Display Port</th></tr>
1388 	 *   </tbody>
1389 	 * </table>
1390 	 * </div>
1391 	 *  <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
1392 	 * 
1393 	 * @since 1.0
1394 	 */
1395     Signage.prototype.getFailoverMode = function (successCallback, errorCallback) {
1396         try {
1397             service.Request("luna://com.webos.service.commercial.signage.storageservice", {
1398                 method: "getFailoverPrioirty",
1399                 parameters: {},
1400                 onSuccess: function (result) {
1401                     log("onSuccess");
1402                     if (result.returnValue) {
1403                         successCallback({
1404                             priority: result.priority,
1405                             mode: result.mode
1406                         });
1407                     }
1408                     else {
1409                         log("FAILED: " + result.errorText);
1410                         errorCallback({
1411                             errorCode: result.errorCode,
1412                             errorText: result.errorText
1413                         });
1414                     }
1415                 },
1416                 onFailure: function (result) {
1417                     log("onFailure");
1418                     log("FAILED: " + result.errorText);
1419                     errorCallback({
1420                         errorCode: result.errorCode,
1421                         errorText: result.errorText
1422                     });
1423                 }
1424             });
1425         } catch (err) {
1426             log("EXCEPTION" + err);           
1427             errorCallback({
1428                 errorCode: "SGFO", // Temperatory error code
1429                 errorText: "Signage.getFailoverMode occur error during operaation."
1430             });
1431         }
1432     };
1433 
1434 
1435     function getByType(val, type) {
1436         var mytype = typeof val;
1437         log("mytype: " + mytype);
1438         log("type: " + type);
1439 
1440         if (mytype === 'undefined') {
1441             return true;
1442         }
1443         else if (mytype === type) {
1444             return val;
1445         }
1446         else {
1447             return false;
1448         }
1449     }
1450 
1451 
1452 	/**
1453 	 * <p>Sets tile mode. Tile mode is used for multi-monitor display.</p>
1454 	 * @example 
1455 	 * 
1456 	 * function setTileInfo() {
1457 	 *    var options = {
1458 	 *      tileInfo: {
1459 	 *         enabled: true,
1460 	 *         row : 2,
1461 	 *         column : 2,
1462 	 *         tileId: 2,
1463 	 *         naturalMode : true
1464 	 *      }
1465 	 *    };
1466 	 * 
1467 	 *    var successCb = function (){
1468 	 *      console.log("Tile Info successfully Set");
1469 	 *    }; 
1470 	 * 
1471 	 *    var failureCb = function(cbObject){ 
1472 	 *      var errorCode = cbObject.errorCode; 
1473 	 *      var errorText = cbObject.errorText; 
1474 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
1475 	 *    };
1476 	 * 
1477 	 *    var signage = new Signage();
1478 	 *    signage.setTileInfo(successCb, failureCb, options);
1479 	 * }
1480 	 * 
1481 	 * @class Signage
1482 	 * @param {Function} successCallback success callback function.
1483 	 * @param {Function} errorCallback failure callback function.
1484 	 * @param {Object} options  parameter list.
1485 	 * @param {Object} options.tileInfo  TileInfo Object for setting.
1486 	 * Only attributes that exist will be set.
1487 	 * <div align=left>
1488 	 * <table class="hcap_spec" width=400>
1489 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
1490 	 *   <tbody>
1491 	 *       <tr><th>enabled</th><th>Boolean</th><th>Enable/disable Tile Mode</th><th>optional</th></tr>
1492 	 *       <tr class="odd"><th>row</th><th>Number</th><th>Number of rows (1~15)</th><th>optional</th></tr>
1493 	 *       <tr><th>column</th><th>Number</th><th>Number of columns (1~15)</th><th>optional</th></tr>
1494 	 *       <tr class="odd"><th>tileId</th><th>Number</th><th>The ID for this monitor. It will start to count from 1, left to right and top to bottom (1~Rows x Columns)</th><th>optional</th></tr>
1495 	 *       <tr><th>naturalMode</th><th>Boolean</th><th>Enable/disable Natural mode, which will adjust image based on the bezel size</th><th>optional</th></tr>
1496 	 *   </tbody>
1497 	 * </table>
1498 	 * </div>
1499 	 * 
1500 	 * @returns  <p>After the method is successfully executed, successCallback is called without any parameter.</br>
1501 	 * If an error occurs, errorCallback is called with errorCode and errorText.</p>
1502 	 * 
1503 	 * @since 1.0
1504 	 */
1505     Signage.prototype.setTileInfo = function (successCallback, errorCallback, options) {
1506         var errorMessage;
1507         var checkOptions = function (options, tileRowMax, tileColMax) {
1508             var enabledType = typeof options.tileInfo.enabled;
1509             log("enabledType:" + enabledType);
1510             if (enabledType !== 'undefined' && enabledType !== 'boolean') {
1511                 errorMessage = "enabled should be a boolean";
1512                 return false;
1513             }
1514 
1515             var isNotANaturalNumber = function (isNum) {
1516                 var ret = new RegExp(/^[0-9]+$/g).exec(isNum);
1517                 if (ret) {
1518                     return false;
1519                 }
1520                 else {
1521                     return true;
1522                 }
1523             };
1524 
1525             if (options.tileInfo) {
1526                 var row = options.tileInfo.row;
1527                 if (typeof row !== 'undefined') {
1528                     if (isNotANaturalNumber(row)) {
1529                         errorMessage = "row should be a natural number :" + row;
1530                         return false;
1531                     }
1532                     else if (row > tileRowMax || row < 1) {
1533                         errorMessage = "row should be 0<n<" + (tileRowMax+1) + " but :" + row;
1534                         return false;
1535                     }
1536                 }
1537                 else {
1538                     return true;
1539                 }
1540 
1541                 var column = options.tileInfo.column;
1542                 if (typeof column !== 'undefined') {
1543                     if (isNotANaturalNumber(column)) {
1544                         errorMessage = "column should be a natural number :" + column;
1545                         return false;
1546                     }
1547                     else if (column > tileColMax || column < 1) {
1548                         errorMessage = "column should be 0<n<" + (tileColMax+1) + " but :" + column;
1549                         return false;
1550                     }
1551                 }
1552                 else {
1553                     return true;
1554                 }
1555 
1556                 var id = options.tileInfo.tileId;
1557                 if (typeof id !== 'undefined') {
1558                     if (isNotANaturalNumber(id)) {
1559                         errorMessage = "id should be a natural number :" + id;
1560                         return false;
1561                     }
1562                     else if (id < 1) {
1563                         errorMessage = "id should be bigger than 0 but :" + id;
1564                         return false;
1565                     }
1566                     else {
1567                         var curRow = _gTileInfo.row;
1568                         if (row) { curRow = row; }
1569 
1570                         var curCol = _gTileInfo.column;
1571                         if (column) { curCol = column; }
1572 
1573                         log("curRow : " + curRow);
1574                         log("curCol : " + curCol);
1575                         log("id : " + id);
1576 
1577 
1578                         if (id > curCol * curRow) {
1579                             errorMessage = "ID should be less than curRow*curCol";
1580                             return false;
1581                         }
1582                     }
1583                 }
1584                 else {
1585                     return true;
1586                 }
1587             } else {
1588                 errorMessage = "Tile info is mandatory";
1589                 return false;
1590             }
1591             return true;
1592         };
1593 
1594         var rowMax = 15;
1595         var colMax = 15;
1596 
1597         service.Request("luna://com.webos.service.config", {
1598             method: "getConfigs",
1599             parameters: {
1600                 configNames: ["commercial.video.tileRowMax","commercial.video.tileColMax"]
1601             },
1602             onSuccess: function(result) {
1603                 log("onSuccess");
1604                 if (result.returnValue) {
1605                     rowMax = result.configs["commercial.video.tileRowMax"];
1606                     colMax = result.configs["commercial.video.tileColMax"];
1607 
1608                     if (checkOptions(options, rowMax, colMax) === true) {
1609                         var tileInfo = options.tileInfo;
1610                         var settings = {};
1611 
1612                         if (typeof tileInfo.enabled === 'boolean') {
1613                             if (tileInfo.enabled) {
1614                                 settings[SETTINGS_KEY.TILE_MODE] = 'on';
1615                             } else {
1616                                 settings[SETTINGS_KEY.TILE_MODE] = 'off';
1617                             }
1618                         }
1619 
1620                         if (tileInfo.row) {
1621                             settings[SETTINGS_KEY.TILE_ROW] = tileInfo.row.toString();
1622                         }
1623 
1624                         if (tileInfo.column) {
1625                             settings[SETTINGS_KEY.TILE_COLUME] = tileInfo.column.toString();
1626                         }
1627 
1628                         if (tileInfo.tileId) {
1629                             settings[SETTINGS_KEY.TILE_ID] = tileInfo.tileId.toString();
1630                         }
1631 
1632                         if (typeof tileInfo.naturalMode === 'boolean') {
1633                             if (tileInfo.naturalMode) {
1634                                 settings[SETTINGS_KEY.TILE_NATURALMODE] = 'on';
1635                             } else {
1636                                 settings[SETTINGS_KEY.TILE_NATURALMODE] = 'off';
1637                             }
1638                         }
1639 
1640                         log("Set: " + JSON.stringify(settings, null, 3));
1641 
1642 
1643                         var newCallBack = function() {
1644                             log("Do callback");
1645 
1646                             if (tileInfo.row) {
1647                                 _gTileInfo.row = tileInfo.row;
1648                             }
1649 
1650                             if (tileInfo.column) {
1651                                 _gTileInfo.column = tileInfo.column;
1652                             }
1653 
1654                             if (typeof successCallback === 'function') {
1655                                 log("Invoke successCallback");
1656                                 successCallback();
1657                                 log("Invoked successCallback");
1658                             }
1659                         };
1660                         setSystemSettings("commercial", settings, newCallBack, errorCallback);
1661         
1662                         log("setTileInfo Done");
1663                     } else {
1664                         var cbObj = {
1665                             errorCode: "BAD_PARAM",
1666                             errorText: errorMessage
1667                         };
1668                         errorCallback(cbObj);
1669                     }
1670                 } else {
1671                     log("FAILED: " + result.errorText);
1672                     errorCallback({
1673                         errorCode: result.errorCode,
1674                         errorText: result.errorText
1675                     });
1676                 }
1677             },
1678             onFailure: function(result) {
1679                 log("onFailure");
1680                 log("FAILED: " + result.errorText);
1681                 errorCallback({
1682                     errorCode: result.errorCode,
1683                     errorText: result.errorText
1684                 });
1685             }
1686         });        
1687 
1688     };
1689 
1690     function getBooleanValue(value) {
1691         if (value === 'on') { 
1692             return true; 
1693         } 
1694         else {
1695             return false;
1696         }
1697     }
1698 
1699 	/**
1700 	 * <p>Gets current tile mode.</p>
1701 	 * @example 
1702 	 * function getTileInfo() {
1703 	 *    
1704 	 *    var successCb = function (cbObject){
1705 	 *    
1706 	 *      var enabled = cbObject.enabled;
1707 	 *      var row = cbObject.row;
1708 	 *      var column = cbObject.column;
1709 	 *      var tileId = cbObject.tileId;
1710 	 *      var naturalMode = cbObject.naturalMode;
1711 	 *      
1712 	 *      console.log("enable: " + enabled);
1713 	 *      console.log("row: " + row);	
1714 	 *      console.log("column: " + column);
1715 	 *      console.log("tileId: " + tileId);	
1716 	 *      console.log("naturalMode: " + naturalMode);	
1717 	 *    };
1718 	 *  
1719 	 *    var failureCb = function(cbObject){ 
1720 	 *      var errorCode = cbObject.errorCode; 
1721 	 *      var errorText = cbObject.errorText; 
1722 	 *      
1723 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
1724 	 *    };
1725 	 * 
1726 	 *    var signage = new Signage();
1727 	 *    signage.getTileInfo(successCb, failureCb);
1728 	 * }
1729 	 * 
1730 	 * @class Signage
1731 	 * @param {Function} successCallback success callback function.
1732 	 * @param {Function} errorCallback failure callback function.
1733 	 * 
1734 	 * @returns  <p>After the method is successfully executed, successCallback is called with following data.</p>
1735 	 * <div align=left>
1736 	 * <table class="hcap_spec" width=400>
1737 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
1738 	 *   <tbody>
1739 	 *       <tr><th>enabled</th><th>Boolean</th><th>Enable/disable Tile Mode</th></tr>
1740 	 *       <tr class="odd"><th>row</th><th>Number</th><th>Number of rows (1~15)</th></tr>
1741 	 *       <tr><th>column</th><th>Number</th><th>Number of columns (1~15)</th></tr>
1742 	 *       <tr class="odd"><th>tileId</th><th>Number</th><th>The ID for this monitor. It will start to count from 1, left to right and top to bottom (1~Rows x Columns)</th></tr>
1743 	 *       <tr><th>naturalMode</th><th>Boolean</th><th>Enable/disable Natural mode, which will adjust image based on the bezel size</th></tr>
1744 	 *   </tbody>
1745 	 * </table>
1746 	 * </div>
1747 	 * 
1748 	 * 
1749 	 * <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
1750 	 * 
1751 	 * @since 1.0
1752 	 */
1753     Signage.prototype.getTileInfo = function (successCallback, errorCallback) {
1754         var cbgetter = function (settings) {
1755             var cbObj = {};
1756             log("settings Value: " + JSON.stringify(settings, null, 3));
1757             cbObj.enabled = getBooleanValue(settings[SETTINGS_KEY.TILE_MODE]);
1758             cbObj.row = parseInt(settings[SETTINGS_KEY.TILE_ROW], 10);
1759             cbObj.column = parseInt(settings[SETTINGS_KEY.TILE_COLUME], 10);
1760             cbObj.tileId = parseInt(settings[SETTINGS_KEY.TILE_ID], 10);
1761             cbObj.naturalMode = getBooleanValue(settings[SETTINGS_KEY.TILE_NATURALMODE]);
1762 
1763             log("Return Value: " + JSON.stringify(cbObj, null, 3));
1764             return cbObj;
1765         };
1766 
1767         var keys = [SETTINGS_KEY.TILE_MODE, SETTINGS_KEY.TILE_ROW, SETTINGS_KEY.TILE_COLUME, SETTINGS_KEY.TILE_ID, SETTINGS_KEY.TILE_NATURALMODE];
1768         getSystemSettings("commercial", keys, cbgetter, successCallback, errorCallback);
1769     };
1770 
1771 	/**
1772 	 * <p>Gets signage information</p>
1773 	 * 
1774 	 * @example 
1775 	 * 
1776 	 * function getSignageInfo() {
1777 	 * 
1778 	 *    var successCb = function (cbObject){
1779 	 *      var portraitMode= cbObject.signageInfo;
1780 	 *      var ismMethod= cbObject.ismMethod;
1781 	 *      var digitalAudioInputMode= cbObject.digitalAudioInputMode;
1782 	 * 
1783 	 *      console.log("portraitMode: " + portraitMode);
1784 	 *      console.log("ismMethod: " + ismMethod);
1785 	 *   
1786 	 *      for(var input in digitalAudioInputMode){
1787 	 *         var audioInput = digitalAudioInputMode[input];
1788 	 *         console.log("digitalAudioInputMode for " + input +" = " + audioInput);
1789 	 *      }
1790 	 *    }; 
1791 	 * 
1792 	 *    var failureCb = function(cbObject){ 
1793 	 *      var errorCode = cbObject.errorCode; 
1794 	 *      var errorText = cbObject.errorText; 
1795 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
1796 	 *    };
1797 	 * 
1798 	 *    var signage = new Signage();
1799 	 *    signage.getSignageInfo(successCb, failureCb);
1800 	 * 
1801 	 * }
1802 	 * 
1803 	 * @class Signage
1804 	 * @param {Function} successCallback success callback function.
1805 	 * @param {Function} errorCallback failure callback function.
1806 	 * 
1807 	 * @returns  <p>After the method is successfully executed, successCallback is called with the following parameters.</p>
1808 	 * 
1809 	 * <div align=left>
1810 	 * <table class="hcap_spec" width=400>
1811 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
1812 	 *   <tbody>
1813 	 *       <tr><th>portraitMode</th><th>Signage.OsdPortraitMode | Signage.UNDEFINED</th><th>Portrait mode.<br>If the value for this item is not set or defined, Signage.UNDEFINED will be returned. </th></tr>
1814 	 *       <tr class="odd"><th>ismMethod</th><th>Signage.IsmMethod | Signage.UNDEFINED</th><th>ISM(Image Sticking Minimization) Method.<br>If the value for this item is not set or defined, Signage.UNDEFINED will be returned. </th></tr>
1815 	 *       <tr><th>digitalAudioInputMode</th><th>Array</th><th>Digital audio input mode.<br>Array of {input_uri : Signage.DigitalAudioInput or Signage.UNDEFINED } pair. </th></tr>
1816 	 *       <tr class="odd"><th>checkScreen</th><th>Boolean</th><th>Pixel sensor is enabled. true: enabled, false: disabled <br>If it is enabled, Signage.EventType.SCREEN_STATUS event is available. </th></tr>
1817 	 *   </tbody>
1818 	 * </table>
1819 	 * </div>
1820 	 * 
1821 	 * <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
1822 	 * 
1823 	 * @since 1.0
1824 	 * @since 1.3 checkScreen
1825 	 */
1826     Signage.prototype.getSignageInfo = function (successCallback, errorCallback) {
1827         service.Request("luna://com.webos.service.commercial.signage.storageservice/", {
1828             method: "getSignageInformation",
1829             parameters: {},
1830             onSuccess: function (res) {
1831                 if (typeof successCallback === 'function') {
1832                     log(res.signageInfo);
1833                     successCallback(res.signageInfo);
1834                 }
1835             },
1836             onFailure: function (result) {
1837                 delete result.returnValue;
1838                 if (typeof errorCallback === 'function') {
1839                     errorCallback(result);
1840                 }
1841             }
1842         });
1843     };
1844 
1845 	/**
1846      * <p>Enables pixel sensor.</p>
1847      * 
1848      * @class Signage
1849      * @param {Function} successCallback success callback function.
1850      * @param {Function} errorCallback failure callback function.
1851      * @param {Object} options
1852      * <div align=left>
1853      * <table class="hcap_spec" width=400>
1854      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
1855      *   <tbody>
1856      *       <tr><th>checkScreen</th><th>Boolean</th><th>true : enabled / false : disabled </th><th>required</th></tr>
1857      *   </tbody>
1858      * </table>
1859      * </div>
1860      * @return <p>If the method is successfully executed, success callback function is called without a parameter.</br>
1861      * If an error occurs, failure callback function is called with failure callback object as a parameter.</p>
1862      * 
1863      * @example 
1864      * function enableCheckScreen() {
1865      * 
1866      *    var successCb = function (){
1867      *      console.log("Successfully enabled checkScreen");
1868      *    };
1869      * 
1870      *    var failureCb = function(cbObject){ 
1871      *      var errorCode = cbObject.errorCode; 
1872      *      var errorText = cbObject.errorText; 
1873      *      console.log( " Error Code [" + errorCode + "]: " + errorText);
1874      *    };
1875      *    
1876      *    var options = {
1877      *      checkScreen : true
1878      *    };
1879      *    
1880      *    var signage = new Signage();
1881      *    signage.enableCheckScreen(successCb, failureCb, options);
1882      * }
1883      * 
1884      * @since 1.3
1885      * 
1886      * @see
1887      * <a href="Signage%23getSignageInfo.html">Signage.getSignageInfo()</a><br>
1888      */
1889     Signage.prototype.enableCheckScreen = function (successCallback, errorCallback, options) {
1890 
1891         var errorMessage;
1892 
1893         var checkOptions = function (options) {
1894             if (typeof options.checkScreen !== "undefined" || options.checkScreen !== null) {
1895                 return true;
1896             } else {
1897                 errorMessage = "need options.checkScreen.";
1898                 return false;
1899             }
1900         };
1901 
1902         if (checkOptions(options)) {
1903 
1904             var settings = {
1905                 checkScreen: (options.checkScreen === true ? "on" : "off")
1906             };
1907 
1908             log("Set: " + JSON.stringify(settings, null, 3));
1909 
1910             setSystemSettings("commercial", settings, successCallback, errorCallback);
1911 
1912             log("enableCheckScreen Done");
1913         } else {
1914             var cbObj = {
1915                 errorCode: "BAD_PARAMETER",
1916                 errorText: errorMessage
1917             };
1918             errorCallback(cbObj);
1919         }
1920     };
1921     
1922 	/**
1923 	 * <p>Sets ISM(Image Sticking Minimization) Method.</p>
1924 	 * 
1925 	 * @example 
1926 	 * 
1927 	 * function setIsmMethod() {
1928 	 *    var options = {
1929 	 *      ismMethod : Signage.IsmMethod.NORMAL
1930 	 *    };
1931 	 * 
1932 	 *    var successCb = function (){
1933 	 *      console.log("Successfully set ISM Method");
1934 	 *    };
1935 	 * 
1936 	 *    var failureCb = function(cbObject){ 
1937 	 *      var errorCode = cbObject.errorCode; 
1938 	 *      var errorText = cbObject.errorText; 
1939 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText);
1940 	 *    };
1941 	 * 
1942 	 *    var signage = new Signage();
1943 	 *    signage.setIsmMethod (successCb, failureCb, options);
1944 	 * }
1945 	 * 
1946 	 * @class Signage
1947 	 * @param {Function} successCallback success callback function.
1948 	 * @param {Function} errorCallback failure callback function.
1949 	 * @param {Object} options  parameter list.
1950 	 * @param {Signage.IsmMethod} options.ismMethod ISM Method.
1951 	 * @returns  
1952 	 * <p>
1953 	 * After the method is successfully executed, successCallback is called without any parameter.</br>
1954 	 * If an error occurs, errorCallback is called with errorCode and errorText.</p>
1955 	 * 
1956 	 * @since 1.0
1957 	 */
1958     Signage.prototype.setIsmMethod = function (successCallback, errorCallback, options) {
1959         var settings = {};
1960         var errorMessage;
1961         function checkOptions(options, hasUserImage, hasUserVideo) {
1962             if (options.ismMethod) {
1963 
1964                 if((hasUserImage === false && options.ismMethod === Signage.IsmMethod.USER_IMAGE) || 
1965                     (hasUserVideo === false && (options.ismMethod === Signage.IsmMethod.USER_IMAGE || options.ismMethod === Signage.IsmMethod.USER_VIDEO)))
1966                 {
1967                     errorMessage = "no supported ismMethod  : " + options.ismMethod;
1968                     return false;
1969                 }                
1970 
1971                 for (var key in Signage.IsmMethod) {
1972                     if (options.ismMethod === Signage.IsmMethod[key]) {
1973                         return true;
1974                     }
1975                 }
1976 
1977                 errorMessage = "Unrecognized ismMethod  : " + options.ismMethod;
1978                 return false;
1979             }
1980             else {
1981                 errorMessage = "ismMethod  does not exist.";
1982                 return false;
1983             }
1984         }
1985 
1986 
1987         service.Request("luna://com.webos.service.config/", {
1988             method: "getConfigs",
1989             parameters: {
1990                 configNames: ["commercial.applist.disablePhoto","commercial.unsupportedFeatures"]
1991             },
1992             onSuccess: function(result) {
1993                 if (typeof successCallback === 'function' && result.returnValue === true) {
1994                     //successCallback();
1995 
1996                     var hasUserImage = true;
1997                     var hasUserVideo = true;
1998                     var disablePhoto = result.configs["commercial.applist.disablePhoto"];
1999                     for (var i = 0; i < disablePhoto.length; i++) {
2000                         if (disablePhoto[i].toLowerCase() === "com.webos.app.ism") {
2001                             hasUserImage = false;
2002 
2003                             break;
2004                         }
2005                     }
2006 
2007                     var unsupportedFeatures = result.configs["commercial.unsupportedFeatures"];
2008                     for (var j = 0; j < unsupportedFeatures.length; j++) {
2009                         if (unsupportedFeatures[j].toLowerCase() === "usb") {
2010                             hasUserImage = false;
2011                             hasUserVideo = false;
2012 
2013                             break;
2014                         }
2015                     }
2016 
2017                     if (checkOptions(options, hasUserImage, hasUserVideo)) {
2018                         if (options.ismMethod) {
2019                             var ismMethod = options.ismMethod;
2020                             log("ismMethod : " + ismMethod);
2021                             settings[SETTINGS_KEY.ISM_METHOD] = ismMethod;
2022                         }
2023 
2024                         log("Set: " + JSON.stringify(settings, null, 3));
2025 
2026                         setSystemSettings("commercial", settings, successCallback, errorCallback);
2027 
2028                         log("setIsmMethod Done");
2029                     } else {
2030                         var cbObj = {
2031                             errorCode: "BAD_PARAMETER",
2032                             errorText: errorMessage
2033                         };
2034                         errorCallback(cbObj);
2035                     }
2036                 }
2037             },
2038             onFailure: function(result) {
2039                 delete result.returnValue;
2040                 if (typeof errorCallback === 'function') {
2041                     errorCallback(result);
2042                 }
2043             }
2044         });
2045     };
2046 
2047 
2048 
2049 	/**
2050 	 * <p>Sets digital audio input mode. </p> <br>
2051 	 * Audio from different source can be mixed with a video from HDMI or DP using this method.
2052 	 * @example 
2053 	 * function setDigitalAudioInputMode() {
2054 	 * 
2055 	 *    var options = {
2056 	 *      digitalAudioInputList:{
2057 	 *         'ext://hdmi:1' : Signage.DigitalAudioInput.HDMI_DP,
2058 	 *         'ext://hdmi:2' : Signage.DigitalAudioInput.HDMI_DP,
2059 	 *         'ext://dp:1' : Signage.DigitalAudioInput.AUDIO_IN
2060 	 *      }
2061 	 *    };
2062 	 * 
2063 	 *    var successCb = function (){
2064 	 *      console.log("Successfully Done");
2065 	 *    }; 
2066 	 * 
2067 	 *    var failureCb = function(cbObject){ 
2068 	 *      var errorCode = cbObject.errorCode; 
2069 	 *      var errorText = cbObject.errorText; 
2070 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2071 	 *    };
2072 	 * 
2073 	 *    var signage = new Signage();
2074 	 *    signage.setDigitalAudioInputMode (successCb, failureCb, options);
2075 	 * 
2076 	 * }
2077 	 * 
2078 	 * @class Signage
2079 	 * @param {Function} successCallback success callback function.
2080 	 * @param {Function} errorCallback failure callback function.
2081 	 * @param {Object} options  parameter list.
2082 	 * @param {Object} options.digitalAudioInputList List of digital audio input mode. 
2083 	 * In HDMI_DP mode, same audio from HDMI or DP is used. In AUDIO_IN mode, HDMI or DP video input can be used with external analog audio input.
2084 	 * @returns  
2085 	 * <p>
2086 	 * After the method is successfully executed, successCallback is called without any parameter.</br>
2087 	 * If an error occurs, errorCallback is called with errorCode and errorText.</p>
2088 	 * 
2089 	 * @since 1.0
2090 	 */
2091     Signage.prototype.setDigitalAudioInputMode = function (successCallback, errorCallback, options) {
2092 
2093         var errorMessage;
2094         function checkOptions(options) {
2095             if (options.digitalAudioInputList) {
2096                 for (var key in options.digitalAudioInputList) {
2097                     if (key) {
2098                         var value = options.digitalAudioInputList[key];
2099                         var found = false;
2100                         for (var type in Signage.DigitalAudioInput) {
2101                             if (value === Signage.DigitalAudioInput[type]) {
2102                                 found = true;
2103                             }
2104                         }
2105                         if (!found) {
2106                             errorMessage = "Invalid Audio Input  : " + value;
2107                             return false;
2108                         }
2109                     }
2110                 }
2111                 return true;
2112             } else {
2113                 errorMessage = "digitalAudioInputList  does not exist.";
2114                 return false;
2115             }
2116         }
2117 
2118 
2119 
2120         if (checkOptions(options)) {
2121             /*for(var input in options.digitalAudioInputList){
2122                 if(input === 'ext://hdmi:1'){
2123                     settings[SETTINGS_KEY.AUDIO_SOURCE_HDMI1] = options.digitalAudioInputList[input];
2124                 }
2125                 else if(input === 'ext://hdmi:2'){
2126                     settings[SETTINGS_KEY.AUDIO_SOURCE_HDMI2] = options.digitalAudioInputList[input];
2127                 }
2128                 else if(input === 'ext://dp:1'){
2129                     settings[SETTINGS_KEY.AUDIO_SOURCE_DP] = options.digitalAudioInputList[input];
2130                 }
2131             }*/
2132 
2133             service.Request("luna://com.webos.service.commercial.signage.storageservice/", {
2134                 method: "setDigitalAudioInputList",
2135                 parameters: {
2136                     digitalAudioInputList: options.digitalAudioInputList
2137                 },
2138                 onSuccess: function() {
2139                     if (typeof successCallback === 'function') {
2140                         successCallback();
2141                     }
2142                 },
2143                 onFailure: function(result) {
2144                     delete result.returnValue;
2145                     if (typeof errorCallback === 'function') {
2146                         errorCallback(result);
2147                     }
2148                 }
2149             });
2150         } else {
2151             var cbObj = {
2152                 errorCode: "BAD_PARAMETER",
2153                 errorText: errorMessage
2154             };
2155             errorCallback(cbObj);
2156         }
2157       
2158     };
2159 
2160 
2161     var _gDoBlock = false;
2162 	/**
2163 	 * <p>
2164 	 * Registers system monitoring setting. If one of the attributes is set to true, corresponding sensor events will be received.
2165 	 * When this method is called, all the previously registered monitoring event setup will be reset.
2166 	 * </p>
2167 	 * @example 
2168 	 * 
2169 	 * function registerSystemMonitor() {
2170 	 *    var eventHandler = function(event){
2171 	 *      console.log("Received Event from : " + event.source);
2172 	 *      console.log("Event Type is : " + event.type);
2173 	 *      console.log("Additional Info : " + JSON.stringify(event.data));
2174 	 *    };
2175 	 * 
2176 	 *    var options = { 
2177 	 *      monitorConfiguration: {
2178 	 *         fan: true,
2179 	 *         signal : true,
2180 	 *         lamp : true,
2181 	 *         screen : true,
2182 	 *      },
2183 	 *      eventHandler : eventHandler	
2184 	 *    };
2185 	 *  
2186 	 *    var successCb = function (){
2187 	 *      console.log("successfully Set");
2188 	 *    };
2189 	 * 
2190 	 *    var failureCb = function(cbObject){
2191 	 *      var errorCode = cbObject.errorCode;
2192 	 *      var errorText = cbObject.errorText;
2193 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2194 	 *    };
2195 	 * 
2196 	 *    var signage = new Signage();
2197 	 *    signage.registerSystemMonitor(successCb, failureCb, options);
2198 	 * 
2199 	 * }
2200 	 * 
2201 	 * @class Signage
2202 	 * @param {Function} successCallback success callback function.
2203 	 * @param {Function} errorCallback failure callback function.
2204 	 * @param {Object} options  parameter list.
2205 	 * @param {Object} options.monitorConfiguration  monitorConfiguration object for setting.
2206 	 * Only attributes that exist will be set.
2207 	 * <div align=left>
2208 	 * <table class="hcap_spec" width=400>
2209 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
2210 	 *   <tbody>
2211 	 *       <tr><th>fan</th><th>Boolean</th><th>Receive events from the sensor that monitors the fan </th><th>optional</th></tr>
2212 	 *       <tr class="odd"><th>signal</th><th>Boolean</th><th>Receive events from the signal receiver</th><th>optional</th></tr>
2213 	 *       <tr><th>lamp</th><th>Boolean</th><th>Receive events from the sensor that monitors the lamp</th><th>optional</th></tr>
2214 	 *       <tr class="odd"><th>screen</th><th>Boolean</th><th>Receive events from the sensor that monitors the screen</th><th>optional</th></tr>
2215 	 *       <tr><th>temperature</th><th>Boolean</th><th>Receive events from the sensor that monitors the audio</th><th>optional</th></tr>
2216 	 *   </tbody>
2217 	 * </table>
2218 	 * </div>
2219 	 * @param {Function} options.eventHandler The function for handling system monitor events.
2220 	 * This function has an event object as a parameter, which contains following properties.
2221 	 * <div align=left>
2222 	 * <table class="hcap_spec" width=400>
2223 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
2224 	 *   <tbody>
2225 	 *       <tr><th>source</th><th>Signage.MonitoringSource</th><th>The source of this event</th><th>required</th></tr>
2226 	 *       <tr class="odd"><th>type</th><th>Signage.EventType</th><th>Event Type</th><th>required</th></tr>
2227 	 *       <tr><th>data</th><th>Object</th><th>Additional Data. Format may vary for event type</th><th>optional</th></tr>
2228 	 *   </tbody>
2229 	 * </table>
2230 	 * </div>
2231 	 * @returns  
2232 	 * <p>
2233 	 * After the method is successfully executed, successCallback is called without any parameter.</br>
2234 	 * If an error occurs, errorCallback is called with errorCode and errorText.</p>
2235 	 * 
2236 	 * @since 1.0
2237 	 */
2238     Signage.prototype.registerSystemMonitor = function (successCallback, errorCallback, options) {
2239         var keys = ['fan', 'signal', 'lamp', 'screen', 'temperature'];
2240         var errorMessage;
2241         var errorCode = "BAD_PARAMETER";
2242 
2243         log("Listeners are: " + JSON.stringify(_gSystemMonitoringSetup, null, 3));
2244 
2245         function checkOptions(options) {
2246             if (_gDoBlock === true) {
2247                 errorMessage = "Not ready to register monitor now.";
2248                 errorCode = "SYSTEM_ERROR";
2249                 return false;
2250             }
2251 
2252             log("options are: " + JSON.stringify(options, null, 3));
2253 
2254             if (typeof options.eventHandler !== 'function') {
2255                 errorMessage = "No event handler was given or event hadnler is not a function";
2256                 return false;
2257             }
2258 
2259             if (options.monitorConfiguration) {
2260                 for (var key in options.monitorConfiguration) {
2261                     if (key) {
2262                         var found = false;
2263                         for (var i = 0; i < keys.length; ++i) {
2264                             if (key === keys[i]) {
2265                                 log("Found key: " + keys[i]);
2266                                 found = true;
2267                             }
2268                         }
2269 
2270                         if (!found) {
2271                             errorMessage = "Invalid Monitoring source  : " + key;
2272                             return false;
2273                         }
2274 
2275                         var value = options.monitorConfiguration[key];
2276                         log("value: " + value);
2277 
2278                         if (typeof value !== 'boolean') {
2279                             errorMessage = "Invalid value  : " + value;
2280                             return false;
2281                         }
2282                     }
2283                 }
2284                 return true;
2285             }
2286             else {
2287                 errorMessage = "monitorConfiguration  does not exist.";
2288                 return false;
2289             }
2290         }
2291 
2292         if (checkOptions(options)) {
2293 
2294             var cancelSuccess = function () {
2295                 log("Canceled all previous message subscriptions");
2296 
2297                 var handler = options.eventHandler;
2298                 for (var key in options.monitorConfiguration) {
2299                     if (key) {
2300                         var value = options.monitorConfiguration[key];
2301                         if (value === true) {
2302                             log("Add listener for : " + key);
2303                             addSignageEventListener(key, handler);
2304                         }
2305                     }
2306                 }
2307                 log("Monitoring Setup : " + JSON.stringify(_gSystemMonitoringSetup, null, 3));
2308                 
2309                 // Start Polling
2310                 log("Start Polling : ");
2311 
2312                 service.Request("luna://com.webos.service.commercial.signage.storageservice", {
2313                     method: "systemMonitor/startMonitor",
2314                     parameters: {},
2315                     onSuccess: function (result) {
2316                         log("On Success");
2317                         if (result.returnValue === true) {
2318                             if (typeof successCallback === 'function') {
2319                                 successCallback();
2320                             }
2321                         }
2322                         else {
2323                             if (typeof errorCallback === 'function') {
2324                                 errorCallback(result);
2325                             }
2326                         }
2327                         _gDoBlock = false;
2328                     },
2329                     onFailure: function (result) {
2330                         log("On Failure");
2331                         delete result.returnValue;
2332                         if (typeof errorCallback === 'function') {
2333                             errorCallback(result);
2334                         }
2335                         _gDoBlock = false;
2336                     }
2337                 });
2338             };
2339 
2340             var cancelError = function (result) {
2341                 errorCallback(result);
2342             };
2343 
2344             // Cancel all previous message subscriptions
2345             log("Cancel all previous message subscriptions");
2346             _gDoBlock = true;
2347             cancelAllSubscription(cancelSuccess, cancelError);
2348         }
2349         else {
2350             var cbObj = {
2351                 errorCode: errorCode,
2352                 errorText: errorMessage
2353             };
2354             errorCallback(cbObj);
2355         }
2356     };
2357 
2358 	/**
2359 	 * <p>
2360 	 * Unregisters all the system monitoring handlers. No more monitoring events will be received.
2361 	 * </p>
2362 	 * @example 
2363 	 * 
2364 	 * function unregisterSystemMonitor() {
2365 	 *    var successCb = function (){
2366 	 *      console.log("successfully canceled");
2367 	 *    };
2368 	 * 
2369 	 *    var failureCb = function(cbObject){
2370 	 *      var errorCode = cbObject.errorCode;
2371 	 *      var errorText = cbObject.errorText;
2372 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2373 	 *    };
2374 	 * 
2375 	 *    var signage = new Signage();
2376 	 *    signage.unregisterSystemMonitor(successCb, failureCb);
2377 	 * }
2378 	 * 
2379 	 * @class Signage
2380 	 * @param {Function} successCallback success callback function.
2381 	 * @param {Function} errorCallback failure callback function.
2382 	 * 
2383 	 * @returns  <p>After the method is successfully executed, successCallback is called without any parameter.</br>
2384 	 * If an error occurs, errorCallback is called with errorCode and errorText.</p>
2385 	 * 
2386 	 * @since 1.0
2387 	 */
2388 
2389     Signage.prototype.unregisterSystemMonitor = function (successCallback, errorCallback) {
2390         cancelAllSubscription(successCallback, errorCallback);
2391         log("After unregister, _gSystemMonitoringSetup are: " + JSON.stringify(_gSystemMonitoringSetup, null, 3));
2392     };
2393 
2394     function cancelAllSubscription(successCallback, errorCallback) {
2395         log("cancelAllSubscription> setup are: " + JSON.stringify(_gSystemMonitoringSetup, null, 3));
2396 
2397         for (var key in _gSystemMonitoringSetup) {
2398             if (key) {
2399                 removeSignageEventListener(key);
2400             }
2401         }
2402 
2403 		/*
2404 		if(_gSystemMonitoringSetup.fan === true){
2405 			log("Remove monitor_fan");
2406 			removeEventListener('monitor_fan');
2407 			_gSystemMonitoringSetup.fan = false;
2408 		}
2409 
2410 		if(_gSystemMonitoringSetup.screen === true){
2411 			log("Remove monitor_screen");
2412 			removeEventListener('monitor_screen');
2413 			_gSystemMonitoringSetup.screen = false;
2414 		}
2415 
2416 		if(_gSystemMonitoringSetup.temperature === true){
2417 			log("Remove monitor_temperature");
2418 			removeEventListener('monitor_temperature');
2419 			_gSystemMonitoringSetup.temperature = false;
2420 		}
2421 
2422 		if(_gSystemMonitoringSetup.signal === true){
2423 			log("Remove monitor_signal");
2424 			removeEventListener('monitor_signal');
2425 			_gSystemMonitoringSetup.signal = false;
2426 		}
2427 		if(_gSystemMonitoringSetup.lamp === true){
2428 			log("Remove monitor_lamp");
2429 			removeEventListener('monitor_lamp');
2430 			_gSystemMonitoringSetup.lamp = false;
2431 		}
2432 		 */
2433         log("Stop Polling");
2434 
2435         service.Request("luna://com.webos.service.commercial.signage.storageservice", {
2436             method: "systemMonitor/stopMonitor",
2437             parameters: {},
2438             onSuccess: function (result) {
2439                 log("On Success");
2440                 if (result.returnValue === true) {
2441                     if (typeof successCallback === 'function') {
2442                         successCallback();
2443                     }
2444                 }
2445                 else {
2446                     if (typeof errorCallback === 'function') {
2447                         errorCallback(result);
2448                     }
2449                 }
2450             },
2451             onFailure: function (result) {
2452                 log("On Failure");
2453                 delete result.returnValue;
2454                 if (typeof errorCallback === 'function') {
2455                     errorCallback(result);
2456                 }
2457             }
2458         });
2459     }
2460 
2461 
2462 	/**
2463 	 * <p>Gets system monitoring setting. If one of the attributes is set to true, corresponding sensor events will be sent.
2464 	 * Use onSignageMonitoringEvent to register handler for those events.
2465 	 * </p>
2466 	 * @example 
2467 	 * function getSystemMonitoringInfo() {
2468 	 *    var successCb = function (cbObject){
2469 	 *      var fan =  cbObject.fan;
2470 	 *      var signal =  cbObject.signal;
2471 	 *      var lamp =  cbObject.lamp;
2472 	 *      var screen =  cbObject.screen;
2473 	 *      var temperature =  cbObject.temperature;	 
2474 	 * 
2475 	 *      console.log("Monitor Fan: " + fan);
2476 	 *      console.log("Monitor signal: " + signal);
2477 	 *      console.log("Monitor lamp: " + lamp);
2478 	 *      console.log("Monitor screen: " + screen);
2479 	 *      console.log("Monitor temperature: " + temperature);	 
2480 	 *    };
2481 	 * 
2482 	 *    var failureCb = function(cbObject){
2483 	 *      var errorCode = cbObject.errorCode;
2484 	 *      var errorText = cbObject.errorText;
2485 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2486 	 *    };
2487 	 * 
2488 	 *    var signage = new Signage();
2489 	 *    signage.getSystemMonitoringInfo(successCb, failureCb);
2490 	 * }
2491 	 * 
2492 	 * @class Signage
2493 	 * @param {Function} successCallback success callback function.
2494 	 * @param {Function} errorCallback failure callback function.
2495 	 * @returns  <p>After the method is successfully executed, successCallback is called with monitorConfiguration object with following data</p>
2496 	 * <div align=left>
2497 	 * <table class="hcap_spec" width=400>
2498 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
2499 	 *   <tbody>
2500 	 *       <tr><th>fan</th><th>Boolean</th><th>Receive events from the sensor that monitors the fan </th></tr>
2501 	 *       <tr class="odd"><th>signal</th><th>Boolean</th><th>Receive events from the signal receiver</th></tr>
2502 	 *       <tr><th>lamp</th><th>Boolean</th><th>Receive events from the sensor that monitors the lamp</th></tr>
2503 	 *       <tr class="odd"><th>screen</th><th>Boolean</th><th>Receive events from the sensor that monitors the screen</th></tr>
2504 	 *       <tr><th>temperature</th><th>Boolean</th><th>Receive events from the sensor that monitors the temperature</th></tr>
2505 	 *   </tbody>
2506 	 * </table>
2507 	 * </div>
2508 	 * <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
2509 	 *
2510 	 * @since 1.0 
2511 	 * */
2512 
2513     Signage.prototype.getSystemMonitoringInfo = function (successCallback, errorCallback) {
2514         if (_gSystemMonitoringSetup) {
2515             successCallback({
2516                 fan: _gSystemMonitoringSetup.fan.getEvent,
2517                 signal: _gSystemMonitoringSetup.signal.getEvent,
2518                 lamp: _gSystemMonitoringSetup.lamp.getEvent,
2519                 screen: _gSystemMonitoringSetup.screen.getEvent,
2520                 temperature: _gSystemMonitoringSetup.temperature.getEvent
2521             });
2522         }
2523         else {
2524             var cbObj = {
2525                 errorCode: "ERROR",
2526                 errorText: "Failed to get system monitoring setup"
2527             };
2528             errorCallback(cbObj);
2529         }
2530     };
2531 
2532 	/**
2533 	 * <p>Sets power saving mode.</p>
2534 	 * @example 
2535 	 * function setPowerSaveMode() {
2536 	 *    var options = { 
2537 	 *      powerSaveMode: {
2538 	 *         ses: true,
2539 	 *         dpmMode: Signage.DpmMode.OFF,
2540 	 *         automaticStandby: Signage.AutomaticStandbyMode.OFF,
2541 	 *         do15MinOff: true,
2542 	 *      }
2543 	 *   }; 
2544 	 *
2545 	 *    var successCb = function (){
2546 	 *      console.log("successfully Set");
2547 	 *    };
2548 	 * 
2549 	 *    var failureCb = function(cbObject){
2550 	 *      var errorCode = cbObject.errorCode;
2551 	 *      var errorText = cbObject.errorText;
2552 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2553 	 *    };
2554 	 * 
2555 	 *    var signage = new Signage();
2556 	 *    signage.setPowerSaveMode(successCb, failureCb, options);
2557 	 * }
2558 	 * 
2559 	 * @class Signage
2560 	 * @param {Function} successCallback success callback function.
2561 	 * @param {Function} errorCallback failure callback function.
2562 	 * @param {Object} options  parameter list.
2563 	 * @param {Object} options.powerSaveMode  powerSaveMode object.
2564 	 * Only attributes that exist will be set.
2565 	 * 'automaticStandby' mode is triggered when there are no RCU or local key input for 4 hours.
2566 	 * '15MinOff' mode is triggered when there is no video input for 15 minutes.
2567 	 * 
2568 	 * <div align=left>
2569 	 * <table class="hcap_spec" width=400>
2570 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
2571 	 *   <tbody>
2572 	 *       <tr><th>ses</th><th>Boolean</th><th>Smart Energy Saving mode.</br>This will deduce monitor power usage by manipulating the power usage on the screen backlight etc. </th><th>optional</th></tr>
2573 	 *       <tr class="odd"><th>dpmMode</th><th>Signage.DpmMode</th><th>Display Power Management mode.</br>Sets the monitor power off time while there is no signal/no user inputs/no application on the monitor</th><th>optional</th></tr>
2574 	 *       <tr><th>automaticStandby</th><th>Signage.AutomaticStandbyMode</th><th>Automatic standby mode.</br>Sets the monitor power off time while there is no user inputs on the monitor</th><th>optional</th></tr>
2575 	 *       <tr class="odd"><th>do15MinOff</th><th>Boolean</th><th>15 Minutes off mode.</br>Sets the monitor power off time while there is no signal/no user inputs on the monitor</th><th>optional</th></tr>
2576 	 *   </tbody>
2577 	 * </table>
2578 	 * </div>
2579 	 * 
2580 	 * @returns  
2581 	 * <p>
2582 	 * After the method is successfully executed, successCallback is called without any parameter.</br>
2583 	 * If an error occurs, errorCallback is called with errorCode and errorText.</p>
2584 	 * 
2585 	 * @since 1.0
2586 	 */
2587 
2588     Signage.prototype.setPowerSaveMode = function (successCallback, errorCallback, options) {        
2589         var errorMessage;
2590         function checkOptions(options) {
2591             if (options.powerSaveMode) {
2592                 for (var key in options.powerSaveMode) {
2593                     if (key) {
2594                         var value = options.powerSaveMode[key];
2595                         if (key === 'ses' || key === 'do15MinOff') {
2596                             if (typeof value !== 'boolean') {
2597                                 errorMessage = "Invalid value  : " + value;
2598                                 return false;
2599                             }
2600                         }
2601 
2602                         else if (key === 'automaticStandby') {
2603                             if (!isValidEnum(Signage.AutomaticStandbyMode, value)) {
2604                                 errorMessage = "Invalid automaticStandby value  : " + value;
2605                                 return false;
2606                             }
2607                         }
2608 
2609                         else if (key === 'dpmMode') {
2610                             if (!isValidEnum(Signage.DpmMode, value)) {
2611                                 errorMessage = "Invalid dpmMode value  : " + value;
2612                                 return false;
2613                             }
2614                         }
2615                         else {
2616                             errorMessage = "Unknown value  : " + key;
2617                             return false;
2618                         }
2619                     }
2620                 }
2621 
2622                 return true;
2623             }
2624             else {
2625                 errorMessage = "powerSaveMode  does not exist.";
2626                 return false;
2627             }
2628         }
2629 
2630         if (checkOptions(options)) {
2631             log(options.powerSaveMode);
2632             service.Request("luna://com.webos.service.commercial.signage.storageservice", {
2633                 method: "setPowerSaveMode",
2634                 parameters: {
2635                     mode: options.powerSaveMode
2636                 },
2637                 onSuccess: function (result) {
2638                     log("onSuccess");
2639                     if (result.returnValue) {
2640                         successCallback(result.mode);
2641                     }
2642                     else {
2643                         log("FAILED: " + result.errorText);
2644                         errorCallback({
2645                             errorCode: result.errorCode,
2646                             errorText: result.errorText 
2647                         });
2648                     }
2649                 },
2650                 onFailure: function (result) {
2651                     log("onFailure");
2652                     log("FAILED: " + result.errorText);
2653                     errorCallback({
2654                         errorCode: result.errorCode,
2655                         errorText: result.errorText 
2656                     });
2657                 }
2658             });
2659 
2660         }
2661         else {
2662             var cbObj = {
2663                 errorCode: "BAD_PARAMETER",
2664                 errorText: errorMessage
2665             };
2666             errorCallback(cbObj);
2667         }
2668     };
2669 
2670 	/**
2671 	 * <p>Gets power saving mode.</p>
2672 	 * @example 
2673 	 * 
2674 	 * function getPowerSaveMode() {
2675 	 *    var successCb = function (cbObject){
2676 	 *      var ses = cbObject.ses;
2677 	 *      var dpmMode = cbObject.dpmMode;
2678 	 *      var automaticStandby = cbObject.automaticStandby;
2679 	 *      var do15MinOff = cbObject.do15MinOff;
2680 	 * 
2681 	 *      console.log("Smart Energy Saving: " + ses);
2682 	 *      console.log("Display Power Management: " + dpmMode);
2683 	 *      console.log("Automatic Standby Mode: " + automaticStandby);
2684 	 *      console.log("15 Minutes Off: " + do15MinOff);
2685 	 *    };
2686 	 * 
2687 	 *    var failureCb = function(cbObject){
2688 	 *      var errorCode = cbObject.errorCode;
2689 	 *      var errorText = cbObject.errorText;
2690 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2691 	 *    };
2692 	 * 
2693 	 * var signage = new Signage();
2694 	 * signage.getPowerSaveMode(successCb, failureCb);
2695 	 * 
2696 	 * }
2697 	 * 
2698 	 * @class Signage
2699 	 * @param {Function} successCallback success callback function.
2700 	 * @param {Function} errorCallback failure callback function.
2701 	 * @returns  <p>After the method is successfully executed, successCallback is called with the following data.</p>
2702 	 * <div align=left>
2703 	 * <table class="hcap_spec" width=400>
2704 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
2705 	 *   <tbody>
2706 	 *       <tr><th>ses</th><th>Boolean</th><th>Smart Energy Saving mode.<br> This will deduce monitor power usage by manipulating the power usage on the screen backlight etc. </th></tr>
2707 	 *       <tr class="odd"><th>dpmMode</th><th>Signage.DpmMode</th><th>Display Power Management mode.<br>Sets the monitor power off time while there is no signal/no user inputs/no application on the monitor</th></tr>
2708 	 *       <tr><th>automaticStandby</th><th>Signage.AutomaticStandbyMode</th><th>Automatic standby mode.<br>Sets the monitor power off time while there is no user inputs on the monitor</th></tr>
2709 	 *       <tr class="odd"><th>do15MinOff</th><th>Boolean</th><th>15 Minutes off mode.<br>Sets the monitor power off time while there is no signal/no user inputs on the monitor</th></tr>
2710 	 *   </tbody>
2711 	 * </table>
2712 	 * </div>
2713 	 * <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
2714 	 * 
2715 	 * @since 1.0
2716 	 */
2717     Signage.prototype.getPowerSaveMode = function (successCallback, errorCallback) {
2718 
2719         service.Request("luna://com.webos.service.commercial.signage.storageservice", {
2720             method: "getPowerSaveMode",
2721             parameters: {},
2722             onSuccess: function (result) {
2723                 log("onSuccess");
2724                 if (result.returnValue) {
2725                     successCallback(result.mode);
2726                 }
2727                 else {
2728                     log("FAILED: " + result.errorText);
2729                     errorCallback({
2730                         errorCode: result.errorCode,
2731                         errorText: result.errorText
2732                     });
2733                 }
2734             },
2735             onFailure: function (result) {
2736                 log("onFailure");
2737                 log("FAILED: " + result.errorText);
2738                 errorCallback({
2739                     errorCode: result.errorCode,
2740                     errorText: result.errorText
2741                 });
2742             }
2743         });
2744 
2745     };
2746 
2747 	/**
2748 	 * <p>Sets usage policy. It is used to limit monitor functions.</p>
2749 	 * @example 
2750 	 * 
2751 	 * function setUsagePermission() {
2752 	 *    var options = { 
2753 	 *      policy: {
2754 	 *         remoteKeyOperationMode: Signage.KeyOperationMode.POWER_ONLY,
2755 	 *         localKeyOperationMode: Signage.KeyOperationMode.POWER_ONLY,
2756 	 *      }
2757 	 *   };
2758 	 * 
2759 	 *    var successCb = function (){
2760 	 *      console.log("successfully Set");
2761 	 *    };
2762 	 * 
2763 	 *    var failureCb = function(cbObject){
2764 	 *      var errorCode = cbObject.errorCode;
2765 	 *      var errorText = cbObject.errorText;
2766 	 *         console.log( " Error Code [" + errorCode + "]: " + errorText); 
2767 	 *       };
2768 	 * 
2769 	 *    var signage = new Signage();
2770 	 *    signage.setUsagePermission(successCb, failureCb, options);
2771 	 *    
2772 	 * }
2773 	 * 
2774 	 * @class Signage
2775 	 * @param {Function} successCallback success callback function.
2776 	 * @param {Function} errorCallback failure callback function.
2777 	 * @param {Object} options  parameter list.
2778 	 * @param {Object} options.policy  Policy object.
2779 	 * 
2780 	 * Only attributes that exist will be set.
2781 	 * 
2782 	 * <div align=left>
2783 	 * <table class="hcap_spec" width=400>
2784 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
2785 	 *   <tbody>
2786 	 *       <tr><th>remoteKeyOperationMode</th><th>KeyOperationMode</th><th>Remote Key operation mode </th><th>optional</th></tr>
2787 	 *       <tr class="odd"><th>localKeyOperationMode</th><th>KeyOperationMode</th><th>Built-in key operation mode</th><th>optional</th></tr>
2788 	 *   </tbody>
2789 	 * </table>
2790 	 * </div>
2791 	 * 
2792 	 * @returns  <p>After the method is successfully executed, successCallback is called without any parameter.</br>
2793 	 * If an error occurs, errorCallback is called with errorCode and errorText.</p>
2794 	 * 
2795 	 * @since 1.0
2796 	 */
2797     Signage.prototype.setUsagePermission = function (successCallback, errorCallback, options) {
2798         var settings = {};
2799         var errorMessage;
2800 
2801         function checkOptions(options) {            
2802             if (options.policy) {
2803                 for (var key in options.policy) {
2804                     if (key) {
2805                         var value = options.policy[key];
2806                         if (key === 'remoteKeyOperationMode' || key === 'localKeyOperationMode') {
2807                             if (!isValidEnum(Signage.KeyOperationMode, value)) {
2808                                 errorMessage = "Invalid  KeyOperationMode value  : " + value;
2809                                 return false;
2810                             }
2811                         }
2812                         else {
2813                             errorMessage = "Unknown value  : " + key;
2814                             return false;
2815                         }
2816                     }
2817 
2818                 }
2819                 return true;
2820             }
2821             else {
2822                 errorMessage = "policy  does not exist.";
2823                 return false;
2824             }
2825         }
2826 
2827         if (checkOptions(options)) {
2828             if (options.policy.localKeyOperationMode) {
2829                 var localKeyOperationMode = options.policy.localKeyOperationMode;
2830                 log("portraitMode: " + localKeyOperationMode);
2831                 settings[SETTINGS_KEY.LOCALKEY_OPERATION_MODE] = localKeyOperationMode;
2832             }
2833 
2834             if (options.policy.remoteKeyOperationMode) {
2835                 var remoteKeyOperationMode = options.policy.remoteKeyOperationMode;
2836                 log("portraitMode: " + remoteKeyOperationMode);
2837                 settings[SETTINGS_KEY.IR_OPERATION_MODE] = remoteKeyOperationMode;
2838             }
2839 
2840             log("Set: " + JSON.stringify(settings, null, 3));
2841 
2842             setSystemSettings("hotelMode", settings, successCallback, errorCallback);
2843 
2844             log("setPolicy Done");
2845         }
2846         else {
2847             var cbObj = {
2848                 errorCode: "BAD_PARAMETER",
2849                 errorText: errorMessage
2850             };
2851             errorCallback(cbObj);
2852         }
2853 
2854     };
2855 
2856 	/**
2857 	 * <p>Gets usage policy. </p>
2858 	 * @example 
2859 	 * 
2860 	 * function getUsagePermission() {
2861 	 *    var successCb = function (cbObject){
2862 	 *      var remoteKeyOperationMode = cbObject.remoteKeyOperationMode;
2863 	 *      var localKeyOperationMode = cbObject.localKeyOperationMode;
2864 	 *      console.log("remoteKeyOperationMode: " + remoteKeyOperationMode);
2865 	 *      console.log("localKeyOperationMode: " + localKeyOperationMode);
2866 	 *    };
2867 	 * 
2868 	 *    var failureCb = function(cbObject){
2869 	 *      var errorCode = cbObject.errorCode;
2870 	 *      var errorText = cbObject.errorText;
2871 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2872 	 *    };
2873 	 * 
2874 	 *    var signage = new Signage();
2875 	 *    signage.getUsagePermission(successCb, failureCb);
2876 	 * }
2877 	 * 
2878 	 * @class Signage
2879 	 * @param {Function} successCallback success callback function.
2880 	 * @param {Function} errorCallback failure callback function.
2881 	 * @returns  <p>After the method is successfully executed, successCallback is called with the following data.</p>
2882 	 * 
2883 	 * <div align=left>
2884 	 * <table class="hcap_spec" width=400>
2885 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
2886 	 *   <tbody>
2887 	 *       <tr><th>remoteKeyOperationMode</th><th>KeyOperationMode</th><th>Remote Key operation mode </th></tr>
2888 	 *       <tr class="odd"><th>localKeyOperationMode</th><th>KeyOperationMode</th><th>Built-in key operation mode</th></tr>
2889 	 *   </tbody>
2890 	 * </table>
2891 	 * </div>
2892 	 * 
2893 	 * <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
2894 	 * 
2895 	 * @since 1.0
2896 	 */
2897     Signage.prototype.getUsagePermission = function (successCallback, errorCallback) {
2898         var cbgetter = function (settings) {
2899             log('settings: ' + JSON.stringify(settings, null, 3));
2900             
2901             var cbObj = {};
2902             cbObj.remoteKeyOperationMode = settings[SETTINGS_KEY.IR_OPERATION_MODE];
2903             cbObj.localKeyOperationMode = settings[SETTINGS_KEY.LOCALKEY_OPERATION_MODE];
2904             
2905             log('cbObj: ' + JSON.stringify(cbObj, null, 3));
2906             return cbObj;
2907         };
2908 
2909         var keys = [SETTINGS_KEY.IR_OPERATION_MODE, SETTINGS_KEY.LOCALKEY_OPERATION_MODE];
2910         getSystemSettings("hotelMode", keys, cbgetter, successCallback, errorCallback);
2911     };
2912 
2913 	/**
2914 	 * <p>Gets current usage data information.</p>
2915 	 *
2916 	 * @example 
2917 	 * 
2918 	 * function getUsageData() {
2919 	 *    var successCb = function (cbObject){
2920 	 *      var uptime= cbObject.uptime;
2921 	 *      var totalUsed= cbObject.totalUsed;
2922 	 *      console.log("Uptime: " + uptime);
2923 	 *      console.log("Total Used: " + totalUsed);
2924 	 *    };
2925 	 *  
2926 	 *    var failureCb = function(cbObject){ 
2927 	 *      var errorCode = cbObject.errorCode; 
2928 	 *      var errorText = cbObject.errorText; 
2929 	 *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
2930 	 *    };
2931 	 * 
2932 	 *    var signage = new Signage();
2933 	 *    signage.getUsageData(successCb, failureCb);
2934 	 * }
2935 	 * @class Signage
2936 	 * @param {Function} successCallback success callback function.
2937 	 * @param {Function} errorCallback failure callback function.
2938 	 * 
2939 	 * @returns  <p>After the method is successfully executed, successCallback is called with the following data.</p>
2940 	 * 
2941 	 * <div align=left>
2942 	 * <table class="hcap_spec" width=400>
2943 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
2944 	 *   <tbody>
2945 	 *       <tr><th>uptime</th><th>Number</th><th>Uptime. (Hours after last power on. Showing upto the nearest hundredths. Ex) 1.5 = 1 hour 30 minutes, etc)</th></tr>
2946 	 *       <tr class="odd"><th>totalUsed</th><th>Number</th><th>Total Used. (Total usage hours)</th></tr>
2947 	 *   </tbody>
2948 	 * </table>
2949 	 * </div>
2950 	 * 
2951 	 * <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
2952 	 * 
2953 	 * @since 1.0
2954 	 */
2955     Signage.prototype.getUsageData = function (successCallback, errorCallback) {
2956 
2957 
2958         //var powerHistoryKey = "powerOnOffHistory";
2959 
2960         var gotTT = false;
2961         var gotUT = false;
2962 
2963         var cbObject = {
2964             uptime: false,
2965             totalUsed: false
2966         };
2967 
2968         function accessResult() {
2969             log("accessResult");
2970 
2971             if (gotTT === true && gotUT === true) {
2972                 log("CB Object: " + JSON.stringify(cbObject, null, 3));
2973                 if (cbObject.uptime === false || cbObject.totalUsed === false) {
2974                     errorCallback({
2975                         errorCode: "CORDOVA_FAIL",
2976                         errorText: "Failed to get usage data"
2977                     });
2978                     return;
2979                 }
2980                 else {
2981                     log("SUCCESS");
2982                     successCallback(cbObject);
2983                     return;
2984                 }
2985             }
2986             else {
2987                 log("Not Yet");
2988             }
2989         }
2990 
2991         service.Request("luna://com.webos.service.tv.signage/", {
2992             method: "getUTT",
2993             parameters: {},
2994             onSuccess: function (result) {
2995                 log("On getUTT Success");
2996                 gotTT = true;
2997                 if (result.returnValue === true) {
2998                     log("UTT is :" + result.UTT);
2999                     cbObject.totalUsed = result.UTT;
3000                 }
3001                 accessResult();
3002             },
3003             onFailure: function (result) {
3004                 log("On getUTT Failure :" + JSON.stringify(result, null, 3));
3005                 gotTT = true;
3006                 accessResult();
3007             }
3008         });
3009 
3010         service.Request("luna://com.webos.service.tv.signage/", {
3011             method: "dsmp/getElapsedTime",
3012             parameters: {},
3013             onSuccess: function (result) {
3014                 log("On getElapsedTime Success");
3015                 gotUT = true;
3016                 log("result: " + JSON.stringify(result, null, 3));
3017 
3018                 if (result.returnValue === true) {
3019                     var elapsedTime = result.elapsedTime;
3020                     cbObject.uptime = elapsedTime;                    
3021                     log("Elapsed!!: " + elapsedTime);
3022                 }
3023                 accessResult();
3024             },
3025             onFailure: function (result) {
3026                 log("On getSystemSettings Failure " + JSON.stringify(result, null, 3));
3027                 gotUT = true;
3028                 accessResult();
3029             }
3030         });
3031     };
3032 
3033 	/**
3034 	 * <p>Gets screen capture image. Captured screen image will be returned as JPEG image encoded in base64 string. </p>
3035 	 * 
3036 	 * @example 
3037 	 * function doCapture(){
3038 	 *   var signage = new Signage();
3039 	 *   
3040 	 *   var successCB = function(cbobj){
3041 	 *      var data = cbobj.data;
3042 	 *      var size = cbobj.size;
3043 	 *      var encoding = cbobj.encoding;		
3044 	 *      console.log("Got Data size:" + size);	
3045 	 *      console.log("Got Data encoding :" + encoding);				
3046 	 *      console.log("Got Data :" + data);		
3047 	 *	
3048 	 *      var capturedElement = document.getElementById('captured_img');
3049 	 *      capturedElement.src = 'data:image/jpeg;base64,' + data;
3050 	 *   };
3051 	 *		
3052 	 *   var failureCB = function(cbobj){
3053 	 *      console.log(JSON.stringify(cbobj, null, 3));
3054 	 *   }
3055 	 *
3056 	 *   var options = { 
3057 	 *      save : true
3058 	 *   };   
3059 	 *    
3060 	 *   signage.captureScreen(successCB, failureCB, options);
3061 	 * }
3062 	 *
3063 	 * 
3064 	 * @class Signage
3065 	 * @param {Function} successCallback success callback function.
3066 	 * @param {Function} errorCallback failure callback function.
3067 	 * @param {Object} options
3068 	 * <div align=left>
3069 	 * <table class="hcap_spec" width=400>
3070 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
3071 	 *   <tbody>
3072 	 *       <tr><th>save</th><th>Boolean</th><th>true : saves the captured image file(0_captured_by_scap.jpg) on local storage (content folder and media folder for fail-over mode) <br>and it will be displayed when the fail-over mode is activated, overwriting existing image file which is captured before. false : not save. default value </a></th><th>optional</th></tr>
3073 	 *       <tr class="odd"><th>thumbnail</th><th>Boolean</th><th>true : reduced size version of picutre (128 X 72). <br>false : options.imgResolution size. default value </th><th>optional</th></tr>
3074 	 *       <tr><th>imgResolution</th><th>String</th><th><a href="Signage.ImgResolution.html#constructor">Signage.ImgResolution</a></th><th>optional</th></tr>
3075      *   </tbody>
3076 	 * </table>
3077 	 * </div>
3078 	 * 
3079 	 * @returns  <p>After the method is successfully executed, successCallback is called with the following data.</p>
3080 	 * 
3081 	 * <div align=left>
3082 	 * <table class="hcap_spec" width=400>
3083 	 *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
3084 	 *   <tbody>
3085 	 *       <tr><th>cbObject.data</th><th>String</th>
3086 	 *       <th>
3087 	 *       <p>JPEG screen shot image which is encoded in base64 string. </p>
3088 	 *       </th></tr>
3089 	 *       <tr><th>cbObject.size</th><th>number</th>
3090 	 *       <th>
3091 	 *       <p>size of the data. </p>
3092 	 *       </th></tr>
3093 	 *       <tr><th>cbObject.encoding</th><th>string</th>
3094 	 *       <th>
3095 	 *       <p>encoding used for the data (base64) </p>
3096 	 *       </th></tr>
3097 	 *   </tbody>
3098 	 * </table>
3099 	 * </div>
3100 	 * 
3101 	 * <p>If an error occurs, errorCallback is called with errorCode and errorText.</p>
3102 	 * 
3103 	 * @since 1.0 
3104 	 * @since 1.1 options.save options.thumbnail added
3105 	 * @since 1.2 options.save, saves image also under application's content folder
3106      * @since 1.4.1 options.imgResolution added
3107 	 * 
3108 	 */
3109     Signage.prototype.captureScreen = function (successCallback, errorCallback, options) {
3110         
3111         var param = {
3112             save: (options === undefined || options === null || options.save === undefined ? false : options.save)
3113         };
3114 
3115         if (options !== undefined && options !== null &&
3116             options.thumbnail !== undefined && options.thumbnail === true) {
3117             param.width = 128;
3118             param.height = 72;
3119         }        
3120         else if (options.imgResolution === Signage.ImgResolution.FHD) {
3121             param.width = 1920;
3122             param.height = 1080;
3123         }
3124         else //default is HD
3125         {
3126             param.width = 1280;
3127             param.height = 720;
3128         }        
3129 
3130         service.Request("luna://com.webos.service.commercial.signage.storageservice", {
3131             method: "captureScreen",
3132             parameters: param,
3133             onSuccess: function (result) {
3134                 log("On Success");
3135                 if (result.returnValue === true) {
3136                     successCallback({
3137                         data: result.data,
3138                         size: result.size,
3139                         encoding: result.encoding
3140                     });
3141                 }
3142                 else {
3143                     errorCallback({
3144                         errorCode: result.errorCode,
3145                         errorText: result.errorText 
3146                     });
3147                 }
3148             },
3149             onFailure: function (result) {
3150                 log("On Failure");
3151                 errorCallback({
3152                     errorCode: result.errorCode,
3153                     errorText: result.errorText
3154                 });
3155             }
3156         });
3157     };
3158 
3159 	/**
3160      * set IntelligentAuto enabled/disabled
3161      * @class Signage
3162      * @param {Function} successCallback success callback function.
3163      * @param {Function} errorCallback failure callback function.     
3164      * @param {Object} options
3165      * <div align=left>
3166      * <table class="hcap_spec" width=400>
3167      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
3168      *   <tbody>
3169      *       <tr><th>enabled</th><th>Boolean</th><th>Intelligent auto is enabled. true: enabled, false: disabled</th><th>required</th></tr>
3170      *   </tbody>
3171      * </table>
3172      * </div>
3173      * @return <p>If the method is successfully executed, call the success callback function without a parameter.</br>
3174      * If an error occurs, failure callback function is called with failure callback object as a parameter.</p>
3175      * @example
3176      * // Javascript code     
3177      * function setIntelligentAuto () {
3178      *   var options = {
3179      *      enabled : true
3180      *   };   
3181      *     
3182      *   function successCb() {
3183      *      // Do something
3184      *   }
3185      *
3186      *   function failureCb(cbObject) {
3187      *      var errorCode = cbObject.errorCode;
3188      *      var errorText = cbObject.errorText;
3189      *      console.log ("Error Code [" + errorCode + "]: " + errorText);
3190      *   }
3191      *
3192      *   var signage = new Signage();
3193      *   signage.setIntelligentAuto(successCb, failureCb, options);
3194      * }
3195      * @since 1.4
3196      * @see
3197      * <a href="Signage%23getIntelligentAuto.html">Signage.getIntelligentAuto()</a><br>
3198      */
3199     Signage.prototype.setIntelligentAuto = function (successCallback, errorCallback, options) {
3200         log("setIntelligentAuto: " + options.enabled);
3201         
3202         if (options.enabled === null && typeof errorCallback === 'function') {
3203             var result = {};
3204             checkErrorCodeNText(result, "SSIA", "Signage.setIntelligentAuto returns failure. command was not defined.");
3205             errorCallback(result);
3206             log("Signage.setIntelligentAuto invalid ");
3207             return;
3208         }      
3209         
3210         service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
3211             method : "set",
3212             parameters : {
3213                 category : "commercial",
3214                 settings : {
3215                     "intelligentAuto" : (options.enabled === true ) ? "on" : "off"
3216                 }
3217             },
3218             onSuccess : function(result) {
3219                 log("setIntelligentAuto: On Success");
3220 
3221                 if (result.returnValue === true) {
3222                     if(typeof successCallback === 'function') {
3223                         successCallback();
3224                     }
3225                 }
3226             },
3227             onFailure : function(result) {
3228                 log("setIntelligentAuto: On Failure");
3229                 delete result.returnValue;
3230                 if (typeof errorCallback === 'function') {
3231                     checkErrorCodeNText(result, "SSIA", "Signage.setIntelligentAuto returns failure.");
3232                     errorCallback(result);
3233                 }
3234             }
3235         });
3236         
3237         log("Signage.setIntelligentAuto Done");
3238     };
3239 
3240 		/**
3241      * Gets IntelligentAuto enabled
3242      * @class Signage
3243      * @param {Function} successCallback success callback function.
3244      * @param {Function} errorCallback failure callback function.
3245      * @return {Object} 
3246      * <div align=left>
3247      * <table class="hcap_spec" width=400>
3248      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
3249      *   <tbody>
3250      *       <tr><th>enabled</th><th>Boolean</th><th>Intelligent auto is enabled. true: enabled, false: disabled</th></tr>
3251      *   </tbody>
3252      * </table>
3253      * </div>
3254      *
3255      * @example
3256      * // Javascript code
3257      * function getIntelligentAuto () {
3258      *   function successCb(cbObject) {
3259      *      console.log("cbObject : " + JSON.stringify(cbObject));
3260      *
3261      *      console.log("enabled : " + cbObject.enabled);     
3262      *
3263      *      // Do something
3264      *         ...
3265      *   }
3266      *
3267      *   function failureCb(cbObject) {
3268      *      var errorCode = cbObject.errorCode;
3269      *      var errorText = cbObject.errorText;
3270      *      console.log ("Error Code [" + errorCode + "]: " + errorText);
3271      *   }
3272      *
3273      *   var signage = new Signage();
3274      *   signage.getIntelligentAuto(successCb, failureCb);
3275      * }
3276      * @since 1.4
3277      * @see
3278      * <a href="Signage%23setIntelligentAuto.html">Signage.setIntelligentAuto()</a><br>  
3279      */
3280     Signage.prototype.getIntelligentAuto = function (successCallback, errorCallback) {
3281         
3282         log("getIntelligentAuto: ");
3283         
3284             service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
3285                 method : "get",
3286                 parameters : {
3287                     category : "commercial",
3288                     keys : ["intelligentAuto"]
3289                 },
3290                 onSuccess : function(result) {
3291                     log("getIntelligentAuto: On Success");
3292                     
3293                     if (result.returnValue === true) {
3294                         var cbObj = {};
3295                         cbObj.enabled = result.settings.intelligentAuto;
3296                     
3297                         if (typeof successCallback === 'function') {
3298                             successCallback(cbObj);
3299                         }
3300                     }
3301                 },
3302                 onFailure : function(result) {
3303                     log("getIntelligentAuto: On Failure");
3304                     delete result.returnValue;
3305                     if (typeof errorCallback === 'function') {
3306                         checkErrorCodeNText(result, "SGIA", "Signage.getIntelligentAuto returns failure.");
3307                         errorCallback(result);
3308                     }
3309                 }
3310             });
3311         
3312         log("Signage.getIntelligentAuto Done");
3313     };
3314 
3315 		/**
3316      * set StudioMode enabled/disabled
3317      * @class Signage
3318      * @param {Function} successCallback success callback function.
3319      * @param {Function} errorCallback failure callback function.     
3320      * @param {Object} options
3321      * <div align=left>
3322      * <table class="hcap_spec" width=400>
3323      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
3324      *   <tbody>
3325      *       <tr><th>enabled</th><th>Boolean</th><th>Intelligent auto is enabled. true: enabled, false: disabled</th><th>required</th></tr>
3326      *   </tbody>
3327      * </table>
3328      * </div>
3329      * @return <p>If the method is successfully executed, call the success callback function without a parameter.</br>
3330      * If an error occurs, failure callback function is called with failure callback object as a parameter.</p>
3331      * @example
3332      * // Javascript code
3333      * 
3334      * function setStudioMode () {
3335      *   var options = {
3336      *      enabled : true
3337      *   };   
3338      *     
3339      *   function successCb() {
3340      *      // Do something
3341      *   }
3342      *
3343      *   function failureCb(cbObject) {
3344      *      var errorCode = cbObject.errorCode;
3345      *      var errorText = cbObject.errorText;
3346      *      console.log ("Error Code [" + errorCode + "]: " + errorText);
3347      *   }
3348      *
3349      *   var signage = new Signage();
3350      *   signage.setStudioMode(successCb, failureCb, options);
3351      * }
3352      * @since 1.4
3353      * @see
3354      * <a href="Signage%23getStudioMode.html">Signage.getStudioMode()</a><br>
3355      */
3356     Signage.prototype.setStudioMode = function (successCallback, errorCallback, options) {
3357         log("setStudioMode: " + options.enabled);
3358 
3359         var ret = { };
3360         checkErrorCodeNText(ret, "ERROR", "This function is not supported on webOS 3.2");
3361         errorCallback(ret);
3362         return;
3363 
3364         if (options.enabled === null && typeof errorCallback === 'function') {
3365             var result = {};
3366             checkErrorCodeNText(result, "SSSM", "Signage.setStudioMode returns failure. command was not defined.");
3367             errorCallback(result);
3368             log("Signage.setStudioMode invalid ");
3369             return;
3370         }      
3371         
3372         service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
3373             method : "set",
3374             parameters : {
3375                 category : "commercial",
3376                 settings : {
3377                     "studioMode" : (options.enabled === true ) ? "on" : "off"
3378                 }
3379             },
3380             onSuccess : function(result) {
3381                 log("setStudioMode: On Success");
3382 
3383                 if (result.returnValue === true) {
3384                     if(typeof successCallback === 'function') {
3385                         successCallback();
3386                     }
3387                 }
3388             },
3389             onFailure : function(result) {
3390                 log("setStudioMode: On Failure");
3391                 delete result.returnValue;
3392                 if (typeof errorCallback === 'function') {
3393                     checkErrorCodeNText(result, "SSSM", "Signage.setStudioMode returns failure.");
3394                     errorCallback(result);
3395                 }
3396             }
3397         });
3398         
3399         log("Signage.setStudioMode Done");
3400     };
3401 
3402 		/**
3403      * Gets StudioMode enabled
3404      * @class Signage
3405      * @param {Function} successCallback success callback function.
3406      * @param {Function} errorCallback failure callback function.
3407      * @return {Object} 
3408      * <div align=left>
3409      * <table class="hcap_spec" width=400>
3410      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
3411      *   <tbody>
3412      *       <tr><th>enabled</th><th>Boolean</th><th>Intelligent auto is enabled. true: enabled, false: disabled</th></tr>
3413      *   </tbody>
3414      * </table>
3415      * </div>
3416      *
3417      * @example
3418      * // Javascript code
3419      * function getStudioMode () {
3420      *   function successCb(cbObject) {
3421      *      console.log("cbObject : " + JSON.stringify(cbObject));
3422      *
3423      *      console.log("enabled : " + cbObject.enabled);     
3424      *
3425      *      // Do something
3426      *         ...
3427      *   }
3428      *
3429      *   function failureCb(cbObject) {
3430      *      var errorCode = cbObject.errorCode;
3431      *      var errorText = cbObject.errorText;
3432      *      console.log ("Error Code [" + errorCode + "]: " + errorText);
3433      *   }
3434      *
3435      *   var signage = new Signage();
3436      *   signage.getStudioMode(successCb, failureCb);
3437      * }
3438      * @since 1.4
3439      * @see
3440      * <a href="Signage%23setStudioMode.html">Signage.setStudioMode()</a><br>  
3441      */
3442     Signage.prototype.getStudioMode = function (successCallback, errorCallback) {
3443         
3444         log("getStudioMode: ");
3445         var ret = { };
3446         checkErrorCodeNText(ret, "ERROR", "This function is not supported on webOS 3.2");
3447         errorCallback(ret);
3448         return;
3449 
3450             service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
3451                 method : "get",
3452                 parameters : {
3453                     category : "commercial",
3454                     keys : ["studioMode"]
3455                 },
3456                 onSuccess : function(result) {
3457                     log("getStudioMode: On Success");
3458                     
3459                     if (result.returnValue === true) {
3460                         var cbObj = {};                        
3461                         cbObj.enabled = (result.settings.studioMode === "on") ? true : false;
3462                     
3463                         if (typeof successCallback === 'function') {
3464                             successCallback(cbObj);
3465                         }
3466                     }
3467                 },
3468                 onFailure : function(result) {
3469                     log("getStudioMode: On Failure");
3470                     delete result.returnValue;
3471                     if (typeof errorCallback === 'function') {
3472                         checkErrorCodeNText(result, "SGSM", "Signage.getStudioMode returns failure.");
3473                         errorCallback(result);
3474                     }
3475                 }
3476             });
3477         
3478         log("Signage.getStudioMode Done");
3479     };
3480     
3481     	/**
3482      * set LanDaisyChain enabled/disabled
3483      * @class Signage
3484      * @param {Function} successCallback success callback function.
3485      * @param {Function} errorCallback failure callback function.     
3486      * @param {Object} options
3487      * <div align=left>
3488      * <table class="hcap_spec" width=400>
3489      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
3490      *   <tbody>
3491      *       <tr><th>enabled</th><th>Boolean</th><th>Intelligent auto is enabled. true: enabled, false: disabled</th><th>required</th></tr>
3492      *   </tbody>
3493      * </table>
3494      * </div>
3495      * @return <p>If the method is successfully executed, call the success callback function without a parameter.</br>
3496      * If an error occurs, failure callback function is called with failure callback object as a parameter.</p>
3497      * @example
3498      * // Javascript code
3499      * 
3500      * function setLanDaisyChain () {
3501      *   var options = {
3502      *      enabled : true
3503      *   };   
3504      *     
3505      *   function successCb() {
3506      *      // Do something
3507      *   }
3508      *
3509      *   function failureCb(cbObject) {
3510      *      var errorCode = cbObject.errorCode;
3511      *      var errorText = cbObject.errorText;
3512      *      console.log ("Error Code [" + errorCode + "]: " + errorText);
3513      *   }
3514      *
3515      *   var signage = new Signage();
3516      *   signage.setLanDaisyChain(successCb, failureCb, options);
3517      * }
3518      * @since 1.4
3519      * @see
3520      * <a href="Signage%23getLanDaisyChain.html">Signage.getLanDaisyChain()</a><br>
3521      */
3522 	Signage.prototype.setLanDaisyChain = function (successCallback, errorCallback, options) {
3523         
3524         service.Request("luna://com.webos.service.config/", {
3525             method: "getConfigs",
3526             parameters: {
3527                 configNames: ["commercial.hw.lanDaisyChain"]
3528             },
3529             onSuccess: function(result) {
3530             	if (result.returnValue === true) {
3531 	                if (result.configs["commercial.hw.lanDaisyChain"] === false) {                
3532 	                    checkErrorCodeNText(result, "SSLD", "Signage.setLanDaisyChain returns failure. unsupported feature. ");
3533 	            		errorCallback(result);
3534 	            		log("Signage.setLanDaisyChain invalid ");
3535 	            		return;                               
3536 	                }
3537 	                else {
3538 	                	if (options.enabled === null && typeof errorCallback === 'function') {
3539 				            var result = {};
3540 				            checkErrorCodeNText(result, "SSLD", "Signage.setLanDaisyChain returns failure. command was not defined.");
3541 				            errorCallback(result);
3542 				            log("Signage.setLanDaisyChain invalid ");
3543 				            return;
3544 				        }   
3545 				        
3546 				        log("setLanDaisyChain: " + options.enabled);
3547 				                   
3548 				        service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
3549 				            method : "set",
3550 				            parameters : {
3551 				                category : "commercial",
3552 				                settings : {
3553 				                    "lanDaisyChain" : (options.enabled === true ) ? "on" : "off"
3554 				                }
3555 				            },
3556 				            onSuccess : function(result) {
3557 				                log("setLanDaisyChain: On Success");
3558 				
3559 				                if (result.returnValue === true) {
3560 				                    if(typeof successCallback === 'function') {
3561 				                        successCallback();
3562 				                    }
3563 				                }
3564 				            },
3565 				            onFailure : function(result) {
3566 				                log("setLanDaisyChain: On Failure");
3567 				                delete result.returnValue;
3568 				                if (typeof errorCallback === 'function') {
3569 				                    checkErrorCodeNText(result, "SSIA", "Signage.setLanDaisyChain returns failure.");
3570 				                    errorCallback(result);
3571 				                }
3572 				            }
3573 				        });
3574 				        
3575 				        log("Signage.setLanDaisyChain Done");
3576 	                }
3577                 }
3578             },
3579             onFailure: function(result) {
3580                 delete result.returnValue;
3581                 if (typeof errorCallback === 'function') {
3582                     errorCallback(result);
3583                 }
3584             }
3585         });
3586       
3587         
3588     };
3589 
3590 	/**
3591      * Gets LanDaisyChain enabled
3592      * @class Signage
3593      * @param {Function} successCallback success callback function.
3594      * @param {Function} errorCallback failure callback function.
3595      * @return {Object} 
3596      * <div align=left>
3597      * <table class="hcap_spec" width=400>
3598      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
3599      *   <tbody>
3600      *       <tr><th>enabled</th><th>Boolean</th><th>Intelligent auto is enabled. true: enabled, false: disabled</th></tr>
3601      *   </tbody>
3602      * </table>
3603      * </div>
3604      *
3605      * @example
3606      * // Javascript code
3607      * function getLanDaisyChain () {
3608      *   function successCb(cbObject) {
3609      *      console.log("cbObject : " + JSON.stringify(cbObject));
3610      *      console.log("enabled : " + cbObject.enabled);
3611      *      // Do something     
3612      *   }
3613      *
3614      *   function failureCb(cbObject) {
3615      *      var errorCode = cbObject.errorCode;
3616      *      var errorText = cbObject.errorText;
3617      *      console.log ("Error Code [" + errorCode + "]: " + errorText);
3618      *   }
3619      *
3620      *   var signage = new Signage();
3621      *   signage.getLanDaisyChain(successCb, failureCb);
3622      * }
3623      * @since 1.4
3624      * @see
3625      * <a href="Signage%23setLanDaisyChain.html">Signage.setLanDaisyChain()</a><br> 
3626      */
3627     Signage.prototype.getLanDaisyChain = function (successCallback, errorCallback) {
3628         
3629         service.Request("luna://com.webos.service.config/", {
3630             method: "getConfigs",
3631             parameters: {
3632                 configNames: ["commercial.hw.lanDaisyChain"]
3633             },
3634             onSuccess: function(result) {
3635             	if (result.returnValue === true) {
3636 	                if (result.configs["commercial.hw.lanDaisyChain"] === false) {                
3637 	                    checkErrorCodeNText(result, "SSLD", "Signage.getLanDaisyChain returns failure. unsupported feature. ");
3638 	            		errorCallback(result);
3639 	            		log("Signage.getLanDaisyChain invalid ");
3640 	            		return;                               
3641 	                }
3642 	                else {
3643 	                	log("getLanDaisyChain: ");
3644 	        
3645 				        service.Request("luna://com.webos.service.commercial.signage.storageservice/settings/", {
3646 				            method : "get",
3647 				            parameters : {
3648 				                category : "commercial",
3649 				                keys : ["lanDaisyChain"]
3650 				            },
3651 				            onSuccess : function(result) {
3652 				                log("getLanDaisyChain: On Success");
3653 				                
3654 				                if (result.returnValue === true) {
3655 				                    var cbObj = {};                        
3656 				                    cbObj.enabled = (result.settings.lanDaisyChain === "on") ? true : false;
3657 				                
3658 				                    if (typeof successCallback === 'function') {
3659 				                        successCallback(cbObj);
3660 				                    }
3661 				                }
3662 				            },
3663 				            onFailure : function(result) {
3664 				                log("getLanDaisyChain: On Failure");
3665 				                delete result.returnValue;
3666 				                if (typeof errorCallback === 'function') {
3667 				                    checkErrorCodeNText(result, "SSLD", "Signage.getLanDaisyChain returns failure.");
3668 				                    errorCallback(result);
3669 				                }
3670 				            }
3671 				        });
3672 				        
3673 				        log("Signage.getLanDaisyChain Done");
3674 	                }
3675                 }
3676             },
3677             onFailure: function(result) {
3678                 delete result.returnValue;
3679                 if (typeof errorCallback === 'function') {
3680                     errorCallback(result);
3681                 }
3682             }
3683         });        
3684     };
3685 
3686 
3687     /**
3688      * <p>
3689      * Registers event listener to monitor RS232C data. To use this function, it needs RS232C connection from external device to signage display.
3690      * when external device send the RS232C command following the below protocol, SCAP app can receive the data from external device .</br></br>
3691      * <strong>RS232C Configuration</strong></br>
3692      * Baudrate : 9600<br>Data : 8 bit<br>Parity : none<br>Stop : 1 bit<br>Flow Control : none</br></br>
3693      * <strong>Protocol</strong></br>
3694      * mediabox_[DATA]_[CHECKSUM]</br>
3695      * [DATA] : 1 ~ 100 bytes</br>
3696      * [CHECKSUM]: the last 2 byte hex value after summing all 2 byte hex values in [DATA]</br></br>
3697      * For example, external device should send the ASCII data("mediabox_dummy data_E6") to signage display for SCAP app to receive "dummy data"</br>
3698      * d(0x64) u(0x75) m(0x6d) m(0x6d) y(0x79) SP(0x20) d(0x64) a(0x61) t(0x74) a(0x61)</br>
3699      * 0x64 + 0x75 + 0x6d + 0x6d + 0x79 + 0x20 + 0x64 + 0x61 + 0x74 + 0x61 = 0x3E6 (the checksum of this data is 'E6')</br>
3700      * </p>
3701      * @example 
3702      * // Javascript code
3703      * function registerRS232CEventListener() {
3704      *    var eventListener = function(data){    
3705      *      console.log("received data : " + data.toString());
3706      *    };
3707      * 
3708      *    var options = {      
3709      *      eventListener : eventListener 
3710      *    };
3711      *  
3712      *    var successCb = function (){
3713      *      console.log("success");
3714      *    };
3715      * 
3716      *    var failureCb = function(cbObject){
3717      *      var errorCode = cbObject.errorCode;
3718      *      var errorText = cbObject.errorText;
3719      *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
3720      *    };
3721      * 
3722      *    var signage = new Signage();
3723      *    signage.registerRS232CEventListener(successCb, failureCb, options);     
3724      * }
3725      * 
3726      * @class Signage
3727      * @param {Function} successCallback success callback function.
3728      * @param {Function} errorCallback failure callback function.
3729      * @param {Object} options
3730      * <div align=left>
3731      * <table class="hcap_spec" width=400>
3732      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
3733      *   <tbody>
3734      *       <tr><th>eventListener</th><th>Function</th><th>Event listener to receive data from RS232C port.</th><th>required</th></tr>
3735      *   </tbody>
3736      * </table>
3737      * </div>
3738      * @param {Function} options.eventListener The function for listening RS232C data. it can receive an event object which contains following property through this function.
3739      * <div align=left>
3740      * <table class="hcap_spec" width=400>
3741      *   <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead>
3742      *   <tbody>     
3743      *       <tr><th>data</th><th>String</th><th>Received data from RS232C port</br>1 ~ 100 bytes</th><th>Required</th></tr>
3744      *   </tbody>
3745      * </table>
3746      * </div>
3747      * @returns  
3748      * <p>
3749      * After the method is successfully executed, successCallback is called without any parameter.</br>
3750      * If an error occurs, errorCallback is called with errorCode and errorText.</p>
3751      * @since 1.5
3752      * @see
3753      * <a href="Signage%23unregisterRS232CEventListener.html">Signage.unregisterRS232CEventListener()</a><br> 
3754      */
3755     Signage.prototype.registerRS232CEventListener = function (successCallback, errorCallback, options) {
3756         
3757         if (typeof options.eventListener !== 'function') {
3758             var cbObj = {
3759                 errorCode: "BAD_PARAMETER",
3760                 errorText: "No event listener was given or event listener is not a function"
3761             };            
3762             errorCallback(cbObj);
3763             return false;
3764         }
3765         
3766         monitorRS232C(successCallback, errorCallback, options.eventListener);
3767     };    
3768 
3769     /**
3770      * <p>
3771      * Unregisters event listener to monitor rs232c data. No more events will be received.
3772      * </p>
3773      * @example 
3774      * // Javascript code
3775      * function unregisterRS232CEventListener() {
3776      *    var successCb = function (){
3777      *      console.log("successfully canceled");
3778      *    };
3779      * 
3780      *    var failureCb = function(cbObject){
3781      *      var errorCode = cbObject.errorCode;
3782      *      var errorText = cbObject.errorText;
3783      *      console.log( " Error Code [" + errorCode + "]: " + errorText); 
3784      *    };
3785      * 
3786      *    var signage = new Signage();
3787      *    signage.unregisterRS232CEventListener(successCb, failureCb);
3788      * }
3789      * 
3790      * @class Signage
3791      * @param {Function} successCallback success callback function.
3792      * @param {Function} errorCallback failure callback function.
3793      * 
3794      * @returns  <p>After the method is successfully executed, successCallback is called without any parameter.</br>
3795      * If an error occurs, errorCallback is called with errorCode and errorText.</p>     
3796      * @since 1.5
3797      * @see
3798      * <a href="Signage%23registerRS232CEventListener.html">Signage.registerRS232CEventListener()</a><br> 
3799      */
3800     Signage.prototype.unregisterRS232CEventListener = function(successCallback, errorCallback) {
3801 
3802         if (removeSubscriptionEventInfo('RS232C') === false) {
3803             if (typeof errorCallback === 'function') {
3804                 errorCallback({
3805                     errorCode: "BAD_PARAMETER",
3806                     errorText: "Failed to remove event listener"
3807                 });
3808             }
3809 
3810             return;
3811         } else {
3812             service.Request("luna://com.webos.service.commercial.signage.storageservice", {
3813                 method: "systemMonitor/stopMonitorRS232C",
3814                 parameters: {},
3815                 onSuccess: function(result) {
3816                     log("On Success");
3817                     if (result.returnValue === true) {
3818                         if (typeof successCallback === 'function') {
3819                             successCallback();
3820                         }
3821                     } else {
3822                         if (typeof errorCallback === 'function') {
3823                             errorCallback(result);
3824                         }
3825                     }
3826                 },
3827                 onFailure: function(result) {
3828                     log("On Failure");
3829                     delete result.returnValue;
3830                     if (typeof errorCallback === 'function') {
3831                         errorCallback(result);
3832                     }
3833                 }
3834             });
3835         }
3836     };
3837 
3838     Signage.prototype.addEventListener = addSignageEventListener;
3839     Signage.prototype.removeEventListener = removeSignageEventListener;
3840 
3841     module.exports = Signage;
3842 });
3843 
3844 Signage = cordova.require('cordova/plugin/signage'); // jshint ignore:line
3845 
3846