void
GMPRemoveTest::Setup()
{
  // Initialize media preferences.
  MediaPrefs::GetSingleton();
  GeneratePlugin();
  GetService()->GetThread(getter_AddRefs(mGMPThread));

  // Spin the event loop until the GMP service has had a chance to complete
  // adding GMPs from MOZ_GMP_PATH. Otherwise, the RemovePluginDirectory()
  // below may complete before we're finished adding GMPs from MOZ_GMP_PATH,
  // and we'll end up not removing the GMP, and the test will fail.
  RefPtr<AbstractThread> thread(GetServiceParent()->GetAbstractGMPThread());
  EXPECT_TRUE(thread);
  GMPTestMonitor* mon = &mTestMonitor;
  GetServiceParent()->EnsureInitialized()->Then(thread, __func__,
    [mon]() { mon->SetFinished(); },
    [mon]() { mon->SetFinished(); }
  );
  mTestMonitor.AwaitFinished();

  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
  obs->AddObserver(this, GMP_DELETED_TOPIC, false /* strong ref */);
  EXPECT_OK(GetServiceParent()->RemovePluginDirectory(mOriginalPath));

  GetServiceParent()->AsyncAddPluginDirectory(mTmpPath)->Then(thread, __func__,
    [mon]() { mon->SetFinished(); },
    [mon]() { mon->SetFinished(); }
  );
  mTestMonitor.AwaitFinished();
}
// GMPVideoDecoderCallbackProxy
void
GMPRemoveTest::Decoded(GMPVideoi420Frame* aDecodedFrame)
{
  aDecodedFrame->Destroy();
  mDecodeResult = GMPNoErr;
  mTestMonitor.SetFinished();
}
GMPErr
GMPRemoveTest::Decode()
{
  mGMPThread->Dispatch(
    NS_NewNonOwningRunnableMethod(this, &GMPRemoveTest::gmp_Decode),
    NS_DISPATCH_NORMAL);

  mTestMonitor.AwaitFinished();
  return mDecodeResult;
}
bool
GMPRemoveTest::CreateVideoDecoder(nsCString aNodeId)
{
  GMPVideoHost* host;
  GMPVideoDecoderProxy* decoder = nullptr;

  mGMPThread->Dispatch(NewNonOwningRunnableMethod<nsCString,
                                                  GMPVideoDecoderProxy**,
                                                  GMPVideoHost**>(
                         "GMPRemoveTest::gmp_GetVideoDecoder",
                         this,
                         &GMPRemoveTest::gmp_GetVideoDecoder,
                         aNodeId,
                         &decoder,
                         &host),
                       NS_DISPATCH_NORMAL);

  mTestMonitor.AwaitFinished();

  if (!decoder) {
    return false;
  }

  GMPVideoCodec codec;
  memset(&codec, 0, sizeof(codec));
  codec.mGMPApiVersion = 33;

  nsTArray<uint8_t> empty;
  mGMPThread->Dispatch(
    NewNonOwningRunnableMethod<const GMPVideoCodec&,
                               const nsTArray<uint8_t>&,
                               GMPVideoDecoderCallbackProxy*,
                               int32_t>("GMPVideoDecoderProxy::InitDecode",
                                        decoder,
                                        &GMPVideoDecoderProxy::InitDecode,
                                        codec,
                                        empty,
                                        this,
                                        1 /* core count */),
    NS_DISPATCH_SYNC);

  if (mDecoder) {
    CloseVideoDecoder();
  }

  mDecoder = decoder;
  mHost = host;

  return true;
}
// nsIObserver
NS_IMETHODIMP
GMPRemoveTest::Observe(nsISupports* aSubject, const char* aTopic,
                       const char16_t* aData)
{
  EXPECT_TRUE(!strcmp(GMP_DELETED_TOPIC, aTopic));

  nsString data(aData);
  if (mTmpPath.Equals(data)) {
    mTestMonitor.SetFinished();
    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    obs->RemoveObserver(this, GMP_DELETED_TOPIC);
  }

  return NS_OK;
}
// GMPVideoDecoderCallbackProxy
void
GMPRemoveTest::Error(GMPErr aError)
{
  mDecodeResult = aError;
  mTestMonitor.SetFinished();
}
void
GMPRemoveTest::Wait()
{
  mTestMonitor.AwaitFinished();
}