Merge remote-tracking branch 'origin/tizen_3.0' into tizen_4.0
[platform/core/api/webapi-plugins.git] / src / mediacontroller / mediacontroller_api.js
index ac7f36c..be155e5 100755 (executable)
@@ -24,778 +24,918 @@ var types_ = validator_.Types;
 var native_ = new xwalk.utils.NativeManager(extension);
 
 function ListenerManager(native, listenerName, handle) {
-  this.listeners = {};
-  this.listenerNameToIds = {};
-  this.listenerIdToName = {};
-  this.nextId = 1;
-  this.nativeSet = false;
-  this.native = native;
-  this.listenerName = listenerName;
-  this.handle = handle || function(msg, listener, watchId) {};
+    this.listeners = {};
+    this.listenerNameToIds = {};
+    this.listenerIdToName = {};
+    this.nextId = 1;
+    this.nativeSet = false;
+    this.native = native;
+    this.listenerName = listenerName;
+    this.handle = handle || function(msg, listener, watchId) {};
 }
 
 ListenerManager.prototype.addListener = function(callback) {
-  var id = this.nextId;
-  if (!this.nativeSet) {
-    this.native.addListener(this.listenerName, function(msg) {
-      for (var watchId in this.listeners) {
-        if (this.listeners.hasOwnProperty(watchId)) {
-          var stop = this.handle(msg, this.listeners[watchId], watchId);
-          if (stop) {
-            break;
-          }
-        }
-      }
-    }.bind(this));
-
-    this.nativeSet = true;
-  }
+    var id = this.nextId;
+    if (!this.nativeSet) {
+        this.native.addListener(
+            this.listenerName,
+            function(msg) {
+                for (var watchId in this.listeners) {
+                    if (this.listeners.hasOwnProperty(watchId)) {
+                        var stop = this.handle(msg, this.listeners[watchId], watchId);
+                        if (stop) {
+                            break;
+                        }
+                    }
+                }
+            }.bind(this)
+        );
+
+        this.nativeSet = true;
+    }
 
-  this.listeners[id] = callback;
-  ++this.nextId;
-  return id;
+    this.listeners[id] = callback;
+    ++this.nextId;
+    return id;
 };
 
 ListenerManager.prototype.addServerInfoListener = function(callback, name) {
-  var id = this.nextId;
-  if (!this.nativeSet) {
-    this.native.addListener(this.listenerName, function(msg) {
-      if (this.listenerNameToIds.hasOwnProperty(msg.name)) {
-        var cbArray = this.listenerNameToIds[msg.name];
-        for (var i = 0; i < cbArray.length; ++i) {
-          var watchId = cbArray[i];
-          this.handle(msg, this.listeners[watchId], watchId);
-        }
-      }
-    }.bind(this));
-
-    this.nativeSet = true;
-  }
+    var id = this.nextId;
+    if (!this.nativeSet) {
+        this.native.addListener(
+            this.listenerName,
+            function(msg) {
+                if (this.listenerNameToIds.hasOwnProperty(msg.name)) {
+                    var cbArray = this.listenerNameToIds[msg.name];
+                    for (var i = 0; i < cbArray.length; ++i) {
+                        var watchId = cbArray[i];
+                        this.handle(msg, this.listeners[watchId], watchId);
+                    }
+                }
+            }.bind(this)
+        );
+
+        this.nativeSet = true;
+    }
 
-  this.listenerIdToName[id] = name;
-  if (this.listenerNameToIds[name]) {
-    this.listenerNameToIds[name].push(id);
-  } else {
-    this.listenerNameToIds[name] = [id];
-  }
-  this.listeners[id] = callback;
-  ++this.nextId;
-  return id;
+    this.listenerIdToName[id] = name;
+    if (this.listenerNameToIds[name]) {
+        this.listenerNameToIds[name].push(id);
+    } else {
+        this.listenerNameToIds[name] = [id];
+    }
+    this.listeners[id] = callback;
+    ++this.nextId;
+    return id;
 };
 
 ListenerManager.prototype.removeListener = function(watchId) {
-  if (this.listeners.hasOwnProperty(watchId)) {
-    delete this.listeners[watchId];
-  }
+    if (this.listeners.hasOwnProperty(watchId)) {
+        delete this.listeners[watchId];
+    }
 };
 
 function removeArrayElement(arr, elem) {
-  var index = arr.indexOf(elem);
-  if (index !== -1) {
-    arr.splice(index, 1);
-  }
+    var index = arr.indexOf(elem);
+    if (index !== -1) {
+        arr.splice(index, 1);
+    }
 }
 
 ListenerManager.prototype.removeServerInfoListener = function(watchId) {
-  this.removeListener(watchId);
-  if (this.listenerIdToName.hasOwnProperty(watchId)) {
-    var name = this.listenerIdToName[watchId];
-    removeArrayElement(this.listenerNameToIds[name], watchId);
-    delete this.listenerIdToName[watchId];
-  }
-};
-
-var ServerCommandListener = new ListenerManager(native_, '_ServerCommandListener', function(msg, listener) {
-  var data = undefined;
-  data = listener(msg.clientName, msg.command, msg.data);
-
-  if (type_.isUndefined(data)) {
-   data = null;
-  }
-
-  var nativeData = {
-    clientName: msg.clientName,
-    replyId: msg.replyId,
-    data: data
-  };
-
-  var result = native_.callSync('MediaControllerServer_replyCommand', nativeData);
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
-});
-
-var ReplyCommandListener = new ListenerManager(native_, '_ReplyCommandListener', function(msg, listener, watchId) {
-  if (msg.replyId === watchId) {
-    listener(msg.data);
     this.removeListener(watchId);
-    return true;
-  }
+    if (this.listenerIdToName.hasOwnProperty(watchId)) {
+        var name = this.listenerIdToName[watchId];
+        removeArrayElement(this.listenerNameToIds[name], watchId);
+        delete this.listenerIdToName[watchId];
+    }
+};
 
-  return false;
-});
+var ServerCommandListener = new ListenerManager(
+    native_,
+    '_ServerCommandListener',
+    function(msg, listener) {
+        var data = undefined;
+        data = listener(msg.clientName, msg.command, msg.data);
 
-var ServerPlaybackInfoListener = new ListenerManager(native_, '_ServerPlaybackInfoListener', function(msg, listener) {
-  if (msg.action === 'onplaybackstaterequest') {
-    native_.callIfPossible(listener[msg.action], msg.state);
-  }
-  if (msg.action === 'onplaybackpositionrequest') {
-    native_.callIfPossible(listener[msg.action], msg.position);
-  }
-  if (msg.action === 'onshufflemoderequest' || msg.action === 'onrepeatmoderequest') {
-    native_.callIfPossible(listener[msg.action], msg.mode);
-  }
-});
+        if (type_.isUndefined(data)) {
+            data = null;
+        }
 
-var ServerInfoStatusListener = new ListenerManager(native_, '_ServerInfoStatusListener', function(msg, listener) {
-  listener(msg.state);
-});
+        var nativeData = {
+            clientName: msg.clientName,
+            replyId: msg.replyId,
+            data: data
+        };
+
+        var result = native_.callSync('MediaControllerServer_replyCommand', nativeData);
+        if (native_.isFailure(result)) {
+            throw native_.getErrorObject(result);
+        }
+    }
+);
+
+var ReplyCommandListener = new ListenerManager(native_, '_ReplyCommandListener', function(
+    msg,
+    listener,
+    watchId
+) {
+    if (msg.replyId === watchId) {
+        listener(msg.data);
+        this.removeListener(watchId);
+        return true;
+    }
 
-var ServerInfoPlaybackInfoListener = new ListenerManager(native_, '_ServerInfoPlaybackInfoListener', function(msg, listener) {
-  if (msg.action === 'onplaybackchanged') {
-    listener[msg.action](msg.state, msg.position);
-  }
-  if (msg.action === 'onshufflemodechanged' || msg.action === 'onrepeatmodechanged') {
-    listener[msg.action](msg.mode);
-  }
-  if (msg.action === 'onmetadatachanged') {
-    listener[msg.action](new MediaControllerMetadata(msg.metadata));
-  }
+    return false;
 });
 
+var ServerPlaybackInfoListener = new ListenerManager(
+    native_,
+    '_ServerPlaybackInfoListener',
+    function(msg, listener) {
+        if (msg.action === 'onplaybackstaterequest') {
+            native_.callIfPossible(listener[msg.action], msg.state);
+        }
+        if (msg.action === 'onplaybackpositionrequest') {
+            native_.callIfPossible(listener[msg.action], msg.position);
+        }
+        if (
+            msg.action === 'onshufflemoderequest' ||
+            msg.action === 'onrepeatmoderequest'
+        ) {
+            native_.callIfPossible(listener[msg.action], msg.mode);
+        }
+    }
+);
+
+var ServerInfoStatusListener = new ListenerManager(
+    native_,
+    '_ServerInfoStatusListener',
+    function(msg, listener) {
+        listener(msg.state);
+    }
+);
+
+var ServerInfoPlaybackInfoListener = new ListenerManager(
+    native_,
+    '_ServerInfoPlaybackInfoListener',
+    function(msg, listener) {
+        if (msg.action === 'onplaybackchanged') {
+            listener[msg.action](msg.state, msg.position);
+        }
+        if (
+            msg.action === 'onshufflemodechanged' ||
+            msg.action === 'onrepeatmodechanged'
+        ) {
+            listener[msg.action](msg.mode);
+        }
+        if (msg.action === 'onmetadatachanged') {
+            listener[msg.action](new MediaControllerMetadata(msg.metadata));
+        }
+    }
+);
+
 var EditManager = function() {
-  this.isAllowed = false;
+    this.isAllowed = false;
 };
 
 EditManager.prototype.allow = function() {
-  this.isAllowed = true;
+    this.isAllowed = true;
 };
 
 EditManager.prototype.disallow = function() {
-  this.isAllowed = false;
+    this.isAllowed = false;
 };
 
 var edit_ = new EditManager();
 
-
 var MediaControllerServerState = {
-  ACTIVE: 'ACTIVE',
-  INACTIVE: 'INACTIVE'
+    ACTIVE: 'ACTIVE',
+    INACTIVE: 'INACTIVE'
 };
 
 var MediaControllerPlaybackState = {
-  PLAY: 'PLAY',
-  PAUSE: 'PAUSE',
-  STOP: 'STOP',
-  NEXT: 'NEXT',
-  PREV: 'PREV',
-  FORWARD: 'FORWARD',
-  REWIND: 'REWIND'
+    PLAY: 'PLAY',
+    PAUSE: 'PAUSE',
+    STOP: 'STOP',
+    NEXT: 'NEXT',
+    PREV: 'PREV',
+    FORWARD: 'FORWARD',
+    REWIND: 'REWIND'
 };
 
-
 function MediaControllerManager() {}
 
 MediaControllerManager.prototype.getClient = function() {
-  var result = native_.callSync('MediaControllerManager_getClient', {});
+    var result = native_.callSync('MediaControllerManager_getClient', {});
 
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
 
-  return new MediaControllerClient(native_.getResultObject(result));
+    return new MediaControllerClient(native_.getResultObject(result));
 };
 
 MediaControllerManager.prototype.createServer = function() {
-  var result = native_.callSync('MediaControllerManager_createServer', {});
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
+    var result = native_.callSync('MediaControllerManager_createServer', {});
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
 
-  return new MediaControllerServer(native_.getResultObject(result));
+    return new MediaControllerServer(native_.getResultObject(result));
 };
 
-
 var MediaControllerMetadata = function(data) {
-  var _title = '';
-  var _artist = '';
-  var _album = '';
-  var _author = '';
-  var _genre = '';
-  var _duration = '';
-  var _date = '';
-  var _copyright = '';
-  var _description = '';
-  var _trackNum = '';
-  var _picture = '';
-  Object.defineProperties(this, {
-    title: {
-      get: function() {return _title;},
-      set: function(v) {_title = converter_.toString(v)},
-      enumerable: true
-    },
-    artist: {
-      get: function() {return _artist;},
-      set: function(v) {_artist = converter_.toString(v)},
-      enumerable: true
-    },
-    album: {
-      get: function() {return _album;},
-      set: function(v) {_album = converter_.toString(v)},
-      enumerable: true
-    },
-    author: {
-      get: function() {return _author;},
-      set: function(v) {_author = converter_.toString(v)},
-      enumerable: true
-    },
-    genre: {
-      get: function() {return _genre;},
-      set: function(v) {_genre = converter_.toString(v)},
-      enumerable: true
-    },
-    duration: {
-      get: function() {return _duration;},
-      set: function(v) {_duration = converter_.toString(v)},
-      enumerable: true
-    },
-    date: {
-      get: function() {return _date;},
-      set: function(v) {_date = converter_.toString(v)},
-      enumerable: true
-    },
-    copyright: {
-      get: function() {return _copyright;},
-      set: function(v) {_copyright = converter_.toString(v)},
-      enumerable: true
-    },
-    description: {
-      get: function() {return _description;},
-      set: function(v) {_description = converter_.toString(v)},
-      enumerable: true
-    },
-    trackNum: {
-      get: function() {return _trackNum;},
-      set: function(v) {_trackNum = converter_.toString(v)},
-      enumerable: true
-    },
-    picture: {
-      get: function() {return _picture;},
-      set: function(v) {_picture = converter_.toString(v)},
-      enumerable: true
-    }
-  });
+    var _title = '';
+    var _artist = '';
+    var _album = '';
+    var _author = '';
+    var _genre = '';
+    var _duration = '';
+    var _date = '';
+    var _copyright = '';
+    var _description = '';
+    var _trackNum = '';
+    var _picture = '';
+    Object.defineProperties(this, {
+        title: {
+            get: function() {
+                return _title;
+            },
+            set: function(v) {
+                _title = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        artist: {
+            get: function() {
+                return _artist;
+            },
+            set: function(v) {
+                _artist = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        album: {
+            get: function() {
+                return _album;
+            },
+            set: function(v) {
+                _album = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        author: {
+            get: function() {
+                return _author;
+            },
+            set: function(v) {
+                _author = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        genre: {
+            get: function() {
+                return _genre;
+            },
+            set: function(v) {
+                _genre = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        duration: {
+            get: function() {
+                return _duration;
+            },
+            set: function(v) {
+                _duration = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        date: {
+            get: function() {
+                return _date;
+            },
+            set: function(v) {
+                _date = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        copyright: {
+            get: function() {
+                return _copyright;
+            },
+            set: function(v) {
+                _copyright = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        description: {
+            get: function() {
+                return _description;
+            },
+            set: function(v) {
+                _description = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        trackNum: {
+            get: function() {
+                return _trackNum;
+            },
+            set: function(v) {
+                _trackNum = converter_.toString(v);
+            },
+            enumerable: true
+        },
+        picture: {
+            get: function() {
+                return _picture;
+            },
+            set: function(v) {
+                _picture = converter_.toString(v);
+            },
+            enumerable: true
+        }
+    });
 
-  if (data instanceof _global.Object) {
-    for (var prop in data) {
-      if (data.hasOwnProperty(prop) && this.hasOwnProperty(prop)) {
-        this[prop] = data[prop];
-      }
+    if (data instanceof _global.Object) {
+        for (var prop in data) {
+            if (data.hasOwnProperty(prop) && this.hasOwnProperty(prop)) {
+                this[prop] = data[prop];
+            }
+        }
     }
-  }
 };
 
 var MediaControllerPlaybackInfo = function(data) {
-  var _state = 'STOP';
-  var _position = 0;
-  var _shuffleMode = false;
-  var _repeatMode = false;
-  var _metadata = new MediaControllerMetadata();
-  Object.defineProperties(this, {
-    state: {
-      get: function() {
-        return _state;
-      },
-      set: function(v) {
-        _state = edit_.isAllowed && v ? v : _state;
-      },
-      enumerable: true
-    },
-    position: {
-      get: function() {
-        return _position;
-      },
-      set: function(v) {
-        _position = edit_.isAllowed ? converter_.toLong(v) : _position;
-      },
-      enumerable: true
-    },
-    shuffleMode: {
-      get: function() {
-        return _shuffleMode;
-      },
-      set: function(v) {
-        _shuffleMode = edit_.isAllowed ? converter_.toBoolean(v) : _shuffleMode;
-      },
-      enumerable: true
-    },
-    repeatMode: {
-      get: function() {
-        return _repeatMode;
-      },
-      set: function(v) {
-        _repeatMode = edit_.isAllowed ? converter_.toBoolean(v) : _repeatMode;
-      },
-      enumerable: true
-    },
-    metadata: {
-      get: function() {
-        return _metadata;
-      },
-      set: function(v) {
-        _metadata = edit_.isAllowed && v ? new MediaControllerMetadata(v) : _metadata;
-      },
-      enumerable: true
-    }
-  });
+    var _state = 'STOP';
+    var _position = 0;
+    var _shuffleMode = false;
+    var _repeatMode = false;
+    var _metadata = new MediaControllerMetadata();
+    Object.defineProperties(this, {
+        state: {
+            get: function() {
+                return _state;
+            },
+            set: function(v) {
+                _state = edit_.isAllowed && v ? v : _state;
+            },
+            enumerable: true
+        },
+        position: {
+            get: function() {
+                return _position;
+            },
+            set: function(v) {
+                _position = edit_.isAllowed ? converter_.toLong(v) : _position;
+            },
+            enumerable: true
+        },
+        shuffleMode: {
+            get: function() {
+                return _shuffleMode;
+            },
+            set: function(v) {
+                _shuffleMode = edit_.isAllowed ? converter_.toBoolean(v) : _shuffleMode;
+            },
+            enumerable: true
+        },
+        repeatMode: {
+            get: function() {
+                return _repeatMode;
+            },
+            set: function(v) {
+                _repeatMode = edit_.isAllowed ? converter_.toBoolean(v) : _repeatMode;
+            },
+            enumerable: true
+        },
+        metadata: {
+            get: function() {
+                return _metadata;
+            },
+            set: function(v) {
+                _metadata =
+                    edit_.isAllowed && v ? new MediaControllerMetadata(v) : _metadata;
+            },
+            enumerable: true
+        }
+    });
 
-  if (data instanceof _global.Object) {
-    for (var prop in data) {
-      if (data.hasOwnProperty(prop) && this.hasOwnProperty(prop)) {
-        this[prop] = data[prop];
-      }
+    if (data instanceof _global.Object) {
+        for (var prop in data) {
+            if (data.hasOwnProperty(prop) && this.hasOwnProperty(prop)) {
+                this[prop] = data[prop];
+            }
+        }
     }
-  }
 };
 
 function MediaControllerServer(data) {
-  Object.defineProperties(this, {
-    playbackInfo: {
-      value: new MediaControllerPlaybackInfo(data),
-      writable: false,
-      enumerable: true
-    }
-  });
+    Object.defineProperties(this, {
+        playbackInfo: {
+            value: new MediaControllerPlaybackInfo(data),
+            writable: false,
+            enumerable: true
+        }
+    });
 }
 
 MediaControllerServer.prototype.updatePlaybackState = function(state) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'state', type: types_.ENUM, values: Object.keys(MediaControllerPlaybackState)}
-  ]);
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'state',
+            type: types_.ENUM,
+            values: Object.keys(MediaControllerPlaybackState)
+        }
+    ]);
 
-  var data = {
-    state: args.state
-  };
+    var data = {
+        state: args.state
+    };
 
-  var result = native_.callSync('MediaControllerServer_updatePlaybackState', data);
+    var result = native_.callSync('MediaControllerServer_updatePlaybackState', data);
 
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
 
-  edit_.allow();
-  this.playbackInfo.state = args.state;
-  edit_.disallow();
+    edit_.allow();
+    this.playbackInfo.state = args.state;
+    edit_.disallow();
 };
 
 MediaControllerServer.prototype.updatePlaybackPosition = function(position) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'position', type: types_.UNSIGNED_LONG_LONG}
-  ]);
+    var args = validator_.validateArgs(arguments, [
+        { name: 'position', type: types_.UNSIGNED_LONG_LONG }
+    ]);
 
-  var data = {
-    position: args.position
-  };
+    var data = {
+        position: args.position
+    };
 
-  var result = native_.callSync('MediaControllerServer_updatePlaybackPosition', data);
+    var result = native_.callSync('MediaControllerServer_updatePlaybackPosition', data);
 
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
 
-  edit_.allow();
-  this.playbackInfo.position = args.position;
-  edit_.disallow();
+    edit_.allow();
+    this.playbackInfo.position = args.position;
+    edit_.disallow();
 };
 
 MediaControllerServer.prototype.updateShuffleMode = function(mode) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'mode', type: types_.BOOLEAN}
-  ]);
-
-  var data = {
-    mode: args.mode
-  };
-
-  var result = native_.callSync('MediaControllerServer_updateShuffleMode', data);
-
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
-
-  edit_.allow();
-  this.playbackInfo.shuffleMode = args.mode;
-  edit_.disallow();
-};
-
-MediaControllerServer.prototype.updateRepeatMode = function(mode) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'mode', type: types_.BOOLEAN}
-  ]);
+    var args = validator_.validateArgs(arguments, [
+        { name: 'mode', type: types_.BOOLEAN }
+    ]);
 
-  var data = {
-    mode: args.mode
-  };
+    var data = {
+        mode: args.mode
+    };
 
-  var result = native_.callSync('MediaControllerServer_updateRepeatMode', data);
+    var result = native_.callSync('MediaControllerServer_updateShuffleMode', data);
 
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
-
-  edit_.allow();
-  this.playbackInfo.repeatMode = args.mode;
-  edit_.disallow();
-};
-
-MediaControllerServer.prototype.updateMetadata = function(metadata) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'metadata', type: types_.PLATFORM_OBJECT, values: MediaControllerMetadata}
-  ]);
-
-  var data = {
-    metadata: args.metadata
-  };
-
-  var result = native_.callSync('MediaControllerServer_updateMetadata', data);
-
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
-
-  edit_.allow();
-  this.playbackInfo.metadata = args.metadata;
-  edit_.disallow();
-};
-
-MediaControllerServer.prototype.addChangeRequestPlaybackInfoListener = function(listener) {
-  var args = validator_.validateArgs(arguments, [{
-    name: 'listener',
-    type: types_.LISTENER,
-    values: [
-      'onplaybackstaterequest',
-      'onplaybackpositionrequest',
-      'onshufflemoderequest',
-      'onrepeatmoderequest'
-    ]
-  }]);
-
-  if (type_.isEmptyObject(ServerPlaybackInfoListener.listeners)) {
-    var result = native_.callSync('MediaControllerServer_addChangeRequestPlaybackInfoListener', {
-      listenerId: ServerPlaybackInfoListener.listenerName
-    });
     if (native_.isFailure(result)) {
-      throw native_.getErrorObject(result);
+        throw native_.getErrorObject(result);
     }
-  }
 
-  return ServerPlaybackInfoListener.addListener(args.listener);
+    edit_.allow();
+    this.playbackInfo.shuffleMode = args.mode;
+    edit_.disallow();
 };
 
-MediaControllerServer.prototype.removeChangeRequestPlaybackInfoListener = function(watchId) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'watchId', type: types_.LONG}
-  ]);
+MediaControllerServer.prototype.updateRepeatMode = function(mode) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'mode', type: types_.BOOLEAN }
+    ]);
 
-  ServerPlaybackInfoListener.removeListener(args.watchId);
+    var data = {
+        mode: args.mode
+    };
 
-  if (type_.isEmptyObject(ServerPlaybackInfoListener.listeners)) {
-    native_.callSync('MediaControllerServer_removeCommandListener');
-  }
-};
+    var result = native_.callSync('MediaControllerServer_updateRepeatMode', data);
 
-MediaControllerServer.prototype.addCommandListener = function(listener) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'listener', type: types_.FUNCTION}
-  ]);
-
-  if (type_.isEmptyObject(ServerCommandListener.listeners)) {
-    var result = native_.callSync('MediaControllerServer_addCommandListener', {
-      listenerId: ServerCommandListener.listenerName
-    });
     if (native_.isFailure(result)) {
-      throw native_.getErrorObject(result);
+        throw native_.getErrorObject(result);
     }
-  }
 
-  return ServerCommandListener.addListener(args.listener);
-};
-
-MediaControllerServer.prototype.removeCommandListener = function(watchId) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'watchId', type: types_.LONG}
-  ]);
-
-  ServerCommandListener.removeListener(args.watchId);
-
-  if (type_.isEmptyObject(ServerCommandListener.listeners)) {
-    native_.callSync('MediaControllerServer_removeCommandListener');
-  }
+    edit_.allow();
+    this.playbackInfo.repeatMode = args.mode;
+    edit_.disallow();
 };
 
+MediaControllerServer.prototype.updateMetadata = function(metadata) {
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'metadata',
+            type: types_.PLATFORM_OBJECT,
+            values: MediaControllerMetadata
+        }
+    ]);
 
-function MediaControllerClient() {}
+    var data = {
+        metadata: args.metadata
+    };
 
-MediaControllerClient.prototype.findServers = function(successCallback, errorCallback) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'successCallback', type: types_.FUNCTION},
-    {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
-  ]);
+    var result = native_.callSync('MediaControllerServer_updateMetadata', data);
 
-  var callback = function(result) {
     if (native_.isFailure(result)) {
-      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
-      return;
+        throw native_.getErrorObject(result);
     }
-    var info = [];
-    var data = native_.getResultObject(result);
-    for (var i = 0; i < data.length; i++) {
-      info.push(new MediaControllerServerInfo(data[i]));
+
+    edit_.allow();
+    this.playbackInfo.metadata = args.metadata;
+    edit_.disallow();
+};
+
+MediaControllerServer.prototype.addChangeRequestPlaybackInfoListener = function(
+    listener
+) {
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'listener',
+            type: types_.LISTENER,
+            values: [
+                'onplaybackstaterequest',
+                'onplaybackpositionrequest',
+                'onshufflemoderequest',
+                'onrepeatmoderequest'
+            ]
+        }
+    ]);
+
+    if (type_.isEmptyObject(ServerPlaybackInfoListener.listeners)) {
+        var result = native_.callSync(
+            'MediaControllerServer_addChangeRequestPlaybackInfoListener',
+            {
+                listenerId: ServerPlaybackInfoListener.listenerName
+            }
+        );
+        if (native_.isFailure(result)) {
+            throw native_.getErrorObject(result);
+        }
     }
-    native_.callIfPossible(args.successCallback, info);
-  };
 
-  native_.call('MediaControllerClient_findServers', {}, callback);
+    return ServerPlaybackInfoListener.addListener(args.listener);
 };
 
-MediaControllerClient.prototype.getLatestServerInfo = function() {
-
-  var result = native_.callSync('MediaControllerClient_getLatestServerInfo', {});
+MediaControllerServer.prototype.removeChangeRequestPlaybackInfoListener = function(
+    watchId
+) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'watchId', type: types_.LONG }
+    ]);
 
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
+    ServerPlaybackInfoListener.removeListener(args.watchId);
 
-  var serverInfo = native_.getResultObject(result);
-  if (serverInfo) {
-    if ('NONE' === serverInfo.state) {
-      serverInfo.state = 'INACTIVE';
+    if (type_.isEmptyObject(ServerPlaybackInfoListener.listeners)) {
+        native_.callSync('MediaControllerServer_removeCommandListener');
     }
-    serverInfo = new MediaControllerServerInfo(serverInfo);
-  }
-  return serverInfo;
 };
 
+MediaControllerServer.prototype.addCommandListener = function(listener) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'listener', type: types_.FUNCTION }
+    ]);
 
-function MediaControllerServerInfo(data) {
-  Object.defineProperties(this, {
-    name: {
-      value: data.name,
-      writable: false,
-      enumerable: true
-    },
-    state: {
-      value: data.state,
-      writable: false,
-      enumerable: true
-    },
-    playbackInfo: {
-      get: function () {
-        var result = native_.callSync('MediaControllerClient_getPlaybackInfo', {name: this.name});
+    if (type_.isEmptyObject(ServerCommandListener.listeners)) {
+        var result = native_.callSync('MediaControllerServer_addCommandListener', {
+            listenerId: ServerCommandListener.listenerName
+        });
         if (native_.isFailure(result)) {
-          throw new native_.getErrorObject(result);
+            throw native_.getErrorObject(result);
         }
-        edit_.allow();
-        var data = native_.getResultObject(result);
-        var playbackInfo = new MediaControllerPlaybackInfo(data);
-        edit_.disallow();
-
-        return playbackInfo;
-      }.bind(this),
-      set: function() {},
-      enumerable: true
     }
-  });
-}
 
+    return ServerCommandListener.addListener(args.listener);
+};
 
-MediaControllerServerInfo.prototype.sendPlaybackState = function(state, successCallback, errorCallback) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'state', type: types_.ENUM, values: Object.keys(MediaControllerPlaybackState)},
-    {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
-    {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
-  ]);
+MediaControllerServer.prototype.removeCommandListener = function(watchId) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'watchId', type: types_.LONG }
+    ]);
 
-  var data = {
-    name: this.name,
-    state: args.state
-  };
+    ServerCommandListener.removeListener(args.watchId);
 
-  var callback = function(result) {
-    if (native_.isFailure(result)) {
-      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
-      return;
+    if (type_.isEmptyObject(ServerCommandListener.listeners)) {
+        native_.callSync('MediaControllerServer_removeCommandListener');
     }
-    native_.callIfPossible(args.successCallback);
-  };
-
-  native_.call('MediaControllerServerInfo_sendPlaybackState', data, callback);
 };
 
-MediaControllerServerInfo.prototype.sendPlaybackPosition = function(position, successCallback, errorCallback) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'position', type: types_.LONG_LONG},
-    {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
-    {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
-  ]);
-
-  if (args.position < 0) {
-    throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
-  }
+function MediaControllerClient() {}
 
-  var callback = function(result) {
-    if (native_.isFailure(result)) {
-      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
-      return;
-    }
-    native_.callIfPossible(args.successCallback);
-  };
+MediaControllerClient.prototype.findServers = function(successCallback, errorCallback) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'successCallback', type: types_.FUNCTION },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
+    ]);
 
-  var data = {
-    position: args.position,
-    name: this.name
-  };
+    var callback = function(result) {
+        if (native_.isFailure(result)) {
+            native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+            return;
+        }
+        var info = [];
+        var data = native_.getResultObject(result);
+        for (var i = 0; i < data.length; i++) {
+            info.push(new MediaControllerServerInfo(data[i]));
+        }
+        native_.callIfPossible(args.successCallback, info);
+    };
 
-  native_.call('MediaControllerServerInfo_sendPlaybackPosition', data, callback);
+    native_.call('MediaControllerClient_findServers', {}, callback);
 };
 
-MediaControllerServerInfo.prototype.sendShuffleMode = function(mode, successCallback, errorCallback) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'mode', type: types_.BOOLEAN},
-    {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
-    {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
-  ]);
+MediaControllerClient.prototype.getLatestServerInfo = function() {
+    var result = native_.callSync('MediaControllerClient_getLatestServerInfo', {});
 
-  var callback = function(result) {
     if (native_.isFailure(result)) {
-      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
-      return;
+        throw native_.getErrorObject(result);
     }
-    native_.callIfPossible(args.successCallback);
-  };
 
-  var data = {
-    mode: args.mode,
-    name: this.name
-  };
-  native_.call('MediaControllerServerInfo_sendShuffleMode', data, callback);
+    var serverInfo = native_.getResultObject(result);
+    if (serverInfo) {
+        if ('NONE' === serverInfo.state) {
+            serverInfo.state = 'INACTIVE';
+        }
+        serverInfo = new MediaControllerServerInfo(serverInfo);
+    }
+    return serverInfo;
 };
 
-MediaControllerServerInfo.prototype.sendRepeatMode = function(mode, successCallback, errorCallback) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'mode', type: types_.BOOLEAN},
-    {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true},
-    {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
-  ]);
+function MediaControllerServerInfo(data) {
+    Object.defineProperties(this, {
+        name: {
+            value: data.name,
+            writable: false,
+            enumerable: true
+        },
+        state: {
+            value: data.state,
+            writable: false,
+            enumerable: true
+        },
+        playbackInfo: {
+            get: function() {
+                var result = native_.callSync('MediaControllerClient_getPlaybackInfo', {
+                    name: this.name
+                });
+                if (native_.isFailure(result)) {
+                    throw new native_.getErrorObject(result);
+                }
+                edit_.allow();
+                var data = native_.getResultObject(result);
+                var playbackInfo = new MediaControllerPlaybackInfo(data);
+                edit_.disallow();
+
+                return playbackInfo;
+            }.bind(this),
+            set: function() {},
+            enumerable: true
+        }
+    });
+}
 
-  var callback = function(result) {
-    if (native_.isFailure(result)) {
-      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
-      return;
-    }
-    native_.callIfPossible(args.successCallback);
-  };
-
-  var data = {
-    mode: args.mode,
-    name: this.name
-  };
-  native_.call('MediaControllerServerInfo_sendRepeatMode', data, callback);
-};
-
-MediaControllerServerInfo.prototype.sendCommand = function(command, data, successCallback, errorCallback) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'command', type: types_.STRING},
-    {name: 'data', type: types_.DICTIONARY},
-    {name: 'successCallback', type: types_.FUNCTION},
-    {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
-  ]);
-
-  var nativeData = {
-    command: args.command,
-    data: args.data,
-    name: this.name
-  };
-
-  var replyId = ReplyCommandListener.addListener(successCallback);
-
-  nativeData.replyId = replyId;
-  nativeData.listenerId = ReplyCommandListener.listenerName;
-  var callback = function(result) {
-    if (native_.isFailure(result)) {
-      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
-      return;
+MediaControllerServerInfo.prototype.sendPlaybackState = function(
+    state,
+    successCallback,
+    errorCallback
+) {
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'state',
+            type: types_.ENUM,
+            values: Object.keys(MediaControllerPlaybackState)
+        },
+        {
+            name: 'successCallback',
+            type: types_.FUNCTION,
+            optional: true,
+            nullable: true
+        },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
+    ]);
+
+    var data = {
+        name: this.name,
+        state: args.state
+    };
+
+    var callback = function(result) {
+        if (native_.isFailure(result)) {
+            native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+            return;
+        }
+        native_.callIfPossible(args.successCallback);
+    };
+
+    native_.call('MediaControllerServerInfo_sendPlaybackState', data, callback);
+};
+
+MediaControllerServerInfo.prototype.sendPlaybackPosition = function(
+    position,
+    successCallback,
+    errorCallback
+) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'position', type: types_.LONG_LONG },
+        {
+            name: 'successCallback',
+            type: types_.FUNCTION,
+            optional: true,
+            nullable: true
+        },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
+    ]);
+
+    if (args.position < 0) {
+        throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
     }
-    args.successCallback(native_.getResultObject(result));
-  };
 
-  native_.call('MediaControllerServerInfo_sendCommand', nativeData, callback);
+    var callback = function(result) {
+        if (native_.isFailure(result)) {
+            native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+            return;
+        }
+        native_.callIfPossible(args.successCallback);
+    };
+
+    var data = {
+        position: args.position,
+        name: this.name
+    };
+
+    native_.call('MediaControllerServerInfo_sendPlaybackPosition', data, callback);
+};
+
+MediaControllerServerInfo.prototype.sendShuffleMode = function(
+    mode,
+    successCallback,
+    errorCallback
+) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'mode', type: types_.BOOLEAN },
+        {
+            name: 'successCallback',
+            type: types_.FUNCTION,
+            optional: true,
+            nullable: true
+        },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
+    ]);
+
+    var callback = function(result) {
+        if (native_.isFailure(result)) {
+            native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+            return;
+        }
+        native_.callIfPossible(args.successCallback);
+    };
+
+    var data = {
+        mode: args.mode,
+        name: this.name
+    };
+    native_.call('MediaControllerServerInfo_sendShuffleMode', data, callback);
+};
+
+MediaControllerServerInfo.prototype.sendRepeatMode = function(
+    mode,
+    successCallback,
+    errorCallback
+) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'mode', type: types_.BOOLEAN },
+        {
+            name: 'successCallback',
+            type: types_.FUNCTION,
+            optional: true,
+            nullable: true
+        },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
+    ]);
+
+    var callback = function(result) {
+        if (native_.isFailure(result)) {
+            native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+            return;
+        }
+        native_.callIfPossible(args.successCallback);
+    };
+
+    var data = {
+        mode: args.mode,
+        name: this.name
+    };
+    native_.call('MediaControllerServerInfo_sendRepeatMode', data, callback);
+};
+
+MediaControllerServerInfo.prototype.sendCommand = function(
+    command,
+    data,
+    successCallback,
+    errorCallback
+) {
+    var args = validator_.validateArgs(arguments, [
+        { name: 'command', type: types_.STRING },
+        { name: 'data', type: types_.DICTIONARY },
+        { name: 'successCallback', type: types_.FUNCTION },
+        { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
+    ]);
+
+    var nativeData = {
+        command: args.command,
+        data: args.data,
+        name: this.name
+    };
+
+    var replyId = ReplyCommandListener.addListener(successCallback);
+
+    nativeData.replyId = replyId;
+    nativeData.listenerId = ReplyCommandListener.listenerName;
+    var callback = function(result) {
+        if (native_.isFailure(result)) {
+            native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+            return;
+        }
+        args.successCallback(native_.getResultObject(result));
+    };
+
+    native_.call('MediaControllerServerInfo_sendCommand', nativeData, callback);
 };
 
 MediaControllerServerInfo.prototype.addServerStatusChangeListener = function(listener) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'listener', type: types_.FUNCTION}
-  ]);
-
-  if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
-    var result = native_.callSync('MediaControllerServerInfo_addServerStatusChangeListener', {
-      listenerId: ServerInfoStatusListener.listenerName
-    });
-    if (native_.isFailure(result)) {
-      throw native_.getErrorObject(result);
+    var args = validator_.validateArgs(arguments, [
+        { name: 'listener', type: types_.FUNCTION }
+    ]);
+
+    if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
+        var result = native_.callSync(
+            'MediaControllerServerInfo_addServerStatusChangeListener',
+            {
+                listenerId: ServerInfoStatusListener.listenerName
+            }
+        );
+        if (native_.isFailure(result)) {
+            throw native_.getErrorObject(result);
+        }
     }
-  }
-  return ServerInfoStatusListener.addServerInfoListener(args.listener, this.name);
+    return ServerInfoStatusListener.addServerInfoListener(args.listener, this.name);
 };
 
 MediaControllerServerInfo.prototype.removeServerStatusChangeListener = function(watchId) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'watchId', type: types_.LONG}
-  ]);
+    var args = validator_.validateArgs(arguments, [
+        { name: 'watchId', type: types_.LONG }
+    ]);
 
-  ServerInfoStatusListener.removeServerInfoListener(args.watchId);
+    ServerInfoStatusListener.removeServerInfoListener(args.watchId);
 
-  if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
-    native_.callSync('MediaControllerServerInfo_removeServerStatusChangeListener');
-  }
+    if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
+        native_.callSync('MediaControllerServerInfo_removeServerStatusChangeListener');
+    }
 };
 
 MediaControllerServerInfo.prototype.addPlaybackInfoChangeListener = function(listener) {
-  var args = validator_.validateArgs(arguments, [{
-    name: 'listener',
-    type: types_.LISTENER,
-    values: [
-      'onplaybackchanged',
-      'onshufflemodechanged',
-      'onrepeatmodechanged',
-      'onmetadatachanged'
-    ]
-  }]);
-
-  if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) {
-    var result = native_.callSync(
-        'MediaControllerServerInfo_addPlaybackInfoChangeListener', {
-          listenerId: ServerInfoPlaybackInfoListener.listenerName
-        });
-    if (native_.isFailure(result)) {
-      throw native_.getErrorObject(result);
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'listener',
+            type: types_.LISTENER,
+            values: [
+                'onplaybackchanged',
+                'onshufflemodechanged',
+                'onrepeatmodechanged',
+                'onmetadatachanged'
+            ]
+        }
+    ]);
+
+    if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) {
+        var result = native_.callSync(
+            'MediaControllerServerInfo_addPlaybackInfoChangeListener',
+            {
+                listenerId: ServerInfoPlaybackInfoListener.listenerName
+            }
+        );
+        if (native_.isFailure(result)) {
+            throw native_.getErrorObject(result);
+        }
     }
-  }
 
-  return ServerInfoPlaybackInfoListener.addServerInfoListener(args.listener, this.name);
+    return ServerInfoPlaybackInfoListener.addServerInfoListener(args.listener, this.name);
 };
 
 MediaControllerServerInfo.prototype.removePlaybackInfoChangeListener = function(watchId) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'watchId', type: types_.LONG}
-  ]);
+    var args = validator_.validateArgs(arguments, [
+        { name: 'watchId', type: types_.LONG }
+    ]);
 
-  ServerInfoPlaybackInfoListener.removeServerInfoListener(args.watchId);
+    ServerInfoPlaybackInfoListener.removeServerInfoListener(args.watchId);
 
-  if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) {
-    native_.callSync('MediaControllerServerInfo_removePlaybackInfoChangeListener');
-  }
+    if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) {
+        native_.callSync('MediaControllerServerInfo_removePlaybackInfoChangeListener');
+    }
 };
 
-
 exports = new MediaControllerManager();