Bug 1331829 - Remove async shutdown GMP API. r=gerald
authorChris Pearce <cpearce@mozilla.com>
Wed, 18 Jan 2017 15:01:56 +1300
changeset 377288 f5138ecf6374787133e3381b071cd7737aa16f7a
parent 377287 e98f322145a5c281e72ef279f9378ade609dc9c5
child 377289 a506d21c911efc23fd6f5d7c0d600a90b70b2277
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1331829
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1331829 - Remove async shutdown GMP API. r=gerald Now that we're not supporting Adobe EME anymore, we don't need to provide a mechanism for GMPs to block browser shutdown. MozReview-Commit-ID: KUC94IBQiod
dom/media/MediaPrefs.h
dom/media/gmp-plugin-openh264/gmp-fake-openh264.cpp
dom/media/gmp-plugin/gmp-fake.cpp
dom/media/gmp-plugin/gmp-test-decryptor.cpp
dom/media/gmp-plugin/gmp-test-decryptor.h
dom/media/gmp/GMPChild.cpp
dom/media/gmp/GMPChild.h
dom/media/gmp/GMPParent.cpp
dom/media/gmp/GMPParent.h
dom/media/gmp/GMPService.h
dom/media/gmp/GMPServiceParent.cpp
dom/media/gmp/GMPServiceParent.h
dom/media/gmp/PGMP.ipdl
dom/media/gmp/gmp-api/gmp-async-shutdown.h
dom/media/gmp/moz.build
dom/media/gtest/TestGMPCrossOrigin.cpp
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -96,17 +96,16 @@ private:
   DECL_MEDIA_PREF("media.ruin-av-sync.enabled",               RuinAvSync, bool, false);
 
   // Encrypted Media Extensions
   DECL_MEDIA_PREF("media.clearkey.persistent-license.enabled", ClearKeyPersistentLicenseEnabled, bool, false);
 
   // PlatformDecoderModule
   DECL_MEDIA_PREF("media.apple.forcevda",                     AppleForceVDA, bool, false);
   DECL_MEDIA_PREF("media.gmp.insecure.allow",                 GMPAllowInsecure, bool, false);
-  DECL_MEDIA_PREF("media.gmp.async-shutdown-timeout",         GMPAsyncShutdownTimeout, uint32_t, GMP_DEFAULT_ASYNC_SHUTDOWN_TIMEOUT);
   DECL_MEDIA_PREF("media.eme.enabled",                        EMEEnabled, bool, false);
   DECL_MEDIA_PREF("media.use-blank-decoder",                  PDMUseBlankDecoder, bool, false);
   DECL_MEDIA_PREF("media.gpu-process-decoder",                PDMUseGPUDecoder, bool, false);
 #ifdef MOZ_GONK_MEDIACODEC
   DECL_MEDIA_PREF("media.gonk.enabled",                       PDMGonkDecoderEnabled, bool, true);
 #endif
 #ifdef MOZ_WIDGET_ANDROID
   DECL_MEDIA_PREF("media.android-media-codec.enabled",        PDMAndroidMediaCodecEnabled, bool, false);
--- a/dom/media/gmp-plugin-openh264/gmp-fake-openh264.cpp
+++ b/dom/media/gmp-plugin-openh264/gmp-fake-openh264.cpp
@@ -407,19 +407,16 @@ extern "C" {
       return GMPNoErr;
     } else if (!strcmp (aApiName, GMP_API_VIDEO_ENCODER)) {
       *aPluginApi = new FakeVideoEncoder (static_cast<GMPVideoHost*> (aHostAPI));
       return GMPNoErr;
 #if defined(GMP_FAKE_SUPPORT_DECRYPT)
     } else if (!strcmp (aApiName, GMP_API_DECRYPTOR)) {
       *aPluginApi = new FakeDecryptor(static_cast<GMPDecryptorHost*> (aHostAPI));
       return GMPNoErr;
-    } else if (!strcmp (aApiName, GMP_API_ASYNC_SHUTDOWN)) {
-      *aPluginApi = new TestAsyncShutdown(static_cast<GMPAsyncShutdownHost*> (aHostAPI));
-      return GMPNoErr;
 #endif
     }
     return GMPGenericErr;
   }
 
   PUBLIC_FUNC void
   GMPShutdown (void) {
     g_platform_api = NULL;
--- a/dom/media/gmp-plugin/gmp-fake.cpp
+++ b/dom/media/gmp-plugin/gmp-fake.cpp
@@ -70,19 +70,16 @@ extern "C" {
       // Note: Deliberately advertise in our .info file that we support
       // video-decode, but we fail the "get" call here to simulate what
       // happens when decoder init fails.
       return GMPGenericErr;
 #if defined(GMP_FAKE_SUPPORT_DECRYPT)
     } else if (!strcmp (aApiName, GMP_API_DECRYPTOR)) {
       *aPluginApi = new FakeDecryptor(static_cast<GMPDecryptorHost*> (aHostAPI));
       return GMPNoErr;
-    } else if (!strcmp (aApiName, GMP_API_ASYNC_SHUTDOWN)) {
-      *aPluginApi = new TestAsyncShutdown(static_cast<GMPAsyncShutdownHost*> (aHostAPI));
-      return GMPNoErr;
 #endif
     }
     return GMPGenericErr;
   }
 
   PUBLIC_FUNC void
   GMPShutdown (void) {
     g_platform_api = NULL;
--- a/dom/media/gmp-plugin/gmp-test-decryptor.cpp
+++ b/dom/media/gmp-plugin/gmp-test-decryptor.cpp
@@ -568,41 +568,8 @@ FakeDecryptor::UpdateSession(uint32_t aP
     std::string voucher((const char*)rawVoucher, (const char*)(rawVoucher + length));
     Message("retrieved plugin-voucher: " + voucher);
   } else if (task == "retrieve-record-names") {
     GMPEnumRecordNames(&RecvGMPRecordIterator, this);
   } else if (task == "retrieve-node-id") {
     Message("node-id " + sNodeId);
   }
 }
-
-class CompleteShutdownTask : public GMPTask {
-public:
-  explicit CompleteShutdownTask(GMPAsyncShutdownHost* aHost)
-    : mHost(aHost)
-  {
-  }
-  void Run() override {
-    mHost->ShutdownComplete();
-  }
-  void Destroy() override { delete this; }
-  GMPAsyncShutdownHost* mHost;
-};
-
-void
-TestAsyncShutdown::BeginShutdown() {
-  switch (sShutdownMode) {
-    case ShutdownNormal:
-      mHost->ShutdownComplete();
-      break;
-    case ShutdownTimeout:
-      // Don't do anything; wait for timeout, Gecko should kill
-      // the plugin and recover.
-      break;
-    case ShutdownStoreToken:
-      // Store message, then shutdown.
-      WriteRecord("shutdown-token",
-                  sShutdownToken,
-                  new CompleteShutdownTask(mHost),
-                  new SendMessageTask("FAIL writing shutdown-token."));
-      break;
-  }
-}
--- a/dom/media/gmp-plugin/gmp-test-decryptor.h
+++ b/dom/media/gmp-plugin/gmp-test-decryptor.h
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef FAKE_DECRYPTOR_H__
 #define FAKE_DECRYPTOR_H__
 
 #include "gmp-decryption.h"
-#include "gmp-async-shutdown.h"
 #include <string>
 #include "mozilla/Attributes.h"
 
 class FakeDecryptor : public GMPDecryptor {
 public:
 
   explicit FakeDecryptor(GMPDecryptorHost* aHost);
 
@@ -86,20 +85,9 @@ private:
   static std::string sNodeId;
 
   void TestStorage();
 
   GMPDecryptorCallback* mCallback;
   GMPDecryptorHost* mHost;
 };
 
-class TestAsyncShutdown : public GMPAsyncShutdown {
-public:
-  explicit TestAsyncShutdown(GMPAsyncShutdownHost* aHost)
-    : mHost(aHost)
-  {
-  }
-  void BeginShutdown() override;
-private:
-  GMPAsyncShutdownHost* mHost;
-};
-
 #endif
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -48,18 +48,17 @@ namespace mozilla {
 
 extern LogModule* GetGMPLog();
 #define LOG(level, x, ...) MOZ_LOG(GetGMPLog(), (level), (x, ##__VA_ARGS__))
 #define LOGD(x, ...) LOG(mozilla::LogLevel::Debug, "GMPChild[pid=%d] " x, (int)base::GetCurrentProcId(), ##__VA_ARGS__)
 
 namespace gmp {
 
 GMPChild::GMPChild()
-  : mAsyncShutdown(nullptr)
-  , mGMPMessageLoop(MessageLoop::current())
+  : mGMPMessageLoop(MessageLoop::current())
   , mGMPLoader(nullptr)
 {
   LOGD("GMPChild ctor");
   nsDebugImpl::SetMultiprocessMode("GMP");
 }
 
 GMPChild::~GMPChild()
 {
@@ -394,24 +393,16 @@ GMPChild::AnswerStartPlugin(const nsStri
                         mNodeId.Length(),
                         platformAPI,
                         adapter)) {
     NS_WARNING("Failed to load GMP");
     delete platformAPI;
     return IPC_FAIL_NO_REASON(this);
   }
 
-  void* sh = nullptr;
-  GMPAsyncShutdownHost* host = static_cast<GMPAsyncShutdownHost*>(this);
-  GMPErr err = GetAPI(GMP_API_ASYNC_SHUTDOWN, host, &sh);
-  if (err == GMPNoErr && sh) {
-    mAsyncShutdown = reinterpret_cast<GMPAsyncShutdown*>(sh);
-    SendAsyncShutdownRequired();
-  }
-
   return IPC_OK();
 }
 
 MessageLoop*
 GMPChild::GMPMessageLoop()
 {
   return mGMPMessageLoop;
 }
@@ -529,47 +520,24 @@ GMPChild::GetGMPStorage()
 mozilla::ipc::IPCResult
 GMPChild::RecvCrashPluginNow()
 {
   MOZ_CRASH();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-GMPChild::RecvBeginAsyncShutdown()
-{
-  LOGD("%s AsyncShutdown=%d", __FUNCTION__, mAsyncShutdown!=nullptr);
-
-  MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current());
-  if (mAsyncShutdown) {
-    mAsyncShutdown->BeginShutdown();
-  } else {
-    ShutdownComplete();
-  }
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
 GMPChild::RecvCloseActive()
 {
   for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
     mGMPContentChildren[i - 1]->CloseActive();
   }
   return IPC_OK();
 }
 
-void
-GMPChild::ShutdownComplete()
-{
-  LOGD("%s", __FUNCTION__);
-  MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current());
-  mAsyncShutdown = nullptr;
-  SendAsyncShutdownComplete();
-}
-
 static void
 GetPluginVoucherFile(const nsAString& aPluginPath,
                      nsCOMPtr<nsIFile>& aOutVoucherFile)
 {
   nsAutoString baseName;
   GetFileBase(aPluginPath, aOutVoucherFile, baseName);
   nsAutoString infoFileName = baseName + NS_LITERAL_STRING(".voucher");
   aOutVoucherFile->AppendRelativePath(infoFileName);
--- a/dom/media/gmp/GMPChild.h
+++ b/dom/media/gmp/GMPChild.h
@@ -5,46 +5,41 @@
 
 #ifndef GMPChild_h_
 #define GMPChild_h_
 
 #include "mozilla/gmp/PGMPChild.h"
 #include "GMPTimerChild.h"
 #include "GMPStorageChild.h"
 #include "GMPLoader.h"
-#include "gmp-async-shutdown.h"
 #include "gmp-entrypoints.h"
 #include "prlink.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPContentChild;
 
 class GMPChild : public PGMPChild
-               , public GMPAsyncShutdownHost
 {
 public:
   GMPChild();
   virtual ~GMPChild();
 
   bool Init(const nsAString& aPluginPath,
             const nsAString& aVoucherPath,
             base::ProcessId aParentPid,
             MessageLoop* aIOLoop,
             IPC::Channel* aChannel);
   MessageLoop* GMPMessageLoop();
 
   // Main thread only.
   GMPTimerChild* GetGMPTimers();
   GMPStorageChild* GetGMPStorage();
 
-  // GMPAsyncShutdownHost
-  void ShutdownComplete() override;
-
 #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
   bool SetMacSandboxInfo(MacSandboxPluginType aPluginType);
 #endif
 
 private:
   friend class GMPContentChild;
 
   bool PreLoadPluginVoucher();
@@ -65,27 +60,25 @@ private:
   PGMPStorageChild* AllocPGMPStorageChild() override;
   bool DeallocPGMPStorageChild(PGMPStorageChild* aActor) override;
 
   PGMPContentChild* AllocPGMPContentChild(Transport* aTransport,
                                           ProcessId aOtherPid) override;
   void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
 
   mozilla::ipc::IPCResult RecvCrashPluginNow() override;
-  mozilla::ipc::IPCResult RecvBeginAsyncShutdown() override;
   mozilla::ipc::IPCResult RecvCloseActive() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
   void ProcessingError(Result aCode, const char* aReason) override;
 
   GMPErr GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI, uint32_t aDecryptorId = 0);
 
   nsTArray<UniquePtr<GMPContentChild>> mGMPContentChildren;
 
-  GMPAsyncShutdown* mAsyncShutdown;
   RefPtr<GMPTimerChild> mTimerChild;
   RefPtr<GMPStorageChild> mStorage;
 
   MessageLoop* mGMPMessageLoop;
   nsString mPluginPath;
   nsString mSandboxVoucherPath;
   nsCString mNodeId;
   GMPLoader* mGMPLoader;
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -63,18 +63,16 @@ namespace gmp {
 GMPParent::GMPParent()
   : mState(GMPStateNotLoaded)
   , mProcess(nullptr)
   , mDeleteProcessOnlyOnUnload(false)
   , mAbnormalShutdownInProgress(false)
   , mIsBlockingDeletion(false)
   , mCanDecrypt(false)
   , mGMPContentChildCount(0)
-  , mAsyncShutdownRequired(false)
-  , mAsyncShutdownInProgress(false)
   , mChildPid(0)
   , mHoldingSelfRef(false)
 {
   mPluginId = GeckoChildProcessHost::GetUniqueID();
   LOGD("GMPParent ctor id=%u", mPluginId);
 }
 
 GMPParent::~GMPParent()
@@ -212,225 +210,65 @@ GMPParent::LoadProcess()
   // terminate the child process.
   MOZ_ASSERT(!mHoldingSelfRef);
   mHoldingSelfRef = true;
   AddRef();
 
   return NS_OK;
 }
 
-// static
-void
-GMPParent::AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure)
-{
-  NS_WARNING("Timed out waiting for GMP async shutdown!");
-  GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure);
-  MOZ_ASSERT(parent->mService);
-#if defined(MOZ_CRASHREPORTER)
-  parent->mService->SetAsyncShutdownPluginState(parent, 'G',
-    NS_LITERAL_CSTRING("Timed out waiting for async shutdown"));
-#endif
-  parent->mService->AsyncShutdownComplete(parent);
-}
-
-nsresult
-GMPParent::EnsureAsyncShutdownTimeoutSet()
-{
-  MOZ_ASSERT(mAsyncShutdownRequired);
-  if (mAsyncShutdownTimeout) {
-    return NS_OK;
-  }
-
-  nsresult rv;
-  mAsyncShutdownTimeout = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // Set timer to abort waiting for plugin to shutdown if it takes
-  // too long.
-  rv = mAsyncShutdownTimeout->SetTarget(mGMPThread);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-   return rv;
-  }
-
-  int32_t timeout = MediaPrefs::GMPAsyncShutdownTimeout();
-  RefPtr<GeckoMediaPluginServiceParent> service =
-    GeckoMediaPluginServiceParent::GetSingleton();
-  if (service) {
-    timeout = service->AsyncShutdownTimeoutMs();
-  }
-  rv = mAsyncShutdownTimeout->InitWithFuncCallback(
-    &AbortWaitingForGMPAsyncShutdown, this, timeout,
-    nsITimer::TYPE_ONE_SHOT);
-  Unused << NS_WARN_IF(NS_FAILED(rv));
-  return rv;
-}
-
 mozilla::ipc::IPCResult
 GMPParent::RecvPGMPContentChildDestroyed()
 {
   --mGMPContentChildCount;
   if (!IsUsed()) {
-#if defined(MOZ_CRASHREPORTER)
-    if (mService) {
-      mService->SetAsyncShutdownPluginState(this, 'E',
-        NS_LITERAL_CSTRING("Last content child destroyed"));
-    }
-#endif
     CloseIfUnused();
   }
-#if defined(MOZ_CRASHREPORTER)
-  else {
-    if (mService) {
-      mService->SetAsyncShutdownPluginState(this, 'F',
-        nsPrintfCString("Content child destroyed, remaining: %u", mGMPContentChildCount));
-    }
-  }
-#endif
   return IPC_OK();
 }
 
 void
 GMPParent::CloseIfUnused()
 {
   MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
-  LOGD("%s: mAsyncShutdownRequired=%d", __FUNCTION__, mAsyncShutdownRequired);
+  LOGD("%s", __FUNCTION__);
 
   if ((mDeleteProcessOnlyOnUnload ||
        mState == GMPStateLoaded ||
        mState == GMPStateUnloading) &&
       !IsUsed()) {
     // Ensure all timers are killed.
     for (uint32_t i = mTimers.Length(); i > 0; i--) {
       mTimers[i - 1]->Shutdown();
     }
 
-    if (mAsyncShutdownRequired) {
-      if (!mAsyncShutdownInProgress) {
-        LOGD("%s: sending async shutdown notification", __FUNCTION__);
-#if defined(MOZ_CRASHREPORTER)
-        if (mService) {
-          mService->SetAsyncShutdownPluginState(this, 'H',
-            NS_LITERAL_CSTRING("Sent BeginAsyncShutdown"));
-        }
-#endif
-        mAsyncShutdownInProgress = true;
-        if (!SendBeginAsyncShutdown()) {
-#if defined(MOZ_CRASHREPORTER)
-          if (mService) {
-            mService->SetAsyncShutdownPluginState(this, 'I',
-              NS_LITERAL_CSTRING("Could not send BeginAsyncShutdown - Aborting async shutdown"));
-          }
-#endif
-          AbortAsyncShutdown();
-        } else if (NS_FAILED(EnsureAsyncShutdownTimeoutSet())) {
-#if defined(MOZ_CRASHREPORTER)
-          if (mService) {
-            mService->SetAsyncShutdownPluginState(this, 'J',
-              NS_LITERAL_CSTRING("Could not start timer after sending BeginAsyncShutdown - Aborting async shutdown"));
-          }
-#endif
-          AbortAsyncShutdown();
-        }
-      }
-    } else {
-#if defined(MOZ_CRASHREPORTER)
-      if (mService) {
-        mService->SetAsyncShutdownPluginState(this, 'K',
-          NS_LITERAL_CSTRING("No (more) async-shutdown required"));
-      }
-#endif
-      // No async-shutdown, kill async-shutdown timer started in CloseActive().
-      AbortAsyncShutdown();
-      // Any async shutdown must be complete. Shutdown GMPStorage.
-      for (size_t i = mStorage.Length(); i > 0; i--) {
-        mStorage[i - 1]->Shutdown();
-      }
-      Shutdown();
+    // Shutdown GMPStorage. Given that all protocol actors must be shutdown
+    // (!Used() is true), all storage operations should be complete.
+    for (size_t i = mStorage.Length(); i > 0; i--) {
+      mStorage[i - 1]->Shutdown();
     }
+    Shutdown();
   }
 }
 
 void
-GMPParent::AbortAsyncShutdown()
-{
-  MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
-  LOGD("%s", __FUNCTION__);
-
-  if (mAsyncShutdownTimeout) {
-    mAsyncShutdownTimeout->Cancel();
-    mAsyncShutdownTimeout = nullptr;
-  }
-
-  if (!mAsyncShutdownRequired || !mAsyncShutdownInProgress) {
-    return;
-  }
-
-  RefPtr<GMPParent> kungFuDeathGrip(this);
-  mService->AsyncShutdownComplete(this);
-  mAsyncShutdownRequired = false;
-  mAsyncShutdownInProgress = false;
-  CloseIfUnused();
-}
-
-void
 GMPParent::CloseActive(bool aDieWhenUnloaded)
 {
   LOGD("%s: state %d", __FUNCTION__, mState);
   MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
 
   if (aDieWhenUnloaded) {
     mDeleteProcessOnlyOnUnload = true; // don't allow this to go back...
   }
   if (mState == GMPStateLoaded) {
     mState = GMPStateUnloading;
   }
   if (mState != GMPStateNotLoaded && IsUsed()) {
-#if defined(MOZ_CRASHREPORTER)
-    if (mService) {
-      mService->SetAsyncShutdownPluginState(this, 'A',
-        nsPrintfCString("Sent CloseActive, content children to close: %u", mGMPContentChildCount));
-    }
-#endif
-    if (!SendCloseActive()) {
-#if defined(MOZ_CRASHREPORTER)
-      if (mService) {
-        mService->SetAsyncShutdownPluginState(this, 'B',
-          NS_LITERAL_CSTRING("Could not send CloseActive - Aborting async shutdown"));
-      }
-#endif
-      AbortAsyncShutdown();
-    } else if (IsUsed()) {
-      // We're expecting RecvPGMPContentChildDestroyed's -> Start async-shutdown timer now if needed.
-      if (mAsyncShutdownRequired && NS_FAILED(EnsureAsyncShutdownTimeoutSet())) {
-#if defined(MOZ_CRASHREPORTER)
-        if (mService) {
-          mService->SetAsyncShutdownPluginState(this, 'C',
-            NS_LITERAL_CSTRING("Could not start timer after sending CloseActive - Aborting async shutdown"));
-        }
-#endif
-        AbortAsyncShutdown();
-      }
-    } else {
-      // We're not expecting any RecvPGMPContentChildDestroyed
-      // -> Call CloseIfUnused() now, to run async shutdown if necessary.
-      // Note that CloseIfUnused() may have already been called from a prior
-      // RecvPGMPContentChildDestroyed(), however depending on the state at
-      // that time, it might not have proceeded with shutdown; And calling it
-      // again after shutdown is fine because after the first one we'll be in
-      // GMPStateNotLoaded.
-#if defined(MOZ_CRASHREPORTER)
-      if (mService) {
-        mService->SetAsyncShutdownPluginState(this, 'D',
-          NS_LITERAL_CSTRING("Content children already destroyed"));
-      }
-#endif
-      CloseIfUnused();
-    }
+    Unused << SendCloseActive();
+    CloseIfUnused();
   }
 }
 
 void
 GMPParent::MarkForDeletion()
 {
   mDeleteProcessOnlyOnUnload = true;
   mIsBlockingDeletion = true;
@@ -443,18 +281,16 @@ GMPParent::IsMarkedForDeletion()
 }
 
 void
 GMPParent::Shutdown()
 {
   LOGD("%s", __FUNCTION__);
   MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
 
-  MOZ_ASSERT(!mAsyncShutdownTimeout, "Should have canceled shutdown timeout");
-
   if (mAbnormalShutdownInProgress) {
     return;
   }
 
   MOZ_ASSERT(!IsUsed());
   if (mState == GMPStateNotLoaded || mState == GMPStateClosing) {
     return;
   }
@@ -701,26 +537,16 @@ GMPParent::ActorDestroy(ActorDestroyReas
   // warn us off trying to close again
   mState = GMPStateClosing;
   mAbnormalShutdownInProgress = true;
   CloseActive(false);
 
   // Normal Shutdown() will delete the process on unwind.
   if (AbnormalShutdown == aWhy) {
     RefPtr<GMPParent> self(this);
-    if (mAsyncShutdownRequired) {
-#if defined(MOZ_CRASHREPORTER)
-      if (mService) {
-        mService->SetAsyncShutdownPluginState(this, 'M',
-          NS_LITERAL_CSTRING("Actor destroyed"));
-      }
-#endif
-      mService->AsyncShutdownComplete(this);
-      mAsyncShutdownRequired = false;
-    }
     // Must not call Close() again in DeleteProcess(), as we'll recurse
     // infinitely if we do.
     MOZ_ASSERT(mState == GMPStateClosing);
     DeleteProcess();
     // Note: final destruction will be Dispatched to ourself
     mService->ReAddOnGMPThread(self);
   }
 }
@@ -993,29 +819,28 @@ GMPParent::ParseChromiumManifest(const n
   mAdapter = NS_LITERAL_STRING("widevine");
 
   return GenericPromise::CreateAndResolve(true, __func__);
 }
 
 bool
 GMPParent::CanBeSharedCrossNodeIds() const
 {
-  return !mAsyncShutdownInProgress &&
-         mNodeId.IsEmpty() &&
+  return mNodeId.IsEmpty() &&
          // XXX bug 1159300 hack -- maybe remove after openh264 1.4
          // We don't want to use CDM decoders for non-encrypted playback
          // just yet; especially not for WebRTC. Don't allow CDMs to be used
          // without a node ID.
          !mCanDecrypt;
 }
 
 bool
 GMPParent::CanBeUsedFrom(const nsACString& aNodeId) const
 {
-  return !mAsyncShutdownInProgress && mNodeId == aNodeId;
+  return mNodeId == aNodeId;
 }
 
 void
 GMPParent::SetNodeId(const nsACString& aNodeId)
 {
   MOZ_ASSERT(!aNodeId.IsEmpty());
   mNodeId = aNodeId;
 }
@@ -1033,45 +858,16 @@ GMPParent::GetVersion() const
 }
 
 uint32_t
 GMPParent::GetPluginId() const
 {
   return mPluginId;
 }
 
-mozilla::ipc::IPCResult
-GMPParent::RecvAsyncShutdownRequired()
-{
-  LOGD("%s", __FUNCTION__);
-  if (mAsyncShutdownRequired) {
-    NS_WARNING("Received AsyncShutdownRequired message more than once!");
-    return IPC_OK();
-  }
-  mAsyncShutdownRequired = true;
-  mService->AsyncShutdownNeeded(this);
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-GMPParent::RecvAsyncShutdownComplete()
-{
-  LOGD("%s", __FUNCTION__);
-
-  MOZ_ASSERT(mAsyncShutdownRequired);
-#if defined(MOZ_CRASHREPORTER)
-  if (mService) {
-    mService->SetAsyncShutdownPluginState(this, 'L',
-      NS_LITERAL_CSTRING("Received AsyncShutdownComplete"));
-  }
-#endif
-  AbortAsyncShutdown();
-  return IPC_OK();
-}
-
 void
 GMPParent::ResolveGetContentParentPromises()
 {
   nsTArray<UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>> promises;
   promises.SwapElements(mGetContentParentPromises);
   MOZ_ASSERT(mGetContentParentPromises.IsEmpty());
   RefPtr<GMPContentParent::CloseBlocker> blocker(new GMPContentParent::CloseBlocker(mGMPContentParent));
   for (auto& holder : promises) {
--- a/dom/media/gmp/GMPParent.h
+++ b/dom/media/gmp/GMPParent.h
@@ -177,32 +177,26 @@ private:
 
   PGMPContentParent* AllocPGMPContentParent(Transport* aTransport,
                                             ProcessId aOtherPid) override;
 
   mozilla::ipc::IPCResult RecvPGMPTimerConstructor(PGMPTimerParent* actor) override;
   PGMPTimerParent* AllocPGMPTimerParent() override;
   bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) override;
 
-  mozilla::ipc::IPCResult RecvAsyncShutdownComplete() override;
-  mozilla::ipc::IPCResult RecvAsyncShutdownRequired() override;
-
   mozilla::ipc::IPCResult RecvPGMPContentChildDestroyed() override;
   bool IsUsed()
   {
     return mGMPContentChildCount > 0 ||
            !mGetContentParentPromises.IsEmpty();
   }
 
   void ResolveGetContentParentPromises();
   void RejectGetContentParentPromises();
 
-  static void AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure);
-  nsresult EnsureAsyncShutdownTimeoutSet();
-
   GMPState mState;
   nsCOMPtr<nsIFile> mDirectory; // plugin directory on disk
   nsString mName; // base name of plugin on disk, UTF-16 because used for paths
   nsCString mDisplayName; // name of plugin displayed to users
   nsCString mDescription; // description of plugin for display to users
   nsCString mVersion;
 #ifdef XP_WIN
   nsCString mLibs;
@@ -215,29 +209,25 @@ private:
   bool mAbnormalShutdownInProgress;
   bool mIsBlockingDeletion;
 
   bool mCanDecrypt;
 
   nsTArray<RefPtr<GMPTimerParent>> mTimers;
   nsTArray<RefPtr<GMPStorageParent>> mStorage;
   nsCOMPtr<nsIThread> mGMPThread;
-  nsCOMPtr<nsITimer> mAsyncShutdownTimeout; // GMP Thread only.
   // NodeId the plugin is assigned to, or empty if the the plugin is not
   // assigned to a NodeId.
   nsCString mNodeId;
   // This is used for GMP content in the parent, there may be more of these in
   // the content processes.
   RefPtr<GMPContentParent> mGMPContentParent;
   nsTArray<UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>> mGetContentParentPromises;
   uint32_t mGMPContentChildCount;
 
-  bool mAsyncShutdownRequired;
-  bool mAsyncShutdownInProgress;
-
   int mChildPid;
 
   // We hold a self reference to ourself while the child process is alive.
   // This ensures that if the GMPService tries to shut us down and drops
   // its reference to us, we stay alive long enough for the child process
   // to terminate gracefully.
   bool mHoldingSelfRef;
 };
--- a/dom/media/gmp/GMPService.h
+++ b/dom/media/gmp/GMPService.h
@@ -70,18 +70,16 @@ public:
   GetGMPVideoDecoder(GMPCrashHelper* aHelper,
                      nsTArray<nsCString>* aTags,
                      const nsACString& aNodeId,
                      UniquePtr<GetGMPVideoDecoderCallback>&& aCallback) override
   {
     return GetDecryptingGMPVideoDecoder(aHelper, aTags, aNodeId, Move(aCallback), 0);
   }
 
-  int32_t AsyncShutdownTimeoutMs();
-
   NS_IMETHOD RunPluginCrashCallbacks(uint32_t aPluginId,
                                      const nsACString& aPluginName) override;
 
   RefPtr<AbstractThread> GetAbstractGMPThread();
 
   void ConnectCrashHelper(uint32_t aPluginId, GMPCrashHelper* aHelper);
   void DisconnectCrashHelper(GMPCrashHelper* aHelper);
 
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -82,39 +82,29 @@ GeckoMediaPluginServiceParent::GetSingle
 
 NS_IMPL_ISUPPORTS_INHERITED(GeckoMediaPluginServiceParent,
                             GeckoMediaPluginService,
                             mozIGeckoMediaPluginChromeService,
                             nsIAsyncShutdownBlocker)
 
 GeckoMediaPluginServiceParent::GeckoMediaPluginServiceParent()
   : mShuttingDown(false)
-#ifdef MOZ_CRASHREPORTER
-  , mAsyncShutdownPluginStatesMutex("GeckoMediaPluginService::mAsyncShutdownPluginStatesMutex")
-#endif
   , mScannedPluginOnDisk(false)
   , mWaitingForPluginsSyncShutdown(false)
   , mInitPromiseMonitor("GeckoMediaPluginServiceParent::mInitPromiseMonitor")
   , mLoadPluginsFromDiskComplete(false)
   , mServiceUserCount(0)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mInitPromise.SetMonitor(&mInitPromiseMonitor);
 }
 
 GeckoMediaPluginServiceParent::~GeckoMediaPluginServiceParent()
 {
   MOZ_ASSERT(mPlugins.IsEmpty());
-  MOZ_ASSERT(mAsyncShutdownPlugins.IsEmpty());
-}
-
-int32_t
-GeckoMediaPluginServiceParent::AsyncShutdownTimeoutMs()
-{
-  return MediaPrefs::GMPAsyncShutdownTimeout();
 }
 
 nsresult
 GeckoMediaPluginServiceParent::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
@@ -283,131 +273,39 @@ GeckoMediaPluginServiceParent::Observe(n
         if (gmpThread) {
           gmpThread->Dispatch(WrapRunnable(this,
                                            &GeckoMediaPluginServiceParent::CrashPlugins),
                               NS_DISPATCH_NORMAL);
         }
       }
     }
   } else if (!strcmp("profile-change-teardown", aTopic)) {
-
-    // How shutdown works:
-    //
-    // Some GMPs require time to do bookkeeping upon shutdown. These GMPs
-    // need to be given time to access storage during shutdown. To signal
-    // that time to shutdown is required, those GMPs implement the
-    // GMPAsyncShutdown interface.
-    //
-    // When we startup the child process, we query the GMP for the
-    // GMPAsyncShutdown interface, and if it's present, we send a message
-    // back to the GMPParent, which then registers the GMPParent by calling
-    // GMPService::AsyncShutdownNeeded().
-    //
-    // On shutdown, we set mWaitingForPluginsSyncShutdown to true, and then
-    // call UnloadPlugins on the GMPThread, and process events on the main
-    // thread until 1. An event sets mWaitingForPluginsSyncShutdown=false on
-    // the main thread; then 2. All async-shutdown plugins have indicated
-    // they have completed shutdown.
-    //
-    // UnloadPlugins() sends close messages for all plugins' API objects to
-    // the GMP interfaces in the child process, and then sends the async
-    // shutdown notifications to child GMPs. When a GMP has completed its
-    // shutdown, it calls GMPAsyncShutdownHost::ShutdownComplete(), which
-    // sends a message back to the parent, which calls
-    // GMPService::AsyncShutdownComplete(). If all plugins requiring async
-    // shutdown have called AsyncShutdownComplete() we stick a dummy event on
-    // the main thread, where the list of pending plugins is checked. We must
-    // use an event to do this, as we must ensure the main thread processes an
-    // event to run its loop. This will unblock the main thread, and shutdown
-    // of other components will proceed.
-    //
-    // During shutdown, each GMPParent starts a timer, and pretends shutdown
-    // is complete if it is taking too long.
-    //
-    // We shutdown in "profile-change-teardown", as the profile dir is
-    // still writable then, and it's required for GMPStorage. We block the
-    // shutdown process by spinning the main thread event loop until all GMPs
-    // have shutdown, or timeout has occurred.
-    //
-    // GMPStorage needs to work up until the shutdown-complete notification
-    // arrives from the GMP process.
-
     mWaitingForPluginsSyncShutdown = true;
 
     nsCOMPtr<nsIThread> gmpThread;
     {
       MutexAutoLock lock(mMutex);
       MOZ_ASSERT(!mShuttingDown);
       mShuttingDown = true;
       gmpThread = mGMPThread;
     }
 
     if (gmpThread) {
-      LOGD(("%s::%s Starting to unload plugins, waiting for first sync shutdown..."
+      LOGD(("%s::%s Starting to unload plugins, waiting for sync shutdown..."
             , __CLASS__, __FUNCTION__));
-#ifdef MOZ_CRASHREPORTER
-      SetAsyncShutdownPluginState(nullptr, '0',
-        NS_LITERAL_CSTRING("Dispatching UnloadPlugins"));
-#endif
       gmpThread->Dispatch(
         NewRunnableMethod(this,
                           &GeckoMediaPluginServiceParent::UnloadPlugins),
         NS_DISPATCH_NORMAL);
 
-#ifdef MOZ_CRASHREPORTER
-      SetAsyncShutdownPluginState(nullptr, '1',
-        NS_LITERAL_CSTRING("Waiting for sync shutdown"));
-#endif
-      // Wait for UnloadPlugins() to do initial sync shutdown...
+      // Wait for UnloadPlugins() to do sync shutdown...
       while (mWaitingForPluginsSyncShutdown) {
         NS_ProcessNextEvent(NS_GetCurrentThread(), true);
       }
 
-#ifdef MOZ_CRASHREPORTER
-      SetAsyncShutdownPluginState(nullptr, '4',
-        NS_LITERAL_CSTRING("Waiting for async shutdown"));
-#endif
-      // Wait for other plugins (if any) to do async shutdown...
-      auto syncShutdownPluginsRemaining =
-        std::numeric_limits<decltype(mAsyncShutdownPlugins.Length())>::max();
-      for (;;) {
-        {
-          MutexAutoLock lock(mMutex);
-          if (mAsyncShutdownPlugins.IsEmpty()) {
-            LOGD(("%s::%s Finished unloading all plugins"
-                  , __CLASS__, __FUNCTION__));
-#if defined(MOZ_CRASHREPORTER)
-            CrashReporter::RemoveCrashReportAnnotation(
-              NS_LITERAL_CSTRING("AsyncPluginShutdown"));
-#endif
-            break;
-          } else if (mAsyncShutdownPlugins.Length() < syncShutdownPluginsRemaining) {
-            // First time here, or number of pending plugins has decreased.
-            // -> Update list of pending plugins in crash report.
-            syncShutdownPluginsRemaining = mAsyncShutdownPlugins.Length();
-            LOGD(("%s::%s Still waiting for %d plugins to shutdown..."
-                  , __CLASS__, __FUNCTION__, (int)syncShutdownPluginsRemaining));
-#if defined(MOZ_CRASHREPORTER)
-            nsAutoCString names;
-            for (const auto& plugin : mAsyncShutdownPlugins) {
-              if (!names.IsEmpty()) { names.Append(NS_LITERAL_CSTRING(", ")); }
-              names.Append(plugin->GetDisplayName());
-            }
-            CrashReporter::AnnotateCrashReport(
-              NS_LITERAL_CSTRING("AsyncPluginShutdown"),
-              names);
-#endif
-          }
-        }
-        NS_ProcessNextEvent(NS_GetCurrentThread(), true);
-      }
-#ifdef MOZ_CRASHREPORTER
-      SetAsyncShutdownPluginState(nullptr, '5',
-        NS_LITERAL_CSTRING("Async shutdown complete"));
-#endif
     } else {
       // GMP thread has already shutdown.
       MOZ_ASSERT(mPlugins.IsEmpty());
       mWaitingForPluginsSyncShutdown = false;
     }
 
   } else if (!strcmp(NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, aTopic)) {
     MOZ_ASSERT(mShuttingDown);
@@ -515,115 +413,16 @@ GeckoMediaPluginServiceParent::Initializ
       [self]() -> void {
         MonitorAutoLock lock(self->mInitPromiseMonitor);
         self->mLoadPluginsFromDiskComplete = true;
         self->mInitPromise.Reject(NS_ERROR_FAILURE, __func__);
       });
 }
 
 void
-GeckoMediaPluginServiceParent::AsyncShutdownNeeded(GMPParent* aParent)
-{
-  LOGD(("%s::%s %p", __CLASS__, __FUNCTION__, aParent));
-  MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
-
-  MutexAutoLock lock(mMutex);
-  MOZ_ASSERT(!mAsyncShutdownPlugins.Contains(aParent));
-  mAsyncShutdownPlugins.AppendElement(aParent);
-}
-
-void
-GeckoMediaPluginServiceParent::AsyncShutdownComplete(GMPParent* aParent)
-{
-  LOGD(("%s::%s %p '%s'", __CLASS__, __FUNCTION__,
-        aParent, aParent->GetDisplayName().get()));
-  MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
-
-  {
-    MutexAutoLock lock(mMutex);
-    mAsyncShutdownPlugins.RemoveElement(aParent);
-  }
-
-  if (mShuttingDownOnGMPThread) {
-    // The main thread may be waiting for async shutdown of plugins,
-    // one of which has completed. Wake up the main thread by sending a task.
-    nsCOMPtr<nsIRunnable> task(NewRunnableMethod(
-      this, &GeckoMediaPluginServiceParent::NotifyAsyncShutdownComplete));
-    NS_DispatchToMainThread(task);
-  }
-}
-
-#ifdef MOZ_CRASHREPORTER
-void
-GeckoMediaPluginServiceParent::SetAsyncShutdownPluginState(GMPParent* aGMPParent,
-                                                           char aId,
-                                                           const nsCString& aState)
-{
-  MutexAutoLock lock(mAsyncShutdownPluginStatesMutex);
-  if (!aGMPParent) {
-    mAsyncShutdownPluginStates.Update(NS_LITERAL_CSTRING("-"),
-                                      NS_LITERAL_CSTRING("-"),
-                                      aId,
-                                      aState);
-    return;
-  }
-  mAsyncShutdownPluginStates.Update(aGMPParent->GetDisplayName(),
-                                    nsPrintfCString("%p", aGMPParent),
-                                    aId,
-                                    aState);
-}
-
-void
-GeckoMediaPluginServiceParent::AsyncShutdownPluginStates::Update(const nsCString& aPlugin,
-                                                                 const nsCString& aInstance,
-                                                                 char aId,
-                                                                 const nsCString& aState)
-{
-  nsCString note;
-  StatesByInstance* instances = mStates.LookupOrAdd(aPlugin);
-  if (!instances) { return; }
-  State* state = instances->LookupOrAdd(aInstance);
-  if (!state) { return; }
-  state->mStateSequence += aId;
-  state->mLastStateDescription = aState;
-  note += '{';
-  bool firstPlugin = true;
-  for (auto pluginIt = mStates.ConstIter(); !pluginIt.Done(); pluginIt.Next()) {
-    if (!firstPlugin) { note += ','; } else { firstPlugin = false; }
-    note += pluginIt.Key();
-    note += ":{";
-    bool firstInstance = true;
-    for (auto instanceIt = pluginIt.UserData()->ConstIter(); !instanceIt.Done(); instanceIt.Next()) {
-      if (!firstInstance) { note += ','; } else { firstInstance = false; }
-      note += instanceIt.Key();
-      note += ":\"";
-      note += instanceIt.UserData()->mStateSequence;
-      note += '=';
-      note += instanceIt.UserData()->mLastStateDescription;
-      note += '"';
-    }
-    note += '}';
-  }
-  note += '}';
-  LOGD(("%s::%s states[%s][%s]='%c'/'%s' -> %s", __CLASS__, __FUNCTION__,
-        aPlugin.get(), aInstance.get(), aId, aState.get(), note.get()));
-  CrashReporter::AnnotateCrashReport(
-    NS_LITERAL_CSTRING("AsyncPluginShutdownStates"),
-    note);
-}
-#endif // MOZ_CRASHREPORTER
-
-void
-GeckoMediaPluginServiceParent::NotifyAsyncShutdownComplete()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // Nothing to do, this task is just used to wake up the event loop in Observe().
-}
-
-void
 GeckoMediaPluginServiceParent::NotifySyncShutdownComplete()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mWaitingForPluginsSyncShutdown = false;
 }
 
 bool
 GeckoMediaPluginServiceParent::IsShuttingDown()
@@ -633,55 +432,39 @@ GeckoMediaPluginServiceParent::IsShuttin
 }
 
 void
 GeckoMediaPluginServiceParent::UnloadPlugins()
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
   MOZ_ASSERT(!mShuttingDownOnGMPThread);
   mShuttingDownOnGMPThread = true;
-#ifdef MOZ_CRASHREPORTER
-      SetAsyncShutdownPluginState(nullptr, '2',
-        NS_LITERAL_CSTRING("Starting to unload plugins"));
-#endif
 
   nsTArray<RefPtr<GMPParent>> plugins;
   {
     MutexAutoLock lock(mMutex);
     // Move all plugins references to a local array. This way mMutex won't be
     // locked when calling CloseActive (to avoid inter-locking).
     Swap(plugins, mPlugins);
   }
 
-  LOGD(("%s::%s plugins:%u including async:%u", __CLASS__, __FUNCTION__,
-        plugins.Length(), mAsyncShutdownPlugins.Length()));
+  LOGD(("%s::%s plugins:%u", __CLASS__, __FUNCTION__,
+        plugins.Length()));
 #ifdef DEBUG
   for (const auto& plugin : plugins) {
     LOGD(("%s::%s plugin: '%s'", __CLASS__, __FUNCTION__,
           plugin->GetDisplayName().get()));
   }
-  for (const auto& plugin : mAsyncShutdownPlugins) {
-    LOGD(("%s::%s async plugin: '%s'", __CLASS__, __FUNCTION__,
-          plugin->GetDisplayName().get()));
-  }
 #endif
   // Note: CloseActive may be async; it could actually finish
   // shutting down when all the plugins have unloaded.
   for (const auto& plugin : plugins) {
-#ifdef MOZ_CRASHREPORTER
-    SetAsyncShutdownPluginState(plugin, 'S',
-        NS_LITERAL_CSTRING("CloseActive"));
-#endif
     plugin->CloseActive(true);
   }
 
-#ifdef MOZ_CRASHREPORTER
-      SetAsyncShutdownPluginState(nullptr, '3',
-        NS_LITERAL_CSTRING("Dispatching sync-shutdown-complete"));
-#endif
   nsCOMPtr<nsIRunnable> task(NewRunnableMethod(
     this, &GeckoMediaPluginServiceParent::NotifySyncShutdownComplete));
   NS_DispatchToMainThread(task);
 }
 
 void
 GeckoMediaPluginServiceParent::CrashPlugins()
 {
@@ -1113,17 +896,16 @@ GeckoMediaPluginServiceParent::RemoveOnG
       deadPlugins.AppendElement(gmp);
       mPlugins.RemoveElementAt(i);
     }
   }
 
   {
     MutexAutoUnlock unlock(mMutex);
     for (auto& gmp : deadPlugins) {
-      gmp->AbortAsyncShutdown();
       gmp->CloseActive(true);
     }
   }
 
   if (aDeleteFromDisk && !inUse) {
     // Ensure the GMP dir and all files in it are writable, so we have
     // permission to delete them.
     directory->SetPermissions(0700);
@@ -1557,19 +1339,16 @@ KillPlugins(const nsTArray<RefPtr<GMPPar
       if (aFilter(parent)) {
         pluginsToKill.AppendElement(parent);
       }
     }
   }
 
   for (size_t i = 0; i < pluginsToKill.Length(); i++) {
     pluginsToKill[i]->CloseActive(false);
-    // Abort async shutdown because we're going to wipe the plugin's storage,
-    // so we don't want it writing more data in its async shutdown path.
-    pluginsToKill[i]->AbortAsyncShutdown();
   }
 }
 
 static nsresult
 DeleteDir(nsIFile* aPath)
 {
   bool exists = false;
   nsresult rv = aPath->Exists(&exists);
--- a/dom/media/gmp/GMPServiceParent.h
+++ b/dom/media/gmp/GMPServiceParent.h
@@ -44,23 +44,16 @@ public:
   NS_IMETHOD GetNodeId(const nsAString& aOrigin,
                        const nsAString& aTopLevelOrigin,
                        const nsAString& aGMPName,
                        UniquePtr<GetNodeIdCallback>&& aCallback) override;
 
   NS_DECL_MOZIGECKOMEDIAPLUGINCHROMESERVICE
   NS_DECL_NSIOBSERVER
 
-  void AsyncShutdownNeeded(GMPParent* aParent);
-  void AsyncShutdownComplete(GMPParent* aParent);
-
-  int32_t AsyncShutdownTimeoutMs();
-#ifdef MOZ_CRASHREPORTER
-  void SetAsyncShutdownPluginState(GMPParent* aGMPParent, char aId, const nsCString& aState);
-#endif // MOZ_CRASHREPORTER
   RefPtr<GenericPromise> EnsureInitialized();
   RefPtr<GenericPromise> AsyncAddPluginDirectory(const nsAString& aDirectory);
 
   // GMP thread access only
   bool IsShuttingDown();
 
   already_AddRefed<GMPStorage> GetMemoryStorageFor(const nsACString& aNodeId);
   nsresult ForgetThisSiteNative(const nsAString& aSite,
@@ -89,26 +82,23 @@ private:
                                                    size_t* aOutPluginIndex);
 
   nsresult GetNodeId(const nsAString& aOrigin, const nsAString& aTopLevelOrigin,
                      const nsAString& aGMPName, nsACString& aOutId);
 
   void UnloadPlugins();
   void CrashPlugins();
   void NotifySyncShutdownComplete();
-  void NotifyAsyncShutdownComplete();
 
   void ProcessPossiblePlugin(nsIFile* aDir);
 
   void RemoveOnGMPThread(const nsAString& aDirectory,
                          const bool aDeleteFromDisk,
                          const bool aCanDefer);
 
-  nsresult SetAsyncShutdownTimeout();
-
   struct DirectoryFilter {
     virtual bool operator()(nsIFile* aPath) = 0;
     ~DirectoryFilter() {}
   };
   void ClearNodeIdAndPlugin(DirectoryFilter& aFilter);
   void ClearNodeIdAndPlugin(nsIFile* aPluginStorageDir,
                             DirectoryFilter& aFilter);
   void ForgetThisSiteOnGMPThread(const nsACString& aOrigin,
@@ -161,32 +151,16 @@ private:
     nsString mPath;
     EOperation mOperation;
     bool mDefer;
   };
 
   // Protected by mMutex from the base class.
   nsTArray<RefPtr<GMPParent>> mPlugins;
   bool mShuttingDown;
-  nsTArray<RefPtr<GMPParent>> mAsyncShutdownPlugins;
-
-#ifdef MOZ_CRASHREPORTER
-  Mutex mAsyncShutdownPluginStatesMutex; // Protects mAsyncShutdownPluginStates.
-  class AsyncShutdownPluginStates
-  {
-  public:
-    void Update(const nsCString& aPlugin, const nsCString& aInstance,
-                char aId, const nsCString& aState);
-  private:
-    struct State { nsCString mStateSequence; nsCString mLastStateDescription; };
-    typedef nsClassHashtable<nsCStringHashKey, State> StatesByInstance;
-    typedef nsClassHashtable<nsCStringHashKey, StatesByInstance> StateInstancesByPlugin;
-    StateInstancesByPlugin mStates;
-  } mAsyncShutdownPluginStates;
-#endif // MOZ_CRASHREPORTER
 
   // True if we've inspected MOZ_GMP_PATH on the GMP thread and loaded any
   // plugins found there into mPlugins.
   Atomic<bool> mScannedPluginOnDisk;
 
   template<typename T>
   class MainThreadOnly {
   public:
--- a/dom/media/gmp/PGMP.ipdl
+++ b/dom/media/gmp/PGMP.ipdl
@@ -23,21 +23,17 @@ intr protocol PGMP
 
 parent:
   async PCrashReporter(NativeThreadId tid);
   async PGMPTimer();
   async PGMPStorage();
 
   async PGMPContentChildDestroyed();
 
-  async AsyncShutdownComplete();
-  async AsyncShutdownRequired();
-
 child:
-  async BeginAsyncShutdown();
   async CrashPluginNow();
   intr StartPlugin(nsString adapter);
   async SetNodeId(nsCString nodeId);
   async PreloadLibs(nsCString libs);
   async CloseActive();
 };
 
 } // namespace gmp
deleted file mode 100644
--- a/dom/media/gmp/gmp-api/gmp-async-shutdown.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-* Copyright 2013, Mozilla Foundation and contributors
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#ifndef GMP_ASYNC_SHUTDOWN_H_
-#define GMP_ASYNC_SHUTDOWN_H_
-
-#define GMP_API_ASYNC_SHUTDOWN "async-shutdown"
-
-// API exposed by the plugin library to manage asynchronous shutdown.
-// Some plugins require special cleanup which may need to make calls
-// to host services and wait for async responses.
-//
-// To enable a plugins to block shutdown until its async shutdown is
-// complete, implement the GMPAsyncShutdown interface and return it when
-// your plugin's GMPGetAPI function is called with "async-shutdown".
-// When your GMPAsyncShutdown's BeginShutdown() implementation is called
-// by the GMP host, you should initate your async shutdown process.
-// Once you have completed shutdown, call the ShutdownComplete() function
-// of the GMPAsyncShutdownHost that is passed as the host argument to the
-// GMPGetAPI() call.
-//
-// Note: Your GMP's GMPShutdown function will still be called after your
-// call to ShutdownComplete().
-//
-// API name macro: GMP_API_ASYNC_SHUTDOWN
-// Host API: GMPAsyncShutdownHost
-class GMPAsyncShutdown {
-public:
-  virtual ~GMPAsyncShutdown() {}
-
-  virtual void BeginShutdown() = 0;
-};
-
-class GMPAsyncShutdownHost {
-public:
-  virtual ~GMPAsyncShutdownHost() {}
-
-  virtual void ShutdownComplete() = 0;
-};
-
-#endif // GMP_ASYNC_SHUTDOWN_H_
--- a/dom/media/gmp/moz.build
+++ b/dom/media/gmp/moz.build
@@ -7,17 +7,16 @@
 XPIDL_MODULE = 'content_geckomediaplugins'
 
 XPIDL_SOURCES += [
     'mozIGeckoMediaPluginChromeService.idl',
     'mozIGeckoMediaPluginService.idl',
 ]
 
 EXPORTS += [
-    'gmp-api/gmp-async-shutdown.h',
     'gmp-api/gmp-decryption.h',
     'gmp-api/gmp-entrypoints.h',
     'gmp-api/gmp-errors.h',
     'gmp-api/gmp-platform.h',
     'gmp-api/gmp-storage.h',
     'gmp-api/gmp-video-codec.h',
     'gmp-api/gmp-video-decode.h',
     'gmp-api/gmp-video-encode.h',
--- a/dom/media/gtest/TestGMPCrossOrigin.cpp
+++ b/dom/media/gtest/TestGMPCrossOrigin.cpp
@@ -1090,102 +1090,16 @@ class GMPStorageTest : public GMPDecrypt
               &GMPStorageTest::SetFinished));
 
     CreateDecryptor(NS_LITERAL_STRING("http://pb1.com"),
                     NS_LITERAL_STRING("http://pb2.com"),
                     true,
                     NS_LITERAL_CSTRING("retrieve pbdata"));
   }
 
-  void NextAsyncShutdownTimeoutTest(nsIRunnable* aContinuation)
-  {
-    if (mDecryptor) {
-      Update(NS_LITERAL_CSTRING("shutdown-mode timeout"));
-      Shutdown();
-    }
-    nsCOMPtr<nsIThread> thread(GetGMPThread());
-    thread->Dispatch(aContinuation, NS_DISPATCH_NORMAL);
-  }
-
-  void CreateAsyncShutdownTimeoutGMP(const nsAString& aOrigin1,
-                                     const nsAString& aOrigin2,
-                                     void (GMPStorageTest::*aCallback)()) {
-    nsCOMPtr<nsIRunnable> continuation(
-      NewRunnableMethod<nsCOMPtr<nsIRunnable>>(
-        this,
-        &GMPStorageTest::NextAsyncShutdownTimeoutTest,
-        NewRunnableMethod(this, aCallback)));
-
-    CreateDecryptor(GetNodeId(aOrigin1, aOrigin2, false), continuation);
-  }
-
-  void TestAsyncShutdownTimeout() {
-    // Create decryptors that timeout in their async shutdown.
-    // If the gtest hangs on shutdown, test fails!
-    CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("http://example7.com"),
-                                  NS_LITERAL_STRING("http://example8.com"),
-                                  &GMPStorageTest::TestAsyncShutdownTimeout2);
-  };
-
-  void TestAsyncShutdownTimeout2() {
-    CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("http://example9.com"),
-                                  NS_LITERAL_STRING("http://example10.com"),
-                                  &GMPStorageTest::TestAsyncShutdownTimeout3);
-  };
-
-  void TestAsyncShutdownTimeout3() {
-    CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("http://example11.com"),
-                                  NS_LITERAL_STRING("http://example12.com"),
-                                  &GMPStorageTest::SetFinished);
-  };
-
-  void TestAsyncShutdownStorage() {
-    // Instruct the GMP to write a token (the current timestamp, so it's
-    // unique) during async shutdown, then shutdown the plugin, re-create
-    // it, and check that the token was successfully stored.
-    auto t = time(0);
-    nsCString update("shutdown-mode token ");
-    nsCString token;
-    token.AppendInt((int64_t)t);
-    update.Append(token);
-
-    // Wait for a response from the GMP, so we know it's had time to receive
-    // the token.
-    nsCString response("shutdown-token received ");
-    response.Append(token);
-    Expect(response, NewRunnableMethod<nsCString>(this,
-      &GMPStorageTest::TestAsyncShutdownStorage_ReceivedShutdownToken, token));
-
-    // Test that a GMP can write to storage during shutdown, and retrieve
-    // that written data in a subsequent session.
-    CreateDecryptor(NS_LITERAL_STRING("http://example13.com"),
-                    NS_LITERAL_STRING("http://example14.com"),
-                    false,
-                    update);
-  }
-
-  void TestAsyncShutdownStorage_ReceivedShutdownToken(const nsCString& aToken) {
-    ShutdownThen(NewRunnableMethod<nsCString>(this,
-      &GMPStorageTest::TestAsyncShutdownStorage_AsyncShutdownComplete, aToken));
-  }
-
-  void TestAsyncShutdownStorage_AsyncShutdownComplete(const nsCString& aToken) {
-    // Create a new instance of the plugin, retrieve the token written
-    // during shutdown and verify it is correct.
-    nsCString response("retrieved shutdown-token ");
-    response.Append(aToken);
-    Expect(response,
-           NewRunnableMethod(this, &GMPStorageTest::SetFinished));
-
-    CreateDecryptor(NS_LITERAL_STRING("http://example13.com"),
-                    NS_LITERAL_STRING("http://example14.com"),
-                    false,
-                    NS_LITERAL_CSTRING("retrieve-shutdown-token"));
-  }
-
 #if defined(XP_WIN)
   void TestOutputProtection() {
     Shutdown();
 
     Expect(NS_LITERAL_CSTRING("OP tests completed"),
            NewRunnableMethod(this, &GMPStorageTest::SetFinished));
 
     CreateDecryptor(NS_LITERAL_STRING("http://example15.com"),
@@ -1509,26 +1423,16 @@ TEST(GeckoMediaPlugins, GMPStorageCrossO
   runner->DoTest(&GMPStorageTest::TestCrossOriginStorage);
 }
 
 TEST(GeckoMediaPlugins, GMPStoragePrivateBrowsing) {
   RefPtr<GMPStorageTest> runner = new GMPStorageTest();
   runner->DoTest(&GMPStorageTest::TestPBStorage);
 }
 
-TEST(GeckoMediaPlugins, GMPStorageAsyncShutdownTimeout) {
-  RefPtr<GMPStorageTest> runner = new GMPStorageTest();
-  runner->DoTest(&GMPStorageTest::TestAsyncShutdownTimeout);
-}
-
-TEST(GeckoMediaPlugins, GMPStorageAsyncShutdownStorage) {
-  RefPtr<GMPStorageTest> runner = new GMPStorageTest();
-  runner->DoTest(&GMPStorageTest::TestAsyncShutdownStorage);
-}
-
 TEST(GeckoMediaPlugins, GMPPluginVoucher) {
   RefPtr<GMPStorageTest> runner = new GMPStorageTest();
   runner->DoTest(&GMPStorageTest::TestPluginVoucher);
 }
 
 #if defined(XP_WIN)
 TEST(GeckoMediaPlugins, GMPOutputProtection) {
   RefPtr<GMPStorageTest> runner = new GMPStorageTest();