Delay initializing the phone stack till the first request comes
[profile/ivi/sockdrawer.git] / Tizen.Device.js
1 ///////////////////////////////////////////////////////////////////////////////
2 // This is a partial implementation of the tizen.application web specification
3 // which using a websocket server for implementing the native backend
4
5 var __application = function () {
6     var appList;
7     var callback;
8
9     var socket = new WebSocket("ws://localhost:7681", "app-list-protocol");
10     socket.onmessage = function(msg) {
11         appList = JSON.parse(msg.data);
12         if (callback)
13             callback(appList);
14     }
15
16     this.launch = function (id, successCallback, errorCallback, argument) {
17         var cmd = {"cmd": "launch", "index": id};
18         socket.send(JSON.stringify(cmd));
19     }
20     this.getAppInfo = function(id) {
21         return appList[id];
22     }
23     this.addAppInfoEventListener = function(eventCallback, errorCallback) {
24         callback = eventCallback;
25     }
26 }
27
28 var __callmanager = function () {
29     var calls = new Array();
30     var callHandlers = new Array();
31     var services = new Array();
32
33     var messagecb = function(msg) {
34         var ev = JSON.parse(msg.data);
35
36         if (ev.type == "ModemAdded") {
37             tizen.__account.addAccount(new tizen.Account(ev.ModemAdded, ev));
38         } else if (ev.type == "ModemRemoved") {
39             tizen.__account.deleteAccount(ev.id);
40         } else if (ev.type == "CallAdded") {
41             calls.push(new __call(this, socket, ev));
42         } else if (ev.type == "CallRemoved") {
43             var tmp = new Array();
44             for (var i in calls)
45                 if (calls[i].id != ev.id)
46                     tmp.push(calls[i]);
47             calls = tmp;
48         } 
49
50         if (ev.State) {
51             try {
52                 if (ev.State == "incoming") {
53                     for (var index in callHandlers)
54                         for (var i in calls)
55                             if (calls[i].id == ev.id)
56                                 callHandlers[index].onIncoming(calls[i]);
57                 } else if (ev.State == "dialing") {
58                     for (var index in callHandlers)
59                         for (var i in calls)
60                             if (calls[i].id == ev.id)
61                                 callHandlers[index].onDialing(calls[i]);
62                 } else if (ev.State == "alerting") {
63                     for (var index in callHandlers)
64                         for (var i in calls)
65                             if (calls[i].id == ev.id)
66                                 callHandlers[index].onAlerting(calls[i]);
67                 } else if (ev.State == "hold") {
68                     for (var index in callHandlers)
69                         for (var i in calls)
70                             if (calls[i].id == ev.id)
71                                 callHandlers[index].onHold(calls[i]);
72                 } else if (ev.State == "waiting") {
73                     for (var index in callHandlers)
74                         for (var i in calls)
75                             if (calls[i].id == ev.id)
76                                 callHandlers[index].onWaiting(calls[i]);
77                 } else if (ev.State == "disconnected") {
78                     for (var index in callHandlers)
79                         for (var i in calls)
80                             if (calls[i].id == ev.id)
81                                 callHandlers[index].onDisconnected(calls[i]);
82                 } else if (ev.State == "disconnecting") {
83                     for (var index in callHandlers)
84                         for (var i in calls)
85                             if (calls[i].id == ev.id)
86                                 callHandlers[index].onDisconnecting(calls[i]);
87                 } else if (ev.State == "accepted") {
88                     for (var index in callHandlers)
89                         for (var i in calls)
90                             if (calls[i].id == ev.id)
91                                 callHandlers[index].onAccepted(calls[i]);
92                 } else if (ev.State == "remotelyheld") {
93                     for (var index in callHandlers)
94                         for (var i in calls)
95                             if (calls[i].id == ev.id)
96                                 callHandlers[index].onRemotelyHeld(calls[i]);
97                 } else if (ev.State == "active") {
98                     for (var index in callHandlers)
99                         for (var i in calls)
100                             if (calls[i].id == ev.id)
101                                 callHandlers[index].onActivated(calls[i]);
102                 } else if (ev.State == "initializing") {
103                     for (var index in callHandlers)
104                         for (var i in calls)
105                             if (calls[i].id == ev.id)
106                                 callHandlers[index].onInitializing(calls[i]);
107                 } else if (ev.State == "initialized") {
108                     for (var index in callHandlers)
109                         for (var i in calls)
110                             if (calls[i].id == ev.id)
111                                 callHandlers[index].onInitialized(calls[i]);
112                 } else {
113                     console.log("Unhandled state: " + ev.State);
114                 }
115             } catch (err) {
116                 // handlers do not have to implement every callback
117             }
118         }
119     }
120
121     var socket = null;
122     function openWS() {
123         socket = new WebSocket("ws://localhost:7681", "dialer-protocol");
124         socket.onmessage = messagecb;
125         socket.onclose = function() {
126             setTimeout(function() {
127                 // abort reconnect if the socket has already recoverd
128                 console.log(socket.readyState);
129                 if (socket.readyState == 1)
130                     return;
131
132                 // trigger the cleanup of accounts and callservices
133                 services = new Array();
134                 tizen.__account.__flush();
135
136                 socket = new WebSocket("ws://localhost:7681", "dialer-protocol");
137                 socket.onmessage = messagecb;
138                 socket.onclose = openWS;
139             }, 2000);
140         }
141     }
142     openWS();
143
144     var listener = {
145         "onAccountUpdated": function(account) {
146         },
147         "onAccountAdded": function(account) {
148             services.push(new __callservice(socket, account.id));
149         },
150         "onAccountRemoved": function(id) {
151             var tmp = new Array();
152             for (var i in services)
153                 if (services[i].id != id)
154                     tmp.push(id);
155             services = tmp;
156         }
157     }
158     tizen.__account.addAccountListener(listener);
159
160     this.history = null;
161     this.isCallInProgress = function() {
162         return calls.length > 0;
163     }
164     this.addCallHandler = function(handler, callServiceType, serviceName) {
165         callHandlers.push(handler);
166     }
167     this.removeCallHandler = function(handler) {
168         var tmp = new Array();
169         for (var item in callHandlers)
170             if (item != handler)
171                 tmp.push(item);
172         callHandlers = tmp;
173
174     }
175     this.getCallService = function(account) {
176         try {
177             for (var i in services)
178                 if (services[i].id == account.id)
179                     return services[i];
180         } catch (ex) {}
181
182         return services[0];
183     }
184 }
185
186 var __callservice = function (wsi, serviceid) {
187     var socket = wsi;
188
189     var id = serviceid;
190     this.__defineGetter__("id", function() {
191         return id;
192     });
193
194     this.launchDialer = function(remotePartyId) {
195         socket.send(JSON.stringify({ "cmd": "launchDialer" }));
196     }
197
198     var voicemailNumbers = new Array();
199     this.__defineGetter__("voiceNumbers", function() {
200         return voicemailNumbers;
201     });
202
203     this.makeCall = function(remotePartyId, handler, extension, localVideoOn) {
204         var c = {
205             "cmd": "makeCall",
206             "remotePartyId": remotePartyId.toString(),
207             "extension": extension,
208             "localVideoOn": localVideoOn
209         };
210         socket.send(JSON.stringify(c));
211     }
212 }
213
214 var __call = function(manager, wsi, data) {
215     var socket = wsi;
216
217     var id = data.id;
218     this.__defineGetter__("id", function() {
219         return id;
220     });
221
222     var callData = data;
223     this.__defineGetter__("callData", function() {
224         return callData;
225     });
226
227     var streamList = new Array();
228     this.__defineGetter__("streamList", function() {
229         return streamList;
230     });
231
232     this.accept = function() {
233         socket.send(JSON.stringify({"cmd": "accept", "path": id}));
234     }
235     this.reject = function() {
236         socket.send(JSON.stringify({"cmd": "reject"}));
237     }
238     this.wait = function() {
239         socket.send(JSON.stringify({"cmd": "wait"}));
240     }
241     this.redirect = function(rid) {
242         socket.send(JSON.stringify({"cmd": "redirect"}));
243     }
244     this.end = function() {
245         socket.send(JSON.stringify({"cmd": "end", "path": id}));
246     }
247     this.hold = function() {
248         socket.send(JSON.stringify({"cmd": "hold"}));
249     }
250     this.activate = function() {
251         socket.send(JSON.stringify({"cmd": "activate"}));
252     }
253     this.migrate = function(callService, callParticipant) {
254         socket.send(JSON.stringify({"cmd": "migrate", "callService": callService, "callParticipant": callParticipant}));
255     }
256     this.merge = function(otherCall) {
257         socket.send(JSON.stringify({"cmd": "merge", "otherCall": otherCall}));
258     }
259     this.drop = function(participant) {
260         socket.send(JSON.stringify({"cmd": "drop", "participant": participant}));
261     }
262     this.split = function(participant) {
263         socket.send(JSON.stringify({"cmd": "split", "participant": participant}));
264     }
265     this.addParticipant = function(remotePartyId, successCallback, errorCallback) {
266     }
267     this.addStream = function(addStream, successCallback, errorCallback) {
268     }
269     this.removeStream = function(addStream, successCallback, errorCallback) {
270     }
271     this.setAudioVolume = function(volume, successCallback, errorCallback) {
272     }
273     this.setMicrophoneSensitivity = function(sensitivity, successCallback, errorCallback) {
274     }
275     this.setLocalVideoEnabled = function(onoff, successCallback, errorCallback) {
276     }
277     this.sendDTMF = function(tones, duration, interval, successCallback, errorCallback) {
278     }
279     this.record = function() {
280     }
281     this.pause = function() {
282     }
283 }
284
285 var __accountmanager = function() {
286     var listeners = new Array();
287     var accounts = new Array();
288
289     this.findServices = function(filter) {
290         /* brain dead matching, patches accepted */
291         var result = new Array();
292         if (accounts.length == 0)
293             return result;
294         try {
295             for (var i in accounts) {
296                 var a = accounts[i];
297                 for (var f in filter)
298                     if (a[f] && a[f] == filter[f]) {
299                         result.push(a);
300                         continue;
301                     }
302             }
303         } catch (err) {
304             console.log(err);
305         }
306
307         if (result.length == 0)
308             result.push(accounts[0]);
309
310         return result;
311     }
312     this.getAccountById = function(accountid) {
313         for (var i in accounts)
314             if (accounts[i].id == accountid)
315                 return accounts[i];
316         return null;
317     }
318     this.deleteAccount = function(accountid) {
319         var l = new Array();
320         for (var i in accounts)
321             if (accountid != accounts[i].id)
322                 l.push(accounts[i]);
323         accounts = l;
324
325         for (var i in listeners)
326             listeners[i].onAccountRemoved(accountid);
327     }
328     this.addAccount = function(account) {
329         accounts.push(account);
330         for (var i in listeners)
331             listeners[i].onAccountAdded(account);
332     }
333     this.addAccountListener = function(observer, errorCallback) {
334         listeners.push(observer);
335         return listeners.length;
336     }
337     this.removeAccountListener = function(handle) {
338         var l = new Array();
339         for (var i in listeners)
340             if (i != handle)
341                 l.push(listeners[i]);
342         listeners = l;
343     }
344
345     this.__flush = function() {
346         for (var j in listeners) {
347             for (var k in accounts) {
348                 listeners[j].onAccountRemoved(accounts[k].id);
349             }
350         }
351         accounts = new Array();
352     }
353 }
354
355 var __tizen = function() {
356     var application = null;
357     this.__defineGetter__("application", function() {
358         if (application == null)
359             application = new __application();
360         return application;
361     });
362
363     this.Account = function (accountId, accountProperties) {
364         var id = accountId;
365         var properties = accountProperties;
366         this.__defineGetter__("id", function() {
367             return id;
368         });
369         for (var p in properties) {
370             this.__defineGetter__(p, function() {
371                 return properties[p];
372             });
373         }
374     }
375
376     var call = null;
377     this.__defineGetter__("call", function() {
378         if (call == null) {
379             // ensure the account object is created first
380             tizen.account;
381
382             call = new __callmanager();
383         }
384         return call;
385     });
386     var account = null;
387     this.__defineGetter__("account", function() {
388         if (account == null)
389             account = new __accountmanager();
390
391         // ensure the call object is always the first listener
392         // for new accounts, which means we need a backdoor to
393         // access the acount object before the getter has finished
394         // executing for the first time
395         this.__defineGetter__("__account", function() {
396             return account;
397         });
398         if (call == null)
399             call = new __callmanager();
400         return account;
401     });
402 }
403
404 var tizen = new __tizen();