@Override
        public void onEvent(JSONArray args, Acknowledge ack) {
          // [{"data":true,"id":331051653483882560,"screen":"","audio":true,"video":true}]
          log("mOnAddStream");

          try {
            StreamDescription stream = StreamDescription.parseJson(args.getJSONObject(0));

            boolean isLocal = mLocalStream.get(stream.getId()) != null;
            if (!isLocal) {
              mRemoteStream.put(stream.getId(), stream);
              triggerStreamAdded(stream);
            }
          } catch (JSONException e) {
          }
        }
 void sendConfirmation() {
   JSONObject p0 = mStream.toJsonOffer("ok");
   try {
     p0.put("streamId", mStream.getId());
     p0.put("messageType", "OK");
     p0.put("offererSessionId", mOffererSessionId);
     p0.put("answererSessionId", mAnswererSessionId);
     p0.put("seq", 1);
     // p0.put("sdp", " ");
   } catch (JSONException e) {
   }
   sendSDPSocket(mSignalChannel, p0, p0, null);
 }
    void sendLocalDescription() {
      JSONObject desc = null;
      if (mIsPublish) {
        desc = mStream.toJsonOffer("offer");
      } else {
        desc = mStream.toJsonOffer(null);
        try {
          desc.put("streamId", mStream.getId());
        } catch (JSONException e) {
        }
      }
      JSONObject p1 = new JSONObject();
      try {
        p1.put("messageType", "OFFER");
        p1.put("sdp", mLocalSdp.description);
        p1.put("tiebreaker", (int) (Math.random() * (Integer.MAX_VALUE - 2)) + 1);
        p1.put("offererSessionId", mOffererSessionId); // hardcoded in
        // Licode?
        p1.put("seq", 1); // should not be hardcoded, but works for now
      } catch (JSONException e) {
      }
      log("SdpObserver#sendLocalDescription; to: " + mSignalChannel + "; msg: " + p1.toString());
      sendSDPSocket(
          mSignalChannel,
          desc,
          p1,
          new Acknowledge() {
            @Override
            public void acknowledge(JSONArray arg0) {
              log("SdpObserver#sendLocalDescription#sendSDPSocket#Acknowledge: " + arg0.toString());

              String streamId = null;
              SessionDescription remoteSdp = null;
              try {
                // log(arg0.getString(0));
                // JSONObject jsonAnswer = arg0.getJSONObject(0);
                // licode server sends answer as string which is
                // basically a json string, though
                JSONObject jsonAnswer = new JSONObject(arg0.getString(0));
                boolean answer = "ANSWER".equals(jsonAnswer.getString("messageType"));
                if (!answer) {
                  log("SdpObserver: expected ANSWER, got: " + jsonAnswer.getString("messageType"));
                }
                remoteSdp = new SessionDescription(Type.ANSWER, jsonAnswer.getString("sdp"));

                if (mIsPublish) {
                  streamId = arg0.getString(1);
                }

                mAnswererSessionId = jsonAnswer.getInt("answererSessionId");
              } catch (JSONException e1) {
              }

              if (mIsPublish) {
                mStream.setId(streamId);
                mLocalStream.put(streamId, mStream);
              }

              final SessionDescription finalRemoteSdp = remoteSdp;
              mActivity.runOnUiThread(
                  new Runnable() {
                    @Override
                    public void run() {
                      mStream.pc.setRemoteDescription(LicodeSdpObserver.this, finalRemoteSdp);
                    }
                  });
            }
          });
    }