[jslint] Enable js lint and fix the errors.
[platform/framework/web/tizen-extensions-crosswalk.git] / application / application_api.js
1 // Copyright (c) 2014 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 var asyncCallbacks = {
6   _next_id: 0,
7   _callbacks: {},
8   key: '_callback',
9
10   // Return a callback ID number which will be contained by the native message.
11   setup: function(callback) {
12     var id = ++this._next_id;
13     this._callbacks[id] = callback;
14     return id;
15   },
16
17   dispatch: function(m) {
18     var id = m[this.key];
19     var callback = this._callbacks[id];
20     callback.call(null, m);
21     delete this._callbacks[id];
22   }
23 };
24
25 var appInfoEventCallbacks = {
26   _next_id: 0,
27   _callbacks: [],
28   key: '_appInfoEventCallback',
29
30   // Return a callback ID number which can be unregistered later.
31   addCallback: function(callback) {
32     if (!this._callbacks.length) {
33       var result = sendSyncMessage({ cmd: 'RegisterAppInfoEvent' });
34       if (result.error != null)
35         throw new tizen.WebAPIException(result.error);
36     }
37
38     var id = ++this._next_id;
39     this._callbacks.push({func: callback, id: id});
40     return id;
41   },
42
43   removeCallback: function(id) {
44     for (var i = 0, len = this._callbacks.length; i < len; i++) {
45       if (id === this._callbacks[i].id)
46         break;
47     }
48     if (i == len)
49       throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR);
50
51     this._callbacks.splice(i, 1);
52     if (!this._callbacks.length) {
53       var result = sendSyncMessage({ cmd: 'UnregisterAppInfoEvent' });
54       if (result.error != null)
55         throw new tizen.WebAPIException(result.error);
56     }
57   },
58
59   dispatch: function(m) {
60     var callbacks = this._callbacks.slice();
61     for (var i = 0, len = callbacks.length; i < len; i++)
62       callbacks[i].func.call(null, m);
63   }
64 };
65
66 extension.setMessageListener(function(msg) {
67   var m = JSON.parse(msg);
68   if (typeof m[asyncCallbacks.key] === 'number') {
69     asyncCallbacks.dispatch(m);
70   } else {
71     if (m[asyncCallbacks.key] === appInfoEventCallbacks.key)
72       appInfoEventCallbacks.dispatch(m);
73     else
74       console.error('unexpected message received' + msg);
75   }
76 });
77
78 // Post async message to extension with callbackId saved. The extension will return
79 // a message with the same callbackId to the callback set in setMessageListener.
80 function postMessage(msg, callbackId) {
81   msg[asyncCallbacks.key] = callbackId;
82   extension.postMessage(JSON.stringify(msg));
83 }
84
85 function sendSyncMessage(msg) {
86   return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(msg)));
87 }
88
89 function defineReadOnlyProperty(object, key, value) {
90   Object.defineProperty(object, key, {
91     enumerable: true,
92     writable: false,
93     value: value
94   });
95 }
96
97 // Define Application interface, the getRequestedAppControl method will not be
98 // implemented ATM.
99 function Application(appInfo, contextId) {
100   defineReadOnlyProperty(this, 'appInfo', appInfo);
101   defineReadOnlyProperty(this, 'contextId', contextId);
102 }
103
104 Application.prototype.exit = function() {
105   var result = sendSyncMessage({ cmd: 'ExitCurrentApp' });
106   if (result.error != null)
107     throw new tizen.WebAPIException(result.error);
108 };
109
110 Application.prototype.hide = function() {
111   var result = sendSyncMessage({ cmd: 'HideCurrentApp' });
112   if (result.error != null)
113     throw new tizen.WebAPIException(result.error);
114 };
115
116 // ApplicationContext interface.
117 function ApplicationContext(json) {
118   defineReadOnlyProperty(this, 'id', json.id);
119   defineReadOnlyProperty(this, 'appId', json.appId);
120 }
121
122 // ApplicationInformation interface.
123 function ApplicationInformation(json) {
124   for (var field in json) {
125     var val = json[field];
126     if (field === 'installDate')
127       val = new Date(val * 1000);
128     defineReadOnlyProperty(this, field, val);
129   }
130 }
131
132 // ApplicationMetaData interface.
133 function ApplicationMetaData(json) {
134   defineReadOnlyProperty(this, 'key', json.key);
135   defineReadOnlyProperty(this, 'value', json.value);
136 }
137
138 exports.getAppInfo = function(appId) {
139   if (typeof appId !== 'string' && appId != undefined)
140     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
141
142   var result = sendSyncMessage({ cmd: 'GetAppInfo', id: appId });
143   if (result.error != null)
144     throw new tizen.WebAPIException(result.error);
145   return new ApplicationInformation(result.data);
146 };
147
148 exports.getAppsInfo = function(onsuccess, onerror) {
149   if ((typeof onsuccess !== 'function') ||
150       (onerror && typeof onerror !== 'function'))
151     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
152
153   var callbackId = asyncCallbacks.setup(function(result) {
154     if (result.error != null) {
155       if (!onerror)
156         return;
157       return onerror(new tizen.WebAPIError(result.error));
158     }
159
160     var appsInfo = [];
161     for (var i = 0, len = result.data.length; i < len; ++i)
162       appsInfo.push(new ApplicationInformation(result.data[i]));
163     return onsuccess(appsInfo);
164   });
165
166   var msg = { cmd: 'GetAppsInfo' };
167   postMessage(msg, callbackId);
168 };
169
170 exports.getAppContext = function(contextId) {
171   if (contextId && !/^\d+$/.test(contextId))
172     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
173
174   var result = sendSyncMessage({ cmd: 'GetAppContext', id: contextId});
175   if (result.error)
176     throw new tizen.WebAPIException(result.error);
177
178   return new ApplicationContext(result.data);
179 };
180
181 exports.getAppsContext = function(onsuccess, onerror) {
182   if ((typeof onsuccess !== 'function') ||
183       (onerror && typeof onerror !== 'function'))
184     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
185
186   var callbackId = asyncCallbacks.setup(function(result) {
187     if (result.error != null) {
188       if (!onerror)
189         return;
190       return onerror(new tizen.WebAPIError(result.error));
191     }
192
193     var contexts = [];
194     for (var i = 0, len = result.data.length; i < len; ++i)
195       contexts.push(new ApplicationContext(result.data[i]));
196     return onsuccess(contexts);
197   });
198
199   var msg = { cmd: 'GetAppsContext' };
200   postMessage(msg, callbackId);
201 };
202
203 exports.getCurrentApplication = function() {
204   var result = sendSyncMessage({ cmd: 'GetCurrentApp' });
205   if (result.error)
206     throw new tizen.WebAPIException(result.error);
207
208   var appInfo = new ApplicationInformation(result.data.appInfo);
209   return new Application(appInfo, result.data.appContext.id);
210 };
211
212 exports.kill = function(contextId, onsuccess, onerror) {
213   if ((!/^\d+$/.test(contextId)) ||
214       (onsuccess && typeof onsuccess !== 'function') ||
215       (onerror && typeof onerror !== 'function'))
216     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
217
218   var callbackId = asyncCallbacks.setup(function(result) {
219     if (result.error != null) {
220       if (!onerror)
221         return;
222       return onerror(new tizen.WebAPIError(result.code));
223     }
224     return onsuccess();
225   });
226
227   var msg = { cmd: 'KillApp', id: contextId };
228   postMessage(msg, callbackId);
229 };
230
231 exports.launch = function(appId, onsuccess, onerror) {
232   if ((typeof appId !== 'string') ||
233       (onsuccess && typeof onsuccess !== 'function') ||
234       (onerror && typeof onerror !== 'function'))
235     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
236
237   var callbackId = asyncCallbacks.setup(function(result) {
238     if (result.error != null) {
239       if (!onerror)
240         return;
241       return onerror(new tizen.WebAPIError(result.error));
242     }
243     return onsuccess();
244   });
245
246   var msg = { cmd: 'LaunchApp', id: appId };
247   postMessage(msg, callbackId);
248 };
249
250 exports.addAppInfoEventListener = function(eventCallback) {
251   if (typeof eventCallback !== 'object' ||
252       typeof eventCallback.oninstalled !== 'function' ||
253       typeof eventCallback.onupdated !== 'function' ||
254       typeof eventCallback.onuninstalled !== 'function')
255     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
256
257   var watchId = appInfoEventCallbacks.addCallback(function(result) {
258     if (result.installed) {
259       result.installed.forEach(function(appInfo) {
260         var appInfo = new ApplicationInformation(appInfo);
261         eventCallback.oninstalled(appInfo);
262       });
263     }
264     if (result.updated) {
265       result.updated.forEach(function(appInfo) {
266         var appInfo = new ApplicationInformation(appInfo);
267         eventCallback.onupdated(appInfo);
268       });
269     }
270     if (result.uninstalled) {
271       result.uninstalled.forEach(function(appId) {
272         eventCallback.onuninstalled(appId);
273       });
274     }
275   });
276
277   return watchId;
278 };
279
280 exports.removeAppInfoEventListener = function(watchId) {
281   if (typeof watchId !== 'number')
282     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
283
284   appInfoEventCallbacks.removeCallback(watchId);
285 };
286
287 exports.getAppMetaData = function(appId) {
288   if (typeof appId !== 'string' && appId != undefined)
289     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
290
291   var result = sendSyncMessage({ cmd: 'GetAppMetaData', id: appId });
292   if (result.error != null)
293     throw new tizen.WebAPIException(result.error);
294
295   var data = [];
296   for (var i = 0, len = result.data.length; i < len; ++i)
297     data.push(new ApplicationMetaData(result.data[i]));
298   return data;
299 };