/* static */ int16_t
PluginAsyncSurrogate::NPP_HandleEvent(NPP aInstance, void* aEvent)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  MOZ_ASSERT(surrogate);
  return surrogate->NPP_HandleEvent(aEvent);
}
/* static */ int32_t
PluginAsyncSurrogate::NPP_WriteReady(NPP aInstance, NPStream* aStream)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  MOZ_ASSERT(surrogate);
  return surrogate->NPP_WriteReady(aStream);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_SetWindow(NPP aInstance, NPWindow* aWindow)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  MOZ_ASSERT(surrogate);
  return surrogate->NPP_SetWindow(aWindow);
}
/* static */ void
PluginAsyncSurrogate::NPP_Print(NPP aInstance, NPPrint* aPrintInfo)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  MOZ_ASSERT(surrogate);
  surrogate->NPP_Print(aPrintInfo);
}
mozilla::ipc::IPCResult
BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv,
                                                  const uint16_t& stype)
{
  PLUGIN_LOG_DEBUG_FUNCTION;
  PluginAsyncSurrogate* surrogate = mNPP->GetAsyncSurrogate();
  MOZ_ASSERT(surrogate);
  surrogate->AsyncCallArriving();
  if (mState == DEFERRING_DESTROY) {
    // We've been asked to destroy ourselves before init was complete.
    mState = DYING;
    Unused << SendNPP_DestroyStream(mDeferredDestroyReason);
    return IPC_OK();
  }

  NPError error = rv;
  if (error == NPERR_NO_ERROR) {
    if (!mStreamListener) {
      return IPC_FAIL_NO_REASON(this);
    }
    if (mStreamListener->SetStreamType(stype)) {
      mState = ALIVE;
    } else {
      error = NPERR_GENERIC_ERROR;
    }
  }

  if (error != NPERR_NO_ERROR) {
    surrogate->DestroyAsyncStream(mStream);
    Unused << PBrowserStreamParent::Send__delete__(this);
  }

  return IPC_OK();
}
/* static */ NPError
PluginAsyncSurrogate::NPP_SetValue(NPP aInstance, NPNVariable aVariable,
                                   void* aValue)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  MOZ_ASSERT(surrogate);
  return surrogate->NPP_SetValue(aVariable, aValue);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_NewStream(NPP aInstance, NPMIMEType aType,
                                    NPStream* aStream, NPBool aSeekable,
                                    uint16_t* aStype)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  MOZ_ASSERT(surrogate);
  return surrogate->NPP_NewStream(aType, aStream, aSeekable, aStype);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_DestroyStream(NPP aInstance,
                                        NPStream* aStream,
                                        NPReason aReason)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  MOZ_ASSERT(surrogate);
  return surrogate->NPP_DestroyStream(aStream, aReason);
}
/* static */ void
PluginAsyncSurrogate::NotifyDestroyPending(NPP aInstance)
{
  PluginAsyncSurrogate* surrogate = Cast(aInstance);
  if (!surrogate) {
    return;
  }
  surrogate->NotifyDestroyPending();
}
/* static */ NPError
PluginAsyncSurrogate::NPP_Destroy(NPP aInstance, NPSavedData** aSave)
{
  PluginAsyncSurrogate* rawSurrogate = Cast(aInstance);
  MOZ_ASSERT(rawSurrogate);
  PluginModuleParent* module = rawSurrogate->GetParent();
  if (module && !module->IsInitialized()) {
    // Take ownership of pdata's surrogate since we're going to release it
    nsRefPtr<PluginAsyncSurrogate> surrogate(dont_AddRef(rawSurrogate));
    aInstance->pdata = nullptr;
    // We haven't actually called NPP_New yet, so we should remove the
    // surrogate for this instance.
    bool removeOk = module->RemovePendingSurrogate(surrogate);
    MOZ_ASSERT(removeOk);
    if (!removeOk) {
      return NPERR_GENERIC_ERROR;
    }
    surrogate->mInitCancelled = true;
    return NPERR_NO_ERROR;
  }
  return rawSurrogate->NPP_Destroy(aSave);
}
bool
BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv,
                                                  const uint16_t& stype)
{
  PLUGIN_LOG_DEBUG_FUNCTION;
  PluginAsyncSurrogate* surrogate = mNPP->GetAsyncSurrogate();
  MOZ_ASSERT(surrogate);
  surrogate->AsyncCallArriving();
  nsRefPtr<nsNPAPIPluginStreamListener> streamListener = mStreamListener.forget();
  if (mState == DEFERRING_DESTROY) {
    // We've been asked to destroy ourselves before init was complete.
    mState = DYING;
    unused << SendNPP_DestroyStream(mDeferredDestroyReason);
    return true;
  }

  NPError error = rv;
  if (error == NPERR_NO_ERROR) {
    if (!streamListener) {
      return false;
    }
    if (streamListener->SetStreamType(stype)) {
      mState = ALIVE;
    } else {
      error = NPERR_GENERIC_ERROR;
    }
  }

  if (error != NPERR_NO_ERROR) {
    // We need to clean up the stream
    parent::_destroystream(mNPP->GetNPP(), mStream, NPRES_DONE);
    unused << PBrowserStreamParent::Send__delete__(this);
  }

  return true;
}