[MediaController] Fixing client's listeners 24/147124/1
authorSzymon Jastrzebski <s.jastrzebsk@partner.samsung.com>
Thu, 31 Aug 2017 11:54:52 +0000 (13:54 +0200)
committerSzymon Jastrzebski <s.jastrzebsk@partner.samsung.com>
Thu, 31 Aug 2017 11:54:52 +0000 (13:54 +0200)
Listeners, which are registered per MediaControllerServerInfo object
work globally. This causes to invoke the registered listener for every
change in any server.

[Verification] TCT MC 100% pass rate.

Change-Id: I950e047b07a16d351959fe98e47ea1ca7ff68518
Saaigned-off-by: Szymon Jastrzebski <s.jastrzebsk@partner.samsung.com>
src/mediacontroller/mediacontroller_api.js
src/mediacontroller/mediacontroller_client.cc

index c5a8197..4852464 100755 (executable)
@@ -34,6 +34,8 @@ var internal_commands_ = {
 
 function ListenerManager(native, listenerName, handle) {
   this.listeners = {};
+  this.listenerNameToIds = {};
+  this.listenerIdToName = {};
   this.nextId = 1;
   this.nativeSet = false;
   this.native = native;
@@ -63,12 +65,55 @@ ListenerManager.prototype.addListener = function(callback) {
   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;
+  }
+
+  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];
   }
 };
 
+function removeArrayElement(arr, elem) {
+  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);
@@ -718,8 +763,7 @@ MediaControllerServerInfo.prototype.addServerStatusChangeListener = function(lis
       throw native_.getErrorObject(result);
     }
   }
-
-  return ServerInfoStatusListener.addListener(args.listener);
+  return ServerInfoStatusListener.addServerInfoListener(args.listener, this.name);
 };
 
 MediaControllerServerInfo.prototype.removeServerStatusChangeListener = function(watchId) {
@@ -727,7 +771,7 @@ MediaControllerServerInfo.prototype.removeServerStatusChangeListener = function(
     {name: 'watchId', type: types_.LONG}
   ]);
 
-  ServerInfoStatusListener.removeListener(args.watchId);
+  ServerInfoStatusListener.removeServerInfoListener(args.watchId);
 
   if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
     native_.callSync('MediaControllerServerInfo_removeServerStatusChangeListener');
@@ -756,7 +800,7 @@ MediaControllerServerInfo.prototype.addPlaybackInfoChangeListener = function(lis
     }
   }
 
-  return ServerInfoPlaybackInfoListener.addListener(args.listener);
+  return ServerInfoPlaybackInfoListener.addServerInfoListener(args.listener, this.name);
 };
 
 MediaControllerServerInfo.prototype.removePlaybackInfoChangeListener = function(watchId) {
@@ -764,7 +808,7 @@ MediaControllerServerInfo.prototype.removePlaybackInfoChangeListener = function(
     {name: 'watchId', type: types_.LONG}
   ]);
 
-  ServerInfoPlaybackInfoListener.removeListener(args.watchId);
+  ServerInfoPlaybackInfoListener.removeServerInfoListener(args.watchId);
 
   if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) {
     native_.callSync('MediaControllerServerInfo_removePlaybackInfoChangeListener');
index f48d8a1..8cb9cdd 100644 (file)
@@ -314,6 +314,7 @@ void MediaControllerClient::OnServerStatusUpdate(const char* server_name,
   picojson::object& data_o = data.get<picojson::object>();
 
   data_o["state"] = picojson::value(state_str);
+  data_o["name"] = picojson::value(server_name);
 
   client->server_status_listener_(&data);
 }
@@ -429,6 +430,7 @@ void MediaControllerClient::OnPlaybackUpdate(const char *server_name,
   data_o["action"] = picojson::value(std::string("onplaybackchanged"));
   data_o["state"] = picojson::value(state);
   data_o["position"] = picojson::value(position);
+  data_o["name"] = picojson::value(server_name);
 
   client->playback_info_listener_(&data);
 }
@@ -450,6 +452,7 @@ void MediaControllerClient::OnShuffleModeUpdate(const char *server_name,
 
   data_o["action"] = picojson::value(std::string("onshufflemodechanged"));
   data_o["mode"] = picojson::value(mode == MC_SHUFFLE_MODE_ON);
+  data_o["name"] = picojson::value(server_name);
 
   client->playback_info_listener_(&data);
 }
@@ -471,6 +474,7 @@ void MediaControllerClient::OnRepeatModeUpdate(const char *server_name,
 
   data_o["action"] = picojson::value(std::string("onrepeatmodechanged"));
   data_o["mode"] = picojson::value(mode == MC_REPEAT_MODE_ON);
+  data_o["name"] = picojson::value(server_name);
 
   client->playback_info_listener_(&data);
 }
@@ -500,6 +504,7 @@ void MediaControllerClient::OnMetadataUpdate(const char* server_name,
 
   data_o["action"] = picojson::value(std::string("onmetadatachanged"));
   data_o["metadata"] = metadata;
+  data_o["name"] = picojson::value(server_name);
 
   client->playback_info_listener_(&data);
 }
@@ -590,6 +595,7 @@ void MediaControllerClient::OnCommandReply(const char* server_name,
     return;
   }
   reply_o["data"] = data;
+  reply_o["name"] = picojson::value(server_name);
 
   client->command_reply_callback_(&reply);
 }