dom/media/ipc/RDDProcessManager.h
author Sylvestre Ledru <sledru@mozilla.com>
Mon, 19 Nov 2018 13:25:37 +0000
changeset 446960 0ceae9db9ec0be18daa1a279511ad305723185d4
parent 445369 1a991ac2e1f8db3b9410d1cea09686ebfc38ad1b
child 475066 2db647dcdf1c9f5385da89c3b2b738c2fd35544c
permissions -rw-r--r--
Bug 1204606 - Reformat of dom/media r=jya # skip-blame Differential Revision: https://phabricator.services.mozilla.com/D12251

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 _include_dom_media_ipc_RDDProcessManager_h_
#define _include_dom_media_ipc_RDDProcessManager_h_
#include "mozilla/RDDProcessHost.h"

#include "mozilla/ipc/TaskFactory.h"

namespace mozilla {

class MemoryReportingProcess;
class PRemoteDecoderManagerChild;
class RDDChild;

// The RDDProcessManager is a singleton responsible for creating RDD-bound
// objects that may live in another process. Currently, it provides access
// to the RDD process via ContentParent.
class RDDProcessManager final : public RDDProcessHost::Listener {
 public:
  static void Initialize();
  static void Shutdown();
  static RDDProcessManager* Get();

  ~RDDProcessManager();

  // If not using a RDD process, launch a new RDD process asynchronously.
  void LaunchRDDProcess();

  // Ensure that RDD-bound methods can be used. If no RDD process is being
  // used, or one is launched and ready, this function returns immediately.
  // Otherwise it blocks until the RDD process has finished launching.
  bool EnsureRDDReady();

  bool CreateContentBridge(base::ProcessId aOtherProcess,
                           mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>*
                               aOutRemoteDecoderManager);

  void OnProcessLaunchComplete(RDDProcessHost* aHost) override;
  void OnProcessUnexpectedShutdown(RDDProcessHost* aHost) override;

  // Notify the RDDProcessManager that a top-level PRDD protocol has been
  // terminated. This may be called from any thread.
  void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken);

  // Used for tests and diagnostics
  void KillProcess();

  // Returns -1 if there is no RDD process, or the platform pid for it.
  base::ProcessId RDDProcessPid();

  // If a RDD process is present, create a MemoryReportingProcess object.
  // Otherwise, return null.
  RefPtr<MemoryReportingProcess> GetProcessMemoryReporter();

  // Returns access to the PRDD protocol if a RDD process is present.
  RDDChild* GetRDDChild() { return mRDDChild; }

  // Returns whether or not a RDD process was ever launched.
  bool AttemptedRDDProcess() const { return mNumProcessAttempts > 0; }

 private:
  // Called from our xpcom-shutdown observer.
  void OnXPCOMShutdown();

  RDDProcessManager();

  // Shutdown the RDD process.
  void CleanShutdown();
  void DestroyProcess();

  DISALLOW_COPY_AND_ASSIGN(RDDProcessManager);

  class Observer final : public nsIObserver {
   public:
    NS_DECL_ISUPPORTS
    NS_DECL_NSIOBSERVER
    explicit Observer(RDDProcessManager* aManager);

   protected:
    ~Observer() {}

    RDDProcessManager* mManager;
  };
  friend class Observer;

 private:
  RefPtr<Observer> mObserver;
  mozilla::ipc::TaskFactory<RDDProcessManager> mTaskFactory;
  uint32_t mNumProcessAttempts;

  // Fields that are associated with the current RDD process.
  RDDProcessHost* mProcess;
  uint64_t mProcessToken;
  RDDChild* mRDDChild;
};

}  // namespace mozilla

#endif  // _include_dom_media_ipc_RDDProcessManager_h_