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 
7 #ifndef mozilla_Module_h
8 #define mozilla_Module_h
9 
10 #include "nscore.h"
11 #include "nsID.h"
12 #include "nsIFactory.h"
13 #include "nsCOMPtr.h"  // for already_AddRefed
14 
15 namespace mozilla {
16 
17 /**
18  * A module implements one or more XPCOM components. This structure is used
19  * for both binary and script modules, but the registration members
20  * (cids/contractids/categoryentries) are unused for modules which are loaded
21  * via a module loader.
22  */
23 struct Module {
24   static const unsigned int kVersion = 99;
25 
26   struct CIDEntry;
27 
28   typedef already_AddRefed<nsIFactory> (*GetFactoryProcPtr)(
29       const Module& module, const CIDEntry& entry);
30 
31   typedef nsresult (*ConstructorProcPtr)(nsISupports* aOuter, const nsIID& aIID,
32                                          void** aResult);
33 
34   typedef nsresult (*LoadFuncPtr)();
35   typedef void (*UnloadFuncPtr)();
36 
37   /**
38    * This selector allows CIDEntrys to be marked so that they're only loaded
39    * into certain kinds of processes. Selectors can be combined.
40    */
41   // Note: This must be kept in sync with the selector matching in
42   // nsComponentManager.cpp.
43   enum ProcessSelector {
44     ANY_PROCESS = 0x0,
45     MAIN_PROCESS_ONLY = 0x1,
46     CONTENT_PROCESS_ONLY = 0x2,
47 
48     /**
49      * By default, modules are not loaded in the GPU, VR, Socket, RDD, Utility
50      * and IPDLUnitTest processes, even if ANY_PROCESS is specified. This flag
51      * enables a module in the relevant process.
52      *
53      * NOTE: IPDLUnitTest does not have its own flag, and will only load a
54      * module if it is enabled in all processes.
55      */
56     ALLOW_IN_GPU_PROCESS = 0x4,
57     ALLOW_IN_VR_PROCESS = 0x8,
58     ALLOW_IN_SOCKET_PROCESS = 0x10,
59     ALLOW_IN_RDD_PROCESS = 0x20,
60     ALLOW_IN_UTILITY_PROCESS = 0x30,
61     ALLOW_IN_GPU_AND_MAIN_PROCESS = ALLOW_IN_GPU_PROCESS | MAIN_PROCESS_ONLY,
62     ALLOW_IN_GPU_AND_VR_PROCESS = ALLOW_IN_GPU_PROCESS | ALLOW_IN_VR_PROCESS,
63     ALLOW_IN_GPU_AND_SOCKET_PROCESS =
64         ALLOW_IN_GPU_PROCESS | ALLOW_IN_SOCKET_PROCESS,
65     ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS =
66         ALLOW_IN_GPU_PROCESS | ALLOW_IN_VR_PROCESS | ALLOW_IN_SOCKET_PROCESS,
67     ALLOW_IN_RDD_AND_SOCKET_PROCESS =
68         ALLOW_IN_RDD_PROCESS | ALLOW_IN_SOCKET_PROCESS,
69     ALLOW_IN_GPU_RDD_AND_SOCKET_PROCESS =
70         ALLOW_IN_GPU_PROCESS | ALLOW_IN_RDD_PROCESS | ALLOW_IN_SOCKET_PROCESS,
71     ALLOW_IN_GPU_RDD_SOCKET_AND_UTILITY_PROCESS =
72         ALLOW_IN_GPU_PROCESS | ALLOW_IN_RDD_PROCESS | ALLOW_IN_SOCKET_PROCESS,
73     ALLOW_IN_GPU_RDD_VR_AND_SOCKET_PROCESS =
74         ALLOW_IN_GPU_PROCESS | ALLOW_IN_RDD_PROCESS | ALLOW_IN_VR_PROCESS |
75         ALLOW_IN_SOCKET_PROCESS,
76     ALLOW_IN_GPU_RDD_VR_SOCKET_AND_UTILITY_PROCESS =
77         ALLOW_IN_GPU_PROCESS | ALLOW_IN_RDD_PROCESS | ALLOW_IN_VR_PROCESS |
78         ALLOW_IN_SOCKET_PROCESS | ALLOW_IN_UTILITY_PROCESS
79   };
80 
81   static constexpr size_t kMaxProcessSelector =
82       size_t(ProcessSelector::ALLOW_IN_GPU_RDD_VR_SOCKET_AND_UTILITY_PROCESS);
83 
84   /**
85    * This allows category entries to be marked so that they are or are
86    * not loaded when in backgroundtask mode.
87    */
88   // Note: This must be kept in sync with the selector matching in
89   // StaticComponents.cpp.in.
90   enum BackgroundTasksSelector {
91     NO_TASKS = 0x0,
92     ALL_TASKS = 0xFFFF,
93   };
94 
95   /**
96    * The constructor callback is an implementation detail of the default binary
97    * loader and may be null.
98    */
99   struct CIDEntry {
100     const nsCID* cid;
101     bool service;
102     GetFactoryProcPtr getFactoryProc;
103     ConstructorProcPtr constructorProc;
104     ProcessSelector processSelector;
105   };
106 
107   struct ContractIDEntry {
108     const char* contractid;
109     nsID const* cid;
110     ProcessSelector processSelector;
111   };
112 
113   struct CategoryEntry {
114     const char* category;
115     const char* entry;
116     const char* value;
117   };
118 
119   /**
120    * Binary compatibility check, should be kModuleVersion.
121    */
122   unsigned int mVersion;
123 
124   /**
125    * An array of CIDs (class IDs) implemented by this module. The final entry
126    * should be { nullptr }.
127    */
128   const CIDEntry* mCIDs;
129 
130   /**
131    * An array of mappings from contractid to CID. The final entry should
132    * be { nullptr }.
133    */
134   const ContractIDEntry* mContractIDs;
135 
136   /**
137    * An array of category manager entries. The final entry should be
138    * { nullptr }.
139    */
140   const CategoryEntry* mCategoryEntries;
141 
142   /**
143    * When the component manager tries to get the factory for a CID, it first
144    * checks for this module-level getfactory callback. If this function is
145    * not implemented, it checks the CIDEntry getfactory callback. If that is
146    * also nullptr, a generic factory is generated using the CIDEntry
147    * constructor callback which must be non-nullptr.
148    */
149   GetFactoryProcPtr getFactoryProc;
150 
151   /**
152    * Optional Function which are called when this module is loaded and
153    * at shutdown. These are not C++ constructor/destructors to avoid
154    * calling them too early in startup or too late in shutdown.
155    */
156   LoadFuncPtr loadProc;
157   UnloadFuncPtr unloadProc;
158 
159   /**
160    * Optional flags which control whether the module loads on a process-type
161    * basis.
162    */
163   ProcessSelector selector;
164 };
165 
166 }  // namespace mozilla
167 
168 #endif  // mozilla_Module_h
169