コード例 #1
0
nsresult
PresentationService::HandleTerminateRequest(nsIPresentationTerminateRequest* aRequest)
{
  nsCOMPtr<nsIPresentationControlChannel> ctrlChannel;
  nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel));
  if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) {
    return rv;
  }

  nsAutoString sessionId;
  rv = aRequest->GetPresentationId(sessionId);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  nsCOMPtr<nsIPresentationDevice> device;
  rv = aRequest->GetDevice(getter_AddRefs(device));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  bool isFromReceiver;
  rv = aRequest->GetIsFromReceiver(&isFromReceiver);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  RefPtr<PresentationSessionInfo> info;
  if (!isFromReceiver) {
    info = GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER);
  } else {
    info = GetSessionInfo(sessionId, nsIPresentationService::ROLE_CONTROLLER);
  }
  if (NS_WARN_IF(!info)) {
    // Cannot terminate non-existed session.
    ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR);
    return NS_ERROR_DOM_ABORT_ERR;
  }

  // Check if terminate request comes from known device.
  RefPtr<nsIPresentationDevice> knownDevice = info->GetDevice();
  if (NS_WARN_IF(!IsSameDevice(device, knownDevice))) {
    ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR);
    return NS_ERROR_DOM_ABORT_ERR;
  }

  PRES_DEBUG("handle termination:id[%s], receiver[%d]\n", __func__,
             sessionId.get(), isFromReceiver);

  return info->OnTerminate(ctrlChannel);
}
コード例 #2
0
NS_IMETHODIMP
PresentationService::RegisterSessionListener(const nsAString& aSessionId,
                                             uint8_t aRole,
                                             nsIPresentationSessionListener* aListener)
{
  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);

  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(aListener);
  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
             aRole == nsIPresentationService::ROLE_RECEIVER);

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    // Notify the listener of TERMINATED since no correspondent session info is
    // available possibly due to establishment failure. This would be useful at
    // the receiver side, since a presentation session is created at beginning
    // and here is the place to realize the underlying establishment fails.
    nsresult rv = aListener->NotifyStateChange(aSessionId,
                                               nsIPresentationSessionListener::STATE_TERMINATED,
                                               NS_ERROR_NOT_AVAILABLE);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
    return NS_ERROR_NOT_AVAILABLE;
  }

  return info->SetListener(aListener);
}
コード例 #3
0
NS_IMETHODIMP
PresentationService::ReconnectSession(const nsTArray<nsString>& aUrls,
                                      const nsAString& aSessionId,
                                      uint8_t aRole,
                                      nsIPresentationServiceCallback* aCallback)
{
  PRES_DEBUG("%s:id[%s]\n", __func__, NS_ConvertUTF16toUTF8(aSessionId).get());

  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!aSessionId.IsEmpty());
  MOZ_ASSERT(aCallback);
  MOZ_ASSERT(!aUrls.IsEmpty());

  if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
    MOZ_ASSERT(false, "Only controller can call ReconnectSession.");
    return NS_ERROR_INVALID_ARG;
  }

  if (NS_WARN_IF(!aCallback)) {
    return NS_ERROR_INVALID_ARG;
  }

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR);
  }

  if (NS_WARN_IF(!aUrls.Contains(info->GetUrl()))) {
    return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR);
  }

  return static_cast<PresentationControllingInfo*>(info.get())->Reconnect(aCallback);
}
コード例 #4
0
NS_IMETHODIMP
PresentationService::CloseSession(const nsAString& aSessionId,
                                  uint8_t aRole,
                                  uint8_t aClosedReason)
{
  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
             NS_ConvertUTF16toUTF8(aSessionId).get(), aClosedReason, aRole);

  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!aSessionId.IsEmpty());
  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
             aRole == nsIPresentationService::ROLE_RECEIVER);

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  if (aClosedReason == nsIPresentationService::CLOSED_REASON_WENTAWAY) {
    // Remove nsIPresentationSessionListener since we don't want to dispatch
    // PresentationConnectionCloseEvent if the page is went away.
    info->SetListener(nullptr);
  }

  return info->Close(NS_OK, nsIPresentationSessionListener::STATE_CLOSED);
}
コード例 #5
0
NS_IMETHODIMP
PresentationService::NotifyReceiverReady(
    const nsAString& aSessionId, uint64_t aWindowId, bool aIsLoading,
    nsIPresentationTransportBuilderConstructor* aBuilderConstructor) {
  PRES_DEBUG("%s:id[%s], windowId[%" PRIu64 "], loading[%d]\n", __func__,
             NS_ConvertUTF16toUTF8(aSessionId).get(), aWindowId, aIsLoading);

  RefPtr<PresentationSessionInfo> info =
      GetSessionInfo(aSessionId, nsIPresentationService::ROLE_RECEIVER);
  if (NS_WARN_IF(!info)) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  AddRespondingSessionId(aWindowId, aSessionId,
                         nsIPresentationService::ROLE_RECEIVER);

  if (!aIsLoading) {
    return static_cast<PresentationPresentingInfo*>(info.get())
        ->NotifyResponderFailure();
  }

  nsCOMPtr<nsIPresentationRespondingListener> listener;
  if (mRespondingListeners.Get(aWindowId, getter_AddRefs(listener))) {
    nsresult rv = listener->NotifySessionConnect(aWindowId, aSessionId);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  info->SetTransportBuilderConstructor(aBuilderConstructor);
  return static_cast<PresentationPresentingInfo*>(info.get())
      ->NotifyResponderReady();
}
コード例 #6
0
bool PresentationService::IsSessionAccessible(const nsAString& aSessionId,
                                              const uint8_t aRole,
                                              base::ProcessId aProcessId) {
  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
             aRole == nsIPresentationService::ROLE_RECEIVER);
  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    return false;
  }
  return info->IsAccessible(aProcessId);
}
コード例 #7
0
nsresult
PresentationService::HandleReconnectRequest(nsIPresentationSessionRequest* aRequest)
{
  nsCOMPtr<nsIPresentationControlChannel> ctrlChannel;
  nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel));
  if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) {
    return rv;
  }

  nsAutoString sessionId;
  rv = aRequest->GetPresentationId(sessionId);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  uint64_t windowId;
  rv = GetWindowIdBySessionIdInternal(sessionId,
                                      nsIPresentationService::ROLE_RECEIVER,
                                      &windowId);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  RefPtr<PresentationSessionInfo> info =
    GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER);
  if (NS_WARN_IF(!info)) {
    // Cannot reconnect non-existed session
    ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR);
    return NS_ERROR_DOM_ABORT_ERR;
  }

  nsAutoString url;
  rv = aRequest->GetUrl(url);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  // Make sure the url is the same as the previous one.
  if (NS_WARN_IF(!info->GetUrl().Equals(url))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  return HandleSessionRequest(aRequest);
}
コード例 #8
0
NS_IMETHODIMP
PresentationService::SendSessionBlob(const nsAString& aSessionId, uint8_t aRole,
                                     Blob* aBlob) {
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!aSessionId.IsEmpty());
  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
             aRole == nsIPresentationService::ROLE_RECEIVER);
  MOZ_ASSERT(aBlob);

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  return info->SendBlob(aBlob);
}
コード例 #9
0
NS_IMETHODIMP
PresentationService::TerminateSession(const nsAString& aSessionId,
                                      uint8_t aRole) {
  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);

  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!aSessionId.IsEmpty());
  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
             aRole == nsIPresentationService::ROLE_RECEIVER);

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  return info->Close(NS_OK, nsIPresentationSessionListener::STATE_TERMINATED);
}
コード例 #10
0
NS_IMETHODIMP
PresentationService::BuildTransport(const nsAString& aSessionId,
                                    uint8_t aRole)
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!aSessionId.IsEmpty());

  if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
    MOZ_ASSERT(false, "Only controller can call BuildTransport.");
    return NS_ERROR_INVALID_ARG;
  }

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  return static_cast<PresentationControllingInfo*>(info.get())->BuildTransport();
}
コード例 #11
0
nsresult PresentationService::NotifyTransportClosed(const nsAString& aSessionId,
                                                    uint8_t aRole,
                                                    nsresult aReason) {
  PRES_DEBUG("%s:id[%s], reason[%" PRIx32 "], role[%d]\n", __func__,
             NS_ConvertUTF16toUTF8(aSessionId).get(),
             static_cast<uint32_t>(aReason), aRole);

  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!aSessionId.IsEmpty());
  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
             aRole == nsIPresentationService::ROLE_RECEIVER);

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (NS_WARN_IF(!info)) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  return info->NotifyTransportClosed(aReason);
}
コード例 #12
0
NS_IMETHODIMP
PresentationService::UnregisterSessionListener(const nsAString& aSessionId,
                                               uint8_t aRole)
{
  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);

  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
             aRole == nsIPresentationService::ROLE_RECEIVER);

  RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
  if (info) {
    // When content side decide not handling this session anymore, simply
    // close the connection. Session info is kept for reconnection.
    Unused << NS_WARN_IF(NS_FAILED(info->Close(NS_OK, nsIPresentationSessionListener::STATE_CLOSED)));
    return info->SetListener(nullptr);
  }
  return NS_OK;
}
コード例 #13
0
ファイル: DarkPeer.cpp プロジェクト: adrikim/thiefmp
//==============================================================================
// OnEnumerationResponse()
//
// Handles host enumeration responses, and connects to the returned session.
//==============================================================================
void CDarkPeer::OnEnumerationResponse(PDPNMSG_ENUM_HOSTS_RESPONSE pEnumHostsResponseMsg)
{
#if (GAME == GAME_THIEF || GAME == GAME_DROMED)
	if (!g_ConnectAttempt.IsActive())
	{
		return;
	}
#endif

	HRESULT hRes;
	const DPN_APPLICATION_DESC* pAppDesc = pEnumHostsResponseMsg->pApplicationDescription;

#if (GAME == GAME_THIEF || GAME == GAME_DROMED)
	m_pSessionMgr->SetSessionInfo(pEnumHostsResponseMsg->pApplicationDescription);
	const SessionInfo& info = GetSessionInfo();

	if (info.build != TMP_BUILD)
	{
		ConPrintF("Server version (%d) does not match client version. Connection failed.", info.build);
		CancelEnumeration();
		return;
	}

	NString sessName = pEnumHostsResponseMsg->pApplicationDescription->pwszSessionName;
	ConPrintF("Game found: %s  Players: %d/%d  Build: %d.", sessName.Str(), pAppDesc->dwCurrentPlayers, pAppDesc->dwMaxPlayers, info.build);
#endif

	hRes = SetPlayerInfo();
	if (FAILED(hRes))
		return Log.Print("Failed to set peer info.");

	// Set the password, if we have one
	if (g_ConnectAttempt.GetPassword())
	{
		(WCHAR*)pAppDesc->pwszPassword = (WCHAR*)g_ConnectAttempt.GetPassword();
	}

	hRes = m_pDP->Connect(pAppDesc, pEnumHostsResponseMsg->pAddressSender, pEnumHostsResponseMsg->pAddressDevice, 
		NULL, NULL, NULL, 0, this, NULL, NULL, DPNCONNECT_SYNC);

	g_ConnectAttempt.Clear();

	switch (hRes)
	{
	case DPN_OK:
#ifdef ALLOW_LATE_JOINS
		if (info.gameStarted)
		{
			g_bNeedSnapshot = true;
			CNetMsg_RequestSnapshot msg;

			DbgPrint("Requesting snapshot");

			g_pNetMan->m_numStartedSynch = g_pNetMan->NumPlayers(); // 8/8/10 //g_pDarkNet->GetSessionManager()->GetApplicationDesc()->dwCurrentPlayers - 1;
			DbgPrint("Other players: %d", g_pNetMan->m_numStartedSynch);

			cNetManagerFns::_LoopFunc((void*)0x006C9420, kMsgBeginFrame, NULL);

			SendToHost((void*)&msg, sizeof(CNetMsg_RequestSnapshot), DPNSEND_GUARANTEED);
		}
#endif
		break; // Connection successful
	case DPNERR_INVALIDPASSWORD:
		ConPrintF("Incorrect password.");
		CancelEnumeration();
		break;
	case DPNERR_SESSIONFULL:
		ConPrintF("The server is full.");
		CancelEnumeration();
		break;
	case DPNERR_HOSTREJECTEDCONNECTION:
		ConPrintF("Cannot join server: the host has already started the mission.");
		CancelEnumeration();
		break;
	default:
		ConPrintF("Failed to connect to server. (%x)", DPlayErrorToString(hRes)); // Unknown error
		CancelEnumeration();
	}
}
コード例 #14
0
nsresult
PresentationService::HandleSessionRequest(nsIPresentationSessionRequest* aRequest)
{
  nsCOMPtr<nsIPresentationControlChannel> ctrlChannel;
  nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel));
  if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) {
    return rv;
  }

  nsAutoString url;
  rv = aRequest->GetUrl(url);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  nsAutoString sessionId;
  rv = aRequest->GetPresentationId(sessionId);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  nsCOMPtr<nsIPresentationDevice> device;
  rv = aRequest->GetDevice(getter_AddRefs(device));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  // Create or reuse session info.
  RefPtr<PresentationSessionInfo> info =
    GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER);

  // This is the case for reconnecting a session.
  // Update the control channel and device of the session info.
  // Call |NotifyResponderReady| to indicate the receiver page is already there.
  if (info) {
    PRES_DEBUG("handle reconnection:id[%s]\n",
               NS_ConvertUTF16toUTF8(sessionId).get());

    info->SetControlChannel(ctrlChannel);
    info->SetDevice(device);
    return static_cast<PresentationPresentingInfo*>(
      info.get())->DoReconnect();
  }

  // This is the case for a new session.
  PRES_DEBUG("handle new session:url[%d], id[%s]\n",
             NS_ConvertUTF16toUTF8(url).get(),
             NS_ConvertUTF16toUTF8(sessionId).get());

  info = new PresentationPresentingInfo(url, sessionId, device);
  rv = info->Init(ctrlChannel);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return rv;
  }

  mSessionInfoAtReceiver.Put(sessionId, info);

  // Notify the receiver to launch.
  nsCOMPtr<nsIPresentationRequestUIGlue> glue =
    do_CreateInstance(PRESENTATION_REQUEST_UI_GLUE_CONTRACTID);
  if (NS_WARN_IF(!glue)) {
    ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR);
    return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR);
  }
  nsCOMPtr<nsISupports> promise;
  rv = glue->SendRequest(url, sessionId, device, getter_AddRefs(promise));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    ctrlChannel->Disconnect(rv);
    return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR);
  }
  nsCOMPtr<Promise> realPromise = do_QueryInterface(promise);
  static_cast<PresentationPresentingInfo*>(info.get())->SetPromise(realPromise);

  return NS_OK;
}