summaryrefslogtreecommitdiffstats
path: root/xpcom/build/Services.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xpcom/build/Services.py283
1 files changed, 283 insertions, 0 deletions
diff --git a/xpcom/build/Services.py b/xpcom/build/Services.py
new file mode 100644
index 0000000000..495d052560
--- /dev/null
+++ b/xpcom/build/Services.py
@@ -0,0 +1,283 @@
+# 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/.
+
+import buildconfig
+
+
+services = []
+
+
+def service(name, iface, contractid):
+ """Define a convenient service getter"""
+ services.append((name, iface, contractid))
+
+
+# The `name` parameter is derived from the `iface` by removing the `nsI`
+# prefix. (This often matches the `contractid`, but not always.) The only
+# exceptions are when that would result in a misleading name, e.g. for
+# "@mozilla.org/file/directory_service;1".
+service("ChromeRegistry", "nsIChromeRegistry", "@mozilla.org/chrome/chrome-registry;1")
+service(
+ "ToolkitChromeRegistry",
+ "nsIToolkitChromeRegistry",
+ "@mozilla.org/chrome/chrome-registry;1",
+)
+service(
+ "XULChromeRegistry", "nsIXULChromeRegistry", "@mozilla.org/chrome/chrome-registry;1"
+)
+service("DirectoryService", "nsIProperties", "@mozilla.org/file/directory_service;1"),
+service("IOService", "nsIIOService", "@mozilla.org/network/io-service;1")
+service("ObserverService", "nsIObserverService", "@mozilla.org/observer-service;1")
+service(
+ "StringBundleService", "nsIStringBundleService", "@mozilla.org/intl/stringbundle;1"
+)
+service("PermissionManager", "nsIPermissionManager", "@mozilla.org/permissionmanager;1")
+service("PrefService", "nsIPrefService", "@mozilla.org/preferences-service;1")
+service(
+ "ServiceWorkerManager",
+ "nsIServiceWorkerManager",
+ "@mozilla.org/serviceworkers/manager;1",
+)
+service(
+ "AsyncShutdownService",
+ "nsIAsyncShutdownService",
+ "@mozilla.org/async-shutdown-service;1",
+)
+service("UUIDGenerator", "nsIUUIDGenerator", "@mozilla.org/uuid-generator;1")
+service("GfxInfo", "nsIGfxInfo", "@mozilla.org/gfx/info;1")
+service(
+ "SocketTransportService",
+ "nsISocketTransportService",
+ "@mozilla.org/network/socket-transport-service;1",
+)
+service(
+ "StreamTransportService",
+ "nsIStreamTransportService",
+ "@mozilla.org/network/stream-transport-service;1",
+)
+service(
+ "CacheStorageService",
+ "nsICacheStorageService",
+ "@mozilla.org/netwerk/cache-storage-service;1",
+)
+service("URIClassifier", "nsIURIClassifier", "@mozilla.org/uriclassifierservice")
+service(
+ "HttpActivityDistributor",
+ "nsIHttpActivityDistributor",
+ "@mozilla.org/network/http-activity-distributor;1",
+)
+service("History", "mozilla::IHistory", "@mozilla.org/browser/history;1")
+service("ThirdPartyUtil", "mozIThirdPartyUtil", "@mozilla.org/thirdpartyutil;1")
+service("URIFixup", "nsIURIFixup", "@mozilla.org/docshell/uri-fixup;1")
+service("Bits", "nsIBits", "@mozilla.org/bits;1")
+# If you want nsIXULAppInfo, as returned by Services.jsm, you need to call:
+#
+# nsCOMPtr<nsIXULRuntime> runtime = mozilla::services::GetXULRuntime();
+# nsCOMPtr<nsIXULAppInfo> appInfo = do_QueryInterface(runtime);
+#
+# for C++ or:
+#
+# let appInfo =
+# get_XULRuntime().and_then(|p| p.query_interface::<nsIXULAppInfo>());
+#
+# for Rust. Note that not all applications (e.g. xpcshell) implement
+# nsIXULAppInfo.
+service("XULRuntime", "nsIXULRuntime", "@mozilla.org/xre/app-info;1")
+
+if buildconfig.substs.get("ENABLE_REMOTE_AGENT"):
+ service("RemoteAgent", "nsIRemoteAgent", "@mozilla.org/remote/agent;1")
+
+# The definition file needs access to the definitions of the particular
+# interfaces. If you add a new interface here, make sure the necessary includes
+# are also listed in the following code snippet.
+CPP_INCLUDES = """
+#include "mozilla/Likely.h"
+#include "mozilla/Services.h"
+#include "mozIThirdPartyUtil.h"
+#include "nsComponentManager.h"
+#include "nsIObserverService.h"
+#include "nsNetCID.h"
+#include "nsObserverService.h"
+#include "nsXPCOMPrivate.h"
+#include "nsIIOService.h"
+#include "nsIDirectoryService.h"
+#include "nsIChromeRegistry.h"
+#include "nsIStringBundle.h"
+#include "nsIToolkitChromeRegistry.h"
+#include "IHistory.h"
+#include "nsIXPConnect.h"
+#include "nsIPermissionManager.h"
+#include "nsIPrefService.h"
+#include "nsIServiceWorkerManager.h"
+#include "nsICacheStorageService.h"
+#include "nsIStreamTransportService.h"
+#include "nsISocketTransportService.h"
+#include "nsIURIClassifier.h"
+#include "nsIHttpActivityObserver.h"
+#include "nsIAsyncShutdown.h"
+#include "nsIUUIDGenerator.h"
+#include "nsIGfxInfo.h"
+#include "nsIURIFixup.h"
+#include "nsIBits.h"
+#include "nsIXULRuntime.h"
+"""
+
+if buildconfig.substs.get("ENABLE_REMOTE_AGENT"):
+ CPP_INCLUDES += '#include "nsIRemoteAgent.h"'
+
+
+#####
+# Codegen Logic
+#
+# The following code consumes the data listed above to generate the files
+# Services.h, Services.cpp, and services.rs which provide access to these
+# service getters in both rust and C++ code.
+#
+# XXX(nika): would it be a good idea to unify Services.jsm into here too?
+
+
+def services_h(output):
+ output.write(
+ """\
+/* THIS FILE IS GENERATED BY Services.py - DO NOT EDIT */
+
+#ifndef mozilla_Services_h
+#define mozilla_Services_h
+
+#include "nscore.h"
+#include "nsCOMPtr.h"
+"""
+ )
+
+ for (name, iface, contractid) in services:
+ # Write out a forward declaration for the type in question
+ segs = iface.split("::")
+ for namespace in segs[:-1]:
+ output.write("namespace %s {\n" % namespace)
+ output.write("class %s;\n" % segs[-1])
+ for namespace in reversed(segs[:-1]):
+ output.write("} // namespace %s\n" % namespace)
+
+ # Write out the C-style function signature, and the C++ wrapper
+ output.write(
+ """
+#ifdef MOZILLA_INTERNAL_API
+extern "C" {
+/**
+ * NOTE: Don't call this method directly, instead call mozilla::services::Get%(name)s.
+ * It is used to expose XPCOM services to rust code. The return value is already addrefed.
+ */
+%(type)s* XPCOMService_Get%(name)s();
+} // extern "C"
+
+namespace mozilla {
+namespace services {
+/**
+ * Fetch a cached instance of the %(name)s.
+ * This function will return nullptr during XPCOM shutdown.
+ */
+inline already_AddRefed<%(type)s>
+Get%(name)s()
+{
+ return already_AddRefed<%(type)s>(XPCOMService_Get%(name)s());
+}
+} // namespace services
+} // namespace mozilla
+#endif // defined(MOZILLA_INTERNAL_API)
+"""
+ % {
+ "name": name,
+ "type": iface,
+ }
+ )
+
+ output.write("#endif // !defined(mozilla_Services_h)\n")
+
+
+def services_cpp(output):
+ output.write(
+ """\
+/* THIS FILE IS GENERATED BY Services.py - DO NOT EDIT */
+"""
+ )
+ output.write(CPP_INCLUDES)
+
+ for (name, iface, contractid) in services:
+ output.write(
+ """
+static %(type)s* g%(name)s = nullptr;
+
+extern "C" {
+/**
+ * NOTE: Don't call this method directly, instead call `mozilla::services::Get%(name)s`.
+ * This method is extern "C" to expose XPCOM services to rust code.
+ * The return value is already addrefed.
+ */
+%(type)s*
+XPCOMService_Get%(name)s()
+{
+ if (MOZ_UNLIKELY(gXPCOMShuttingDown)) {
+ return nullptr;
+ }
+ if (!g%(name)s) {
+ nsCOMPtr<%(type)s> os = do_GetService("%(contractid)s");
+ os.swap(g%(name)s);
+ }
+ return do_AddRef(g%(name)s).take();
+}
+} // extern "C"
+"""
+ % {
+ "name": name,
+ "type": iface,
+ "contractid": contractid,
+ }
+ )
+
+ output.write(
+ """
+/**
+ * Clears service cache, sets gXPCOMShuttingDown
+ */
+void
+mozilla::services::Shutdown()
+{
+ gXPCOMShuttingDown = true;
+"""
+ )
+ for (name, iface, contractid) in services:
+ output.write(" NS_IF_RELEASE(g%s);\n" % name)
+ output.write("}\n")
+
+
+def services_rs(output):
+ output.write(
+ """\
+/* THIS FILE IS GENERATED BY Services.py - DO NOT EDIT */
+
+use crate::RefPtr;
+"""
+ )
+
+ for (name, iface, _) in services:
+ # NOTE: We can't support namespaced interfaces in rust code, so we have to ignore them.
+ if "::" in iface:
+ continue
+
+ output.write(
+ """
+/// Fetches a cached reference to the `%(name)s`.
+/// This function will return `None` during XPCOM shutdown.
+pub fn get_%(name)s() -> Option<RefPtr<crate::interfaces::%(type)s>> {
+ extern "C" {
+ fn XPCOMService_Get%(name)s() -> *mut crate::interfaces::%(type)s;
+ }
+ unsafe { RefPtr::from_raw_dont_addref(XPCOMService_Get%(name)s()) }
+}
+"""
+ % {
+ "name": name,
+ "type": iface,
+ }
+ )