1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef _include_dom_media_ipc_RDDProcessManager_h_
7 #define _include_dom_media_ipc_RDDProcessManager_h_
8 #include "mozilla/RDDProcessHost.h"
9 
10 #include "mozilla/ipc/TaskFactory.h"
11 
12 namespace mozilla {
13 
14 class MemoryReportingProcess;
15 class PRemoteDecoderManagerChild;
16 class RDDChild;
17 
18 // The RDDProcessManager is a singleton responsible for creating RDD-bound
19 // objects that may live in another process. Currently, it provides access
20 // to the RDD process via ContentParent.
21 class RDDProcessManager final : public RDDProcessHost::Listener {
22   friend class RDDChild;
23 
24  public:
25   static void Initialize();
26   static void Shutdown();
27   static RDDProcessManager* Get();
28 
29   ~RDDProcessManager();
30 
31   // If not using a RDD process, launch a new RDD process asynchronously.
32   bool LaunchRDDProcess();
33   bool IsRDDProcessLaunching();
34 
35   // Ensure that RDD-bound methods can be used. If no RDD process is being
36   // used, or one is launched and ready, this function returns immediately.
37   // Otherwise it blocks until the RDD process has finished launching.
38   bool EnsureRDDReady();
39 
40   bool CreateContentBridge(base::ProcessId aOtherProcess,
41                            mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>*
42                                aOutRemoteDecoderManager);
43 
44   void OnProcessLaunchComplete(RDDProcessHost* aHost) override;
45   void OnProcessUnexpectedShutdown(RDDProcessHost* aHost) override;
46 
47   // Notify the RDDProcessManager that a top-level PRDD protocol has been
48   // terminated. This may be called from any thread.
49   void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken);
50 
51   // Used for tests and diagnostics
52   void KillProcess();
53 
54   // Returns -1 if there is no RDD process, or the platform pid for it.
55   base::ProcessId RDDProcessPid();
56 
57   // If a RDD process is present, create a MemoryReportingProcess object.
58   // Otherwise, return null.
59   RefPtr<MemoryReportingProcess> GetProcessMemoryReporter();
60 
61   // Returns access to the PRDD protocol if a RDD process is present.
GetRDDChild()62   RDDChild* GetRDDChild() { return mRDDChild; }
63 
64   // Returns whether or not a RDD process was ever launched.
AttemptedRDDProcess()65   bool AttemptedRDDProcess() const { return mNumProcessAttempts > 0; }
66 
67   // Returns the RDD Process
Process()68   RDDProcessHost* Process() { return mProcess; }
69 
70  private:
71   bool CreateVideoBridge();
72 
73   // Called from our xpcom-shutdown observer.
74   void OnXPCOMShutdown();
75   void OnPreferenceChange(const char16_t* aData);
76 
77   RDDProcessManager();
78 
79   // Shutdown the RDD process.
80   void CleanShutdown();
81   void DestroyProcess();
82 
83   DISALLOW_COPY_AND_ASSIGN(RDDProcessManager);
84 
85   class Observer final : public nsIObserver {
86    public:
87     NS_DECL_ISUPPORTS
88     NS_DECL_NSIOBSERVER
89     explicit Observer(RDDProcessManager* aManager);
90 
91    protected:
92     ~Observer() = default;
93 
94     RDDProcessManager* mManager;
95   };
96   friend class Observer;
97 
98  private:
99   RefPtr<Observer> mObserver;
100   mozilla::ipc::TaskFactory<RDDProcessManager> mTaskFactory;
101   uint32_t mNumProcessAttempts;
102 
103   // Fields that are associated with the current RDD process.
104   RDDProcessHost* mProcess;
105   uint64_t mProcessToken;
106   RDDChild* mRDDChild;
107   // Collects any pref changes that occur during process launch (after
108   // the initial map is passed in command-line arguments) to be sent
109   // when the process can receive IPC messages.
110   nsTArray<mozilla::dom::Pref> mQueuedPrefs;
111 };
112 
113 }  // namespace mozilla
114 
115 #endif  // _include_dom_media_ipc_RDDProcessManager_h_
116