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