[Content] Add listeners and events support
[platform/framework/web/tizen-extensions-crosswalk.git] / content / content_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 _callbacks = {};
6 var _nextReplyId = 1; // 0 is reserved for events
7
8 function getNextReplyId() {
9   return _nextReplyId++;
10 }
11
12 function postMessage(msg, callback) {
13   var replyId = getNextReplyId();
14   _callbacks[replyId] = callback;
15   msg.replyId = replyId;
16   extension.postMessage(JSON.stringify(msg));
17 }
18
19 function sendSyncMessage(msg) {
20   return extension.internal.sendSyncMessage(JSON.stringify(msg));
21 }
22
23 extension.setMessageListener(function(msg) {
24   var m = JSON.parse(msg);
25   var replyId = m.replyId;
26   var callback = _callbacks[replyId];
27
28   if (replyId == 0) { // replyId zero is for events
29     if (exports.changeListener != null) {
30       if (m.eventType == 'INSERT')
31         exports.changeListener.oncontentadded(m.value);
32       else if (m.eventType == 'DELETE')
33         exports.changeListener.oncontentremoved(m.value.id);
34       else if (m.eventType == 'UPDATE')
35         exports.changeListener.oncontentupdated(m.value);
36     }
37   } else if (typeof(callback) === 'function') {
38     callback(m);
39     delete m.replyId;
40     delete _callbacks[replyId];
41   } else {
42     console.log('Invalid replyId from Tizen Content API: ' + replyId);
43   }
44 });
45
46 function Folder(uri, id, type, title) {
47   Object.defineProperties(this, {
48     'directoryURI': { writable: false, value: uri, enumerable: true },
49     'id': { writable: false, value: id, enumerable: true },
50     'storageType': { writable: false, value: type, enumerable: true },
51     'title': { writable: false, value: title, enumerable: true }
52   });
53 }
54
55 function Content(id, name, type, mimeType, title, contentURI, thumnailURIs, releaseDate,
56                  modifiedDate, size, description, rating) {
57   Object.defineProperties(this, {
58     'id': { writable: false, value: id, enumerable: true },
59     'name': { writable: false, value: name, enumerable: true },
60     'type': { writable: false, value: type, enumerable: true },
61     'mimeType': { writable: false, value: mimeType, enumerable: true },
62     'title': { writable: false, value: title, enumerable: true },
63     'contentURI': { writable: false, value: contentURI, enumerable: true },
64     'thumnailURIs': { writable: false, value: thumnailURIs, enumerable: true },
65     'releaseDate': { writable: false, value: releaseDate, enumerable: true },
66     'modifiedDate': { writable: false, value: modifiedDate, enumerable: true },
67     'size': { writable: false, value: size, enumerable: true },
68     'description': { writable: false, value: description, enumerable: true },
69     'rating': { writable: false, value: rating, enumerable: true }
70   });
71 }
72
73 function ContentAudio(obj, album, genres, artists, composer, copyright,
74                       bitrate, trackNumber, duration) {
75   Object.defineProperties(obj, {
76     'album': { writable: false, value: album, enumerable: true },
77     'genres': { writable: false, value: genres, enumerable: true },
78     'artists': { writable: false, value: artists, enumerable: true },
79     'composer': { writable: false, value: composer, enumerable: true },
80     'copyright': { writable: false, value: copyright, enumerable: true },
81     'bitrate': { writable: false, value: bitrate, enumerable: true },
82     'trackNumber': { writable: false, value: trackNumber, enumerable: true },
83     'duration': { writable: false, value: duration, enumerable: true }
84   });
85 }
86
87 function ContentImage(obj, width, height, orientation) {
88   Object.defineProperties(obj, {
89     'width': { writable: false, value: width, enumerable: true },
90     'height': { writable: false, value: height, enumerable: true },
91     'orientation': { writable: false, value: orientation, enumerable: true }
92   });
93 }
94
95 function ContentVideo(obj, album, artists, duration, width, height) {
96   Object.defineProperties(obj, {
97     'album': { writable: false, value: album, enumerable: true },
98     'artists': { writable: false, value: artists, enumerable: true },
99     'duration': { writable: false, value: duration, enumerable: true },
100     'width': { writable: false, value: width, enumerable: true },
101     'height': { writable: false, value: height, enumerable: true }
102   });
103 }
104
105 function ContentManager() {
106   this.changeListener = null;
107 }
108
109 ContentManager.prototype.update = function(content) {
110   if (!xwalk.utils.validateArguments('o', arguments)) {
111     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
112   }
113 };
114
115 ContentManager.prototype.updateBatch = function(content, onsuccess, onerror) {
116   if (!xwalk.utils.validateArguments('o?ff', arguments)) {
117     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
118   }
119 };
120
121 ContentManager.prototype.getDirectories = function(onsuccess, onerror) {
122   if (!xwalk.utils.validateArguments('f?f', arguments)) {
123     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
124   }
125
126   postMessage({
127     cmd: 'ContentManager.getDirectories'
128   }, function(result) {
129     if (result.isError) {
130       if (onerror)
131         onerror(new tizen.WebAPIError(result.errorCode));
132     } else if (onsuccess) {
133       var folders = [];
134
135       for (var i = 0; i < result.value.length; i++) {
136         var folder = result.value[i];
137         var jsonFolder = new Folder(folder.directoryURI,
138             folder.id,
139             folder.storageType,
140             folder.title);
141         folders.push(jsonFolder);
142       }
143       onsuccess(folders);
144     }
145   });
146 };
147
148 ContentManager.prototype.find = function(onsuccess, onerror, directoryId,
149     filter, sortMode, count, offset) {
150   if (!xwalk.utils.validateArguments('f?fsoonn', arguments)) {
151     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
152   }
153
154   postMessage({
155     cmd: 'ContentManager.find',
156     directoryId: directoryId,
157     filter: filter,
158     sortMode: sortMode,
159     count: count,
160     offset: offset
161   }, function(result) {
162     if (result.isError) {
163       if (onerror)
164         onerror(new tizen.WebAPIError(result.errorCode));
165     } else if (onsuccess) {
166       var contents = [];
167       for (var i = 0; i < result.value.length; i++) {
168         var content = result.value[i];
169         var jsonContent = new Content(content.id,
170             content.name,
171             content.type,
172             content.mimeType,
173             content.title,
174             content.contentURI,
175             content.thumnailURIs,
176             content.releaseDate,
177             content.modifiedDate,
178             content.size,
179             content.description,
180             content.rating);
181
182         if (content.type == 'AUDIO') {
183           ContentAudio(jsonContent,
184               content.album,
185               content.genres,
186               content.artists,
187               content.composer,
188               content.copyright,
189               content.bitrate,
190               content.trackNumber,
191               content.duration);
192         } else if (content.type == 'IMAGE') {
193           ContentImage(jsonContent,
194               content.width,
195               content.height,
196               content.orientation);
197         } else if (content.type == 'VIDEO') {
198           ContentImage(jsonContent,
199               content.album,
200               content.artists,
201               content.duration,
202               content.width,
203               content.height);
204         }
205         contents.push(jsonContent);
206       }
207       onsuccess(contents);
208     }
209   });
210 };
211
212 ContentManager.prototype.scanFile = function(contentURI, onsuccess, onerror) {
213   if (!xwalk.utils.validateArguments('s?ff', arguments)) {
214     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
215   }
216   postMessage({
217     cmd: 'ContentManager.scanFile',
218     contentURI: contentURI
219   }, function(result) {
220     if (result.isError) {
221       if (onerror)
222         onerror(new tizen.WebAPIError(result.errorCode));
223     } else if (onsuccess) {
224       onsuccess(contentURI);
225     }
226   });
227 };
228
229 ContentManager.prototype.setChangeListener = function(listener) {
230   if (!xwalk.utils.validateArguments('o', arguments)) {
231     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
232   }
233
234   if (!xwalk.utils.validateObject(listener, 'fff',
235       ['oncontentadded', 'oncontentupdated', 'oncontentremoved'])) {
236     throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
237   }
238
239   this.changeListener = listener;
240   sendSyncMessage({cmd: 'ContentManager.setChangeListener'});
241 };
242
243 ContentManager.prototype.unsetChangeListener = function() {
244   this.changeListener = null;
245   sendSyncMessage({cmd: 'ContentManager.unsetChangeListener'});
246 };
247
248 exports = new ContentManager();