2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 var _global = window || global || {};
19 var utils_ = xwalk.utils;
20 var type_ = utils_.type;
21 var converter_ = utils_.converter;
22 var validator_ = utils_.validator;
23 var types_ = validator_.Types;
24 var native_ = new xwalk.utils.NativeManager(extension);
26 function ListenerManager(native, listenerName, handle) {
28 this.listenerNameToIds = {};
29 this.listenerIdToName = {};
31 this.nativeSet = false;
33 this.listenerName = listenerName;
34 this.handle = handle || function(msg, listener, watchId) {};
37 ListenerManager.prototype.addListener = function(callback) {
39 if (!this.nativeSet) {
40 this.native.addListener(this.listenerName, function(msg) {
41 for (var watchId in this.listeners) {
42 if (this.listeners.hasOwnProperty(watchId)) {
43 var stop = this.handle(msg, this.listeners[watchId], watchId);
51 this.nativeSet = true;
54 this.listeners[id] = callback;
59 ListenerManager.prototype.addServerInfoListener = function(callback, name) {
61 if (!this.nativeSet) {
62 this.native.addListener(this.listenerName, function(msg) {
63 if (this.listenerNameToIds.hasOwnProperty(msg.name)) {
64 var cbArray = this.listenerNameToIds[msg.name];
65 for (var i = 0; i < cbArray.length; ++i) {
66 var watchId = cbArray[i];
67 this.handle(msg, this.listeners[watchId], watchId);
72 this.nativeSet = true;
75 this.listenerIdToName[id] = name;
76 if (this.listenerNameToIds[name]) {
77 this.listenerNameToIds[name].push(id);
79 this.listenerNameToIds[name] = [id];
81 this.listeners[id] = callback;
86 ListenerManager.prototype.removeListener = function(watchId) {
87 if (this.listeners.hasOwnProperty(watchId)) {
88 delete this.listeners[watchId];
92 function removeArrayElement(arr, elem) {
93 var index = arr.indexOf(elem);
99 ListenerManager.prototype.removeServerInfoListener = function(watchId) {
100 this.removeListener(watchId);
101 if (this.listenerIdToName.hasOwnProperty(watchId)) {
102 var name = this.listenerIdToName[watchId];
103 removeArrayElement(this.listenerNameToIds[name], watchId);
104 delete this.listenerIdToName[watchId];
108 var ServerCommandListener = new ListenerManager(native_, '_ServerCommandListener', function(msg, listener) {
109 var data = undefined;
110 data = listener(msg.clientName, msg.command, msg.data);
112 if (type_.isUndefined(data)) {
117 clientName: msg.clientName,
118 replyId: msg.replyId,
122 var result = native_.callSync('MediaControllerServer_replyCommand', nativeData);
123 if (native_.isFailure(result)) {
124 throw native_.getErrorObject(result);
128 var ReplyCommandListener = new ListenerManager(native_, '_ReplyCommandListener', function(msg, listener, watchId) {
129 if (msg.replyId === watchId) {
131 this.removeListener(watchId);
138 var ServerPlaybackInfoListener = new ListenerManager(native_, '_ServerPlaybackInfoListener', function(msg, listener) {
139 if (msg.action === 'onplaybackstaterequest') {
140 listener[msg.action](msg.state);
142 if (msg.action === 'onplaybackpositionrequest') {
143 listener[msg.action](msg.position);
145 if (msg.action === 'onshufflemoderequest' || msg.action === 'onrepeatmoderequest') {
146 listener[msg.action](msg.mode);
150 var ServerInfoStatusListener = new ListenerManager(native_, '_ServerInfoStatusListener', function(msg, listener) {
154 var ServerInfoPlaybackInfoListener = new ListenerManager(native_, '_ServerInfoPlaybackInfoListener', function(msg, listener) {
155 if (msg.action === 'onplaybackchanged') {
156 listener[msg.action](msg.state, msg.position);
158 if (msg.action === 'onshufflemodechanged' || msg.action === 'onrepeatmodechanged') {
159 listener[msg.action](msg.mode);
161 if (msg.action === 'onmetadatachanged') {
162 listener[msg.action](new MediaControllerMetadata(msg.metadata));
166 var EditManager = function() {
167 this.isAllowed = false;
170 EditManager.prototype.allow = function() {
171 this.isAllowed = true;
174 EditManager.prototype.disallow = function() {
175 this.isAllowed = false;
178 var edit_ = new EditManager();
181 var MediaControllerServerState = {
186 var MediaControllerPlaybackState = {
197 function MediaControllerManager() {}
199 MediaControllerManager.prototype.getClient = function() {
200 var result = native_.callSync('MediaControllerManager_getClient', {});
202 if (native_.isFailure(result)) {
203 throw native_.getErrorObject(result);
206 return new MediaControllerClient(native_.getResultObject(result));
209 MediaControllerManager.prototype.createServer = function() {
210 var result = native_.callSync('MediaControllerManager_createServer', {});
211 if (native_.isFailure(result)) {
212 throw native_.getErrorObject(result);
215 return new MediaControllerServer(native_.getResultObject(result));
219 var MediaControllerMetadata = function(data) {
228 var _description = '';
231 Object.defineProperties(this, {
233 get: function() {return _title;},
234 set: function(v) {_title = converter_.toString(v)},
238 get: function() {return _artist;},
239 set: function(v) {_artist = converter_.toString(v)},
243 get: function() {return _album;},
244 set: function(v) {_album = converter_.toString(v)},
248 get: function() {return _author;},
249 set: function(v) {_author = converter_.toString(v)},
253 get: function() {return _genre;},
254 set: function(v) {_genre = converter_.toString(v)},
258 get: function() {return _duration;},
259 set: function(v) {_duration = converter_.toString(v)},
263 get: function() {return _date;},
264 set: function(v) {_date = converter_.toString(v)},
268 get: function() {return _copyright;},
269 set: function(v) {_copyright = converter_.toString(v)},
273 get: function() {return _description;},
274 set: function(v) {_description = converter_.toString(v)},
278 get: function() {return _trackNum;},
279 set: function(v) {_trackNum = converter_.toString(v)},
283 get: function() {return _picture;},
284 set: function(v) {_picture = converter_.toString(v)},
289 if (data instanceof _global.Object) {
290 for (var prop in data) {
291 if (data.hasOwnProperty(prop) && this.hasOwnProperty(prop)) {
292 this[prop] = data[prop];
298 var MediaControllerPlaybackInfo = function(data) {
301 var _shuffleMode = false;
302 var _repeatMode = false;
303 var _metadata = new MediaControllerMetadata();
304 Object.defineProperties(this, {
310 _state = edit_.isAllowed && v ? v : _state;
319 _position = edit_.isAllowed ? converter_.toLong(v) : _position;
328 _shuffleMode = edit_.isAllowed ? converter_.toBoolean(v) : _shuffleMode;
337 _repeatMode = edit_.isAllowed ? converter_.toBoolean(v) : _repeatMode;
346 _metadata = edit_.isAllowed && v ? new MediaControllerMetadata(v) : _metadata;
352 if (data instanceof _global.Object) {
353 for (var prop in data) {
354 if (data.hasOwnProperty(prop) && this.hasOwnProperty(prop)) {
355 this[prop] = data[prop];
361 function MediaControllerServer(data) {
362 Object.defineProperties(this, {
364 value: new MediaControllerPlaybackInfo(data),
371 MediaControllerServer.prototype.updatePlaybackState = function(state) {
372 var args = validator_.validateArgs(arguments, [
373 {name: 'state', type: types_.ENUM, values: Object.keys(MediaControllerPlaybackState)}
380 var result = native_.callSync('MediaControllerServer_updatePlaybackState', data);
382 if (native_.isFailure(result)) {
383 throw native_.getErrorObject(result);
387 this.playbackInfo.state = args.state;
391 MediaControllerServer.prototype.updatePlaybackPosition = function(position) {
392 var args = validator_.validateArgs(arguments, [
393 {name: 'position', type: types_.UNSIGNED_LONG_LONG}
397 position: args.position
400 var result = native_.callSync('MediaControllerServer_updatePlaybackPosition', data);
402 if (native_.isFailure(result)) {
403 throw native_.getErrorObject(result);
407 this.playbackInfo.position = args.position;
411 MediaControllerServer.prototype.updateShuffleMode = function(mode) {
412 var args = validator_.validateArgs(arguments, [
413 {name: 'mode', type: types_.BOOLEAN}
420 var result = native_.callSync('MediaControllerServer_updateShuffleMode', data);
422 if (native_.isFailure(result)) {
423 throw native_.getErrorObject(result);
427 this.playbackInfo.shuffleMode = args.mode;
431 MediaControllerServer.prototype.updateRepeatMode = function(mode) {
432 var args = validator_.validateArgs(arguments, [
433 {name: 'mode', type: types_.BOOLEAN}
440 var result = native_.callSync('MediaControllerServer_updateRepeatMode', data);
442 if (native_.isFailure(result)) {
443 throw native_.getErrorObject(result);
447 this.playbackInfo.repeatMode = args.mode;
451 MediaControllerServer.prototype.updateMetadata = function(metadata) {
452 var args = validator_.validateArgs(arguments, [
453 {name: 'metadata', type: types_.PLATFORM_OBJECT, values: MediaControllerMetadata}
457 metadata: args.metadata
460 var result = native_.callSync('MediaControllerServer_updateMetadata', data);
462 if (native_.isFailure(result)) {
463 throw native_.getErrorObject(result);
467 this.playbackInfo.metadata = args.metadata;
471 MediaControllerServer.prototype.addChangeRequestPlaybackInfoListener = function(listener) {
472 var args = validator_.validateArgs(arguments, [{
474 type: types_.LISTENER,
476 'onplaybackstaterequest',
477 'onplaybackpositionrequest',
478 'onshufflemoderequest',
479 'onrepeatmoderequest'
483 if (type_.isEmptyObject(ServerPlaybackInfoListener.listeners)) {
484 var result = native_.callSync('MediaControllerServer_addChangeRequestPlaybackInfoListener', {
485 listenerId: ServerPlaybackInfoListener.listenerName
487 if (native_.isFailure(result)) {
488 throw native_.getErrorObject(result);
492 return ServerPlaybackInfoListener.addListener(args.listener);
495 MediaControllerServer.prototype.removeChangeRequestPlaybackInfoListener = function(watchId) {
496 var args = validator_.validateArgs(arguments, [
497 {name: 'watchId', type: types_.LONG}
500 ServerPlaybackInfoListener.removeListener(args.watchId);
502 if (type_.isEmptyObject(ServerPlaybackInfoListener.listeners)) {
503 native_.callSync('MediaControllerServer_removeCommandListener');
507 MediaControllerServer.prototype.addCommandListener = function(listener) {
508 var args = validator_.validateArgs(arguments, [
509 {name: 'listener', type: types_.FUNCTION}
512 if (type_.isEmptyObject(ServerCommandListener.listeners)) {
513 var result = native_.callSync('MediaControllerServer_addCommandListener', {
514 listenerId: ServerCommandListener.listenerName
516 if (native_.isFailure(result)) {
517 throw native_.getErrorObject(result);
521 return ServerCommandListener.addListener(args.listener);
524 MediaControllerServer.prototype.removeCommandListener = function(watchId) {
525 var args = validator_.validateArgs(arguments, [
526 {name: 'watchId', type: types_.LONG}
529 ServerCommandListener.removeListener(args.watchId);
531 if (type_.isEmptyObject(ServerCommandListener.listeners)) {
532 native_.callSync('MediaControllerServer_removeCommandListener');
537 function MediaControllerClient() {}
539 MediaControllerClient.prototype.findServers = function(successCallback, errorCallback) {
540 var args = validator_.validateArgs(arguments, [
541 {name: 'successCallback', type: types_.FUNCTION},
542 {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
545 var callback = function(result) {
546 if (native_.isFailure(result)) {
547 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
551 var data = native_.getResultObject(result);
552 for (var i = 0; i < data.length; i++) {
553 info.push(new MediaControllerServerInfo(data[i]));
555 native_.callIfPossible(args.successCallback, info);
558 native_.call('MediaControllerClient_findServers', {}, callback);
561 MediaControllerClient.prototype.getLatestServerInfo = function() {
563 var result = native_.callSync('MediaControllerClient_getLatestServerInfo', {});
565 if (native_.isFailure(result)) {
566 throw native_.getErrorObject(result);
569 var serverInfo = native_.getResultObject(result);
571 if ('NONE' === serverInfo.state) {
572 serverInfo.state = 'INACTIVE';
574 serverInfo = new MediaControllerServerInfo(serverInfo);
580 function MediaControllerServerInfo(data) {
581 Object.defineProperties(this, {
594 var result = native_.callSync('MediaControllerClient_getPlaybackInfo', {name: this.name});
595 if (native_.isFailure(result)) {
596 throw new native_.getErrorObject(result);
599 var data = native_.getResultObject(result);
600 var playbackInfo = new MediaControllerPlaybackInfo(data);
612 MediaControllerServerInfo.prototype.sendPlaybackState = function(state, successCallback, errorCallback) {
613 var args = validator_.validateArgs(arguments, [
614 {name: 'state', type: types_.ENUM, values: Object.keys(MediaControllerPlaybackState)},
615 {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
616 {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
624 var callback = function(result) {
625 if (native_.isFailure(result)) {
626 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
629 native_.callIfPossible(args.successCallback);
632 native_.call('MediaControllerServerInfo_sendPlaybackState', data, callback);
635 MediaControllerServerInfo.prototype.sendPlaybackPosition = function(position, successCallback, errorCallback) {
636 var args = validator_.validateArgs(arguments, [
637 {name: 'position', type: types_.LONG_LONG},
638 {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
639 {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
642 if (args.position < 0) {
643 throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
646 var callback = function(result) {
647 if (native_.isFailure(result)) {
648 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
651 native_.callIfPossible(args.successCallback);
655 position: args.position,
659 native_.call('MediaControllerServerInfo_sendPlaybackPosition', data, callback);
662 MediaControllerServerInfo.prototype.sendShuffleMode = function(mode, successCallback, errorCallback) {
663 var args = validator_.validateArgs(arguments, [
664 {name: 'mode', type: types_.BOOLEAN},
665 {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
666 {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
669 var callback = function(result) {
670 if (native_.isFailure(result)) {
671 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
674 native_.callIfPossible(args.successCallback);
681 native_.call('MediaControllerServerInfo_sendShuffleMode', data, callback);
684 MediaControllerServerInfo.prototype.sendRepeatMode = function(mode, successCallback, errorCallback) {
685 var args = validator_.validateArgs(arguments, [
686 {name: 'mode', type: types_.BOOLEAN},
687 {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
688 {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
691 var callback = function(result) {
692 if (native_.isFailure(result)) {
693 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
696 native_.callIfPossible(args.successCallback);
703 native_.call('MediaControllerServerInfo_sendRepeatMode', data, callback);
706 MediaControllerServerInfo.prototype.sendCommand = function(command, data, successCallback, errorCallback) {
707 var args = validator_.validateArgs(arguments, [
708 {name: 'command', type: types_.STRING},
709 {name: 'data', type: types_.DICTIONARY},
710 {name: 'successCallback', type: types_.FUNCTION},
711 {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
715 command: args.command,
720 var replyId = ReplyCommandListener.addListener(successCallback);
722 nativeData.replyId = replyId;
723 nativeData.listenerId = ReplyCommandListener.listenerName;
724 var callback = function(result) {
725 if (native_.isFailure(result)) {
726 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
729 args.successCallback(native_.getResultObject(result));
732 native_.call('MediaControllerServerInfo_sendCommand', nativeData, callback);
735 MediaControllerServerInfo.prototype.addServerStatusChangeListener = function(listener) {
736 var args = validator_.validateArgs(arguments, [
737 {name: 'listener', type: types_.FUNCTION}
740 if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
741 var result = native_.callSync('MediaControllerServerInfo_addServerStatusChangeListener', {
742 listenerId: ServerInfoStatusListener.listenerName
744 if (native_.isFailure(result)) {
745 throw native_.getErrorObject(result);
748 return ServerInfoStatusListener.addServerInfoListener(args.listener, this.name);
751 MediaControllerServerInfo.prototype.removeServerStatusChangeListener = function(watchId) {
752 var args = validator_.validateArgs(arguments, [
753 {name: 'watchId', type: types_.LONG}
756 ServerInfoStatusListener.removeServerInfoListener(args.watchId);
758 if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
759 native_.callSync('MediaControllerServerInfo_removeServerStatusChangeListener');
763 MediaControllerServerInfo.prototype.addPlaybackInfoChangeListener = function(listener) {
764 var args = validator_.validateArgs(arguments, [{
766 type: types_.LISTENER,
769 'onshufflemodechanged',
770 'onrepeatmodechanged',
775 if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) {
776 var result = native_.callSync(
777 'MediaControllerServerInfo_addPlaybackInfoChangeListener', {
778 listenerId: ServerInfoPlaybackInfoListener.listenerName
780 if (native_.isFailure(result)) {
781 throw native_.getErrorObject(result);
785 return ServerInfoPlaybackInfoListener.addServerInfoListener(args.listener, this.name);
788 MediaControllerServerInfo.prototype.removePlaybackInfoChangeListener = function(watchId) {
789 var args = validator_.validateArgs(arguments, [
790 {name: 'watchId', type: types_.LONG}
793 ServerInfoPlaybackInfoListener.removeServerInfoListener(args.watchId);
795 if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) {
796 native_.callSync('MediaControllerServerInfo_removePlaybackInfoChangeListener');
801 exports = new MediaControllerManager();