diff options
Diffstat (limited to 'ipc/hal')
-rw-r--r-- | ipc/hal/DaemonRunnables.h | 950 | ||||
-rw-r--r-- | ipc/hal/DaemonSocket.cpp | 263 | ||||
-rw-r--r-- | ipc/hal/DaemonSocket.h | 63 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketConnector.cpp | 244 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketConnector.h | 61 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketConsumer.cpp | 33 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketConsumer.h | 68 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketMessageHandlers.h | 40 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketPDU.cpp | 202 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketPDU.h | 94 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketPDUHelpers.cpp | 335 | ||||
-rw-r--r-- | ipc/hal/DaemonSocketPDUHelpers.h | 1283 | ||||
-rw-r--r-- | ipc/hal/moz.build | 27 |
13 files changed, 0 insertions, 3663 deletions
diff --git a/ipc/hal/DaemonRunnables.h b/ipc/hal/DaemonRunnables.h deleted file mode 100644 index e4a528a9b..000000000 --- a/ipc/hal/DaemonRunnables.h +++ /dev/null @@ -1,950 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 mozilla_ipc_DaemonRunnables_h -#define mozilla_ipc_DaemonRunnables_h - -#include "mozilla/Unused.h" -#include "mozilla/UniquePtr.h" -#include "nsThreadUtils.h" - -namespace mozilla { -namespace ipc { - -namespace details { - -class DaemonRunnable : public Runnable -{ -protected: - DaemonRunnable() = default; - virtual ~DaemonRunnable() = default; - - template<typename Out, typename In> - static Out& ConvertArg(In& aArg) - { - return aArg; - } - - template<typename Out, typename In> - static Out ConvertArg(UniquePtr<In>& aArg) - { - return aArg.get(); - } -}; - -} // namespace detail - -// -// Result handling -// -// The classes of type |DaemonResultRunnable[0..3]| transfer a result -// handler from the I/O thread to the main thread for execution. Call -// the methods |Create| and |Dispatch| to create or create-and-dispatch -// a result runnable. -// -// You need to specify the called method. The |Create| and |Dispatch| -// methods of |DaemonResultRunnable[1..3]| receive an extra argument -// for initializing the result's arguments. During creation, the result -// runnable calls the supplied class's call operator with the result's -// argument. This is where initialization and conversion from backend- -// specific types is performed. -// - -template <typename Obj, typename Res> -class DaemonResultRunnable0 final : public details::DaemonRunnable -{ -public: - typedef DaemonResultRunnable0<Obj, Res> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Obj* aObj, Res (Obj::*aMethod)(), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aObj, aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Obj* aObj, Res (Obj::*aMethod)(), const InitOp& aInitOp) - { - if (!aObj) { - return; // silently return if no result runnable has been given - } - RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - ((*mObj).*mMethod)(); - return NS_OK; - } - -private: - DaemonResultRunnable0(Obj* aObj, Res (Obj::*aMethod)()) - : mObj(aObj) - , mMethod(aMethod) - { - MOZ_ASSERT(mObj); - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - return aInitOp(); - } - - RefPtr<Obj> mObj; - void (Obj::*mMethod)(); -}; - -template <typename Obj, typename Res, typename Tin1, typename Arg1> -class DaemonResultRunnable1 final : public details::DaemonRunnable -{ -public: - typedef DaemonResultRunnable1<Obj, Res, Tin1, Arg1> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Obj* aObj, Res (Obj::*aMethod)(Arg1), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aObj, aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Obj* aObj, Res (Obj::*aMethod)(Arg1), const InitOp& aInitOp) - { - if (!aObj) { - return; // silently return if no result runnable has been given - } - RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - ((*mObj).*mMethod)(ConvertArg<Arg1>(mArg1)); - return NS_OK; - } - -private: - DaemonResultRunnable1(Obj* aObj, Res (Obj::*aMethod)(Arg1)) - : mObj(aObj) - , mMethod(aMethod) - { - MOZ_ASSERT(mObj); - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - return aInitOp(mArg1); - } - - RefPtr<Obj> mObj; - Res (Obj::*mMethod)(Arg1); - Tin1 mArg1; -}; - -template <typename Obj, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Arg1, typename Arg2, typename Arg3> -class DaemonResultRunnable3 final : public details::DaemonRunnable -{ -public: - typedef DaemonResultRunnable3<Obj, Res, - Tin1, Tin2, Tin3, - Arg1, Arg2, Arg3> SelfType; - - template<typename InitOp> - static already_AddRefed<SelfType> - Create(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aObj, aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template<typename InitOp> - static void - Dispatch(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3), - const InitOp& aInitOp) - { - if (!aObj) { - return; // silently return if no result runnable has been given - } - RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - ((*mObj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3)); - return NS_OK; - } - -private: - DaemonResultRunnable3(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3)) - : mObj(aObj) - , mMethod(aMethod) - { - MOZ_ASSERT(mObj); - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult - Init(const InitOp& aInitOp) - { - return aInitOp(mArg1, mArg2, mArg3); - } - - RefPtr<Obj> mObj; - Res (Obj::*mMethod)(Arg1, Arg2, Arg3); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; -}; - -// -// Notification handling -// -// The classes of type |DaemonNotificationRunnable[0..9]| transfer a -// notification from the I/O thread to a notification handler on the -// main thread. Call the methods |Create| and |Dispatch| to create or -// create-and-dispatch a notification runnable. -// -// Like with result runnables, you need to specify the called method. -// And like with result runnables, the |Create| and |Dispatch| methods -// of |DaemonNotificationRunnable[1..9]| receive an extra argument -// for initializing the notification's arguments. During creation, the -// notification runnable calls the class's call operator with the -// notification's argument. This is where initialization and conversion -// from backend-specific types is performed. -// - -template <typename ObjectWrapper, typename Res> -class DaemonNotificationRunnable0 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable0<ObjectWrapper, Res> SelfType; - - template<typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template<typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable0(Res (ObjectType::*aMethod)()) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - return aInitOp(); - } - - Res (ObjectType::*mMethod)(); -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Arg1=Tin1> -class DaemonNotificationRunnable1 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable1<ObjectWrapper, Res, - Tin1, Arg1> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(Arg1), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable1(Res (ObjectType::*aMethod)(Arg1)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1); - Tin1 mArg1; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, - typename Arg1=Tin1, typename Arg2=Tin2> -class DaemonNotificationRunnable2 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable2<ObjectWrapper, Res, - Tin1, Tin2, - Arg1, Arg2> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(Arg1, Arg2), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable2( - Res (ObjectType::*aMethod)(Arg1, Arg2)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2); - Tin1 mArg1; - Tin2 mArg2; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3> -class DaemonNotificationRunnable3 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable3<ObjectWrapper, Res, - Tin1, Tin2, Tin3, - Arg1, Arg2, Arg3> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable3( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, typename Tin4, - typename Arg1=Tin1, typename Arg2=Tin2, - typename Arg3=Tin3, typename Arg4=Tin4> -class DaemonNotificationRunnable4 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable4<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Arg1, Arg2, Arg3, Arg4> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable4( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5> -class DaemonNotificationRunnable5 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable5<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Arg1, Arg2, Arg3, Arg4, Arg5> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable5( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, mArg5); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, typename Tin6, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6> -class DaemonNotificationRunnable6 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable6<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> - SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5), - ConvertArg<Arg6>(mArg6)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable6( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; - Tin6 mArg6; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, typename Tin6, - typename Tin7, typename Tin8, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6, - typename Arg7=Tin7, typename Arg8=Tin8> -class DaemonNotificationRunnable8 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable8<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8, - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5), - ConvertArg<Arg6>(mArg6), - ConvertArg<Arg7>(mArg7), - ConvertArg<Arg8>(mArg8)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable8( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, - mArg5, mArg6, mArg7, mArg8); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; - Tin6 mArg6; - Tin7 mArg7; - Tin8 mArg8; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, typename Tin6, - typename Tin7, typename Tin8, typename Tin9, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6, - typename Arg7=Tin7, typename Arg8=Tin8, typename Arg9=Tin9> -class DaemonNotificationRunnable9 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable9<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8, Tin9, - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5), - ConvertArg<Arg6>(mArg6), - ConvertArg<Arg7>(mArg7), - ConvertArg<Arg8>(mArg8), - ConvertArg<Arg9>(mArg9)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable9( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, - mArg5, mArg6, mArg7, mArg8, mArg9); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; - Tin6 mArg6; - Tin7 mArg7; - Tin8 mArg8; - Tin9 mArg9; -}; - -} -} - -#endif // mozilla_ipc_DaemonRunnables_h diff --git a/ipc/hal/DaemonSocket.cpp b/ipc/hal/DaemonSocket.cpp deleted file mode 100644 index 94c36b955..000000000 --- a/ipc/hal/DaemonSocket.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#include "DaemonSocket.h" -#include "mozilla/ipc/DaemonSocketConsumer.h" -#include "mozilla/ipc/DaemonSocketPDU.h" -#include "mozilla/UniquePtr.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args); -#else -#include <stdio.h> -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -// -// DaemonSocketIO -// - -class DaemonSocketIO final : public ConnectionOrientedSocketIO -{ -public: - DaemonSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, ConnectionStatus aConnectionStatus, - UnixSocketConnector* aConnector, - DaemonSocket* aConnection, - DaemonSocketIOConsumer* aConsumer); - - ~DaemonSocketIO(); - - // Methods for |DataSocketIO| - // - - nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override; - void ConsumeBuffer() override; - void DiscardBuffer() override; - - // Methods for |SocketIOBase| - // - - SocketBase* GetSocketBase() override; - - bool IsShutdownOnConsumerThread() const override; - bool IsShutdownOnIOThread() const override; - - void ShutdownOnConsumerThread() override; - void ShutdownOnIOThread() override; - -private: - DaemonSocket* mConnection; - DaemonSocketIOConsumer* mConsumer; - UniquePtr<DaemonSocketPDU> mPDU; - bool mShuttingDownOnIOThread; -}; - -DaemonSocketIO::DaemonSocketIO( - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, - ConnectionStatus aConnectionStatus, - UnixSocketConnector* aConnector, - DaemonSocket* aConnection, - DaemonSocketIOConsumer* aConsumer) - : ConnectionOrientedSocketIO(aConsumerLoop, - aIOLoop, - aFd, - aConnectionStatus, - aConnector) - , mConnection(aConnection) - , mConsumer(aConsumer) - , mShuttingDownOnIOThread(false) -{ - MOZ_ASSERT(mConnection); - MOZ_ASSERT(mConsumer); - - MOZ_COUNT_CTOR_INHERITED(DaemonSocketIO, ConnectionOrientedSocketIO); -} - -DaemonSocketIO::~DaemonSocketIO() -{ - MOZ_COUNT_DTOR_INHERITED(DaemonSocketIO, ConnectionOrientedSocketIO); -} - -// |DataSocketIO| - -nsresult -DaemonSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) -{ - MOZ_ASSERT(aBuffer); - - if (!mPDU) { - /* There's only one PDU for receiving. We reuse it every time. */ - mPDU = MakeUnique<DaemonSocketPDU>(DaemonSocketPDU::PDU_MAX_PAYLOAD_LENGTH); - } - *aBuffer = mPDU.get(); - - return NS_OK; -} - -void -DaemonSocketIO::ConsumeBuffer() -{ - MOZ_ASSERT(mConsumer); - - mConsumer->Handle(*mPDU); -} - -void -DaemonSocketIO::DiscardBuffer() -{ - // Nothing to do. -} - -// |SocketIOBase| - -SocketBase* -DaemonSocketIO::GetSocketBase() -{ - return mConnection; -} - -bool -DaemonSocketIO::IsShutdownOnConsumerThread() const -{ - MOZ_ASSERT(IsConsumerThread()); - - return mConnection == nullptr; -} - -bool -DaemonSocketIO::IsShutdownOnIOThread() const -{ - return mShuttingDownOnIOThread; -} - -void -DaemonSocketIO::ShutdownOnConsumerThread() -{ - MOZ_ASSERT(IsConsumerThread()); - MOZ_ASSERT(!IsShutdownOnConsumerThread()); - - mConnection = nullptr; -} - -void -DaemonSocketIO::ShutdownOnIOThread() -{ - MOZ_ASSERT(!IsConsumerThread()); - MOZ_ASSERT(!mShuttingDownOnIOThread); - - Close(); // will also remove fd from I/O loop - mShuttingDownOnIOThread = true; -} - -// -// DaemonSocket -// - -DaemonSocket::DaemonSocket( - DaemonSocketIOConsumer* aIOConsumer, - DaemonSocketConsumer* aConsumer, - int aIndex) - : mIO(nullptr) - , mIOConsumer(aIOConsumer) - , mConsumer(aConsumer) - , mIndex(aIndex) -{ - MOZ_ASSERT(mConsumer); - - MOZ_COUNT_CTOR_INHERITED(DaemonSocket, ConnectionOrientedSocket); -} - -DaemonSocket::~DaemonSocket() -{ - MOZ_COUNT_DTOR_INHERITED(DaemonSocket, ConnectionOrientedSocket); -} - -// |ConnectionOrientedSocket| - -nsresult -DaemonSocket::PrepareAccept(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocketIO*& aIO) -{ - MOZ_ASSERT(!mIO); - - SetConnectionStatus(SOCKET_CONNECTING); - - mIO = new DaemonSocketIO( - aConsumerLoop, aIOLoop, -1, UnixSocketWatcher::SOCKET_IS_CONNECTING, - aConnector, this, mIOConsumer); - aIO = mIO; - - return NS_OK; -} - -// |DataSocket| - -void -DaemonSocket::SendSocketData(UnixSocketIOBuffer* aBuffer) -{ - MOZ_ASSERT(mIO); - MOZ_ASSERT(mIO->IsConsumerThread()); - - mIO->GetIOLoop()->PostTask( - MakeAndAddRef<SocketIOSendTask<DaemonSocketIO, UnixSocketIOBuffer>>( - mIO, aBuffer)); -} - -// |SocketBase| - -void -DaemonSocket::Close() -{ - if (!mIO) { - CHROMIUM_LOG("HAL daemon already disconnected!"); - return; - } - - MOZ_ASSERT(mIO->IsConsumerThread()); - - mIO->ShutdownOnConsumerThread(); - mIO->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mIO)); - mIO = nullptr; - - NotifyDisconnect(); -} - -void -DaemonSocket::OnConnectSuccess() -{ - mConsumer->OnConnectSuccess(mIndex); -} - -void -DaemonSocket::OnConnectError() -{ - mConsumer->OnConnectError(mIndex); -} - -void -DaemonSocket::OnDisconnect() -{ - mConsumer->OnDisconnect(mIndex); -} - -} -} diff --git a/ipc/hal/DaemonSocket.h b/ipc/hal/DaemonSocket.h deleted file mode 100644 index 63d3a2e5c..000000000 --- a/ipc/hal/DaemonSocket.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 mozilla_ipc_DaemonSocket_h -#define mozilla_ipc_DaemonSocket_h - -#include "mozilla/ipc/ConnectionOrientedSocket.h" - -namespace mozilla { -namespace ipc { - -class DaemonSocketConsumer; -class DaemonSocketIO; -class DaemonSocketIOConsumer; - -/** - * |DaemonSocket| represents the socket to connect to the HAL daemon. It - * offers connection establishment and sending PDUs. PDU receiving is - * performed by |DaemonSocketIOConsumer|. - */ -class DaemonSocket : public ConnectionOrientedSocket -{ -public: - DaemonSocket(DaemonSocketIOConsumer* aIOConsumer, - DaemonSocketConsumer* aConsumer, - int aIndex); - virtual ~DaemonSocket(); - - // Methods for |ConnectionOrientedSocket| - // - - nsresult PrepareAccept(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocketIO*& aIO) override; - - // Methods for |DataSocket| - // - - void SendSocketData(UnixSocketIOBuffer* aBuffer) override; - - // Methods for |SocketBase| - // - - void Close() override; - void OnConnectSuccess() override; - void OnConnectError() override; - void OnDisconnect() override; - -private: - DaemonSocketIO* mIO; - DaemonSocketIOConsumer* mIOConsumer; - DaemonSocketConsumer* mConsumer; - int mIndex; -}; - -} -} - -#endif diff --git a/ipc/hal/DaemonSocketConnector.cpp b/ipc/hal/DaemonSocketConnector.cpp deleted file mode 100644 index 97106bdd0..000000000 --- a/ipc/hal/DaemonSocketConnector.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#include "DaemonSocketConnector.h" -#include <fcntl.h> -#include <limits.h> -#include <stddef.h> -#include <string.h> -#include <sys/un.h> -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR -#include "prrng.h" - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args); -#else -#include <stdio.h> -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -nsresult -DaemonSocketConnector::CreateRandomAddressString( - const nsACString& aPrefix, unsigned long aPostfixLength, - nsACString& aAddress) -{ - static const char sHexChar[16] = { - [0x0] = '0', [0x1] = '1', [0x2] = '2', [0x3] = '3', - [0x4] = '4', [0x5] = '5', [0x6] = '6', [0x7] = '7', - [0x8] = '8', [0x9] = '9', [0xa] = 'a', [0xb] = 'b', - [0xc] = 'c', [0xd] = 'd', [0xe] = 'e', [0xf] = 'f' - }; - - unsigned short seed[3]; - - if (NS_WARN_IF(!PR_GetRandomNoise(seed, sizeof(seed)))) { - return NS_ERROR_NOT_IMPLEMENTED; - } - - aAddress = aPrefix; - aAddress.Append('-'); - - while (aPostfixLength) { - // Android doesn't provide rand_r, so we use nrand48 here, - // even though it's deprecated. - long value = nrand48(seed); - - size_t bits = sizeof(value) * CHAR_BIT; - - while ((bits > 4) && aPostfixLength) { - aAddress.Append(sHexChar[value&0xf]); - bits -= 4; - value >>= 4; - --aPostfixLength; - } - } - - return NS_OK; -} - -DaemonSocketConnector::DaemonSocketConnector(const nsACString& aSocketName) - : mSocketName(aSocketName) -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketConnector, UnixSocketConnector); -} - -DaemonSocketConnector::~DaemonSocketConnector() -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketConnector, UnixSocketConnector); -} - -nsresult -DaemonSocketConnector::CreateSocket(int& aFd) const -{ - aFd = socket(AF_UNIX, SOCK_SEQPACKET, 0); - if (aFd < 0) { - CHROMIUM_LOG("Could not open daemon socket!"); - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -nsresult -DaemonSocketConnector::SetSocketFlags(int aFd) const -{ - static const int sReuseAddress = 1; - - // Set close-on-exec bit. - int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD)); - if (flags < 0) { - return NS_ERROR_FAILURE; - } - flags |= FD_CLOEXEC; - int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - // Set non-blocking status flag. - flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL)); - if (flags < 0) { - return NS_ERROR_FAILURE; - } - flags |= O_NONBLOCK; - res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - // Set socket addr to be reused even if kernel is still waiting to close. - res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress, - sizeof(sReuseAddress)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -nsresult -DaemonSocketConnector::CreateAddress(struct sockaddr& aAddress, - socklen_t& aAddressLength) const -{ - static const size_t sNameOffset = 1; - - struct sockaddr_un* address = - reinterpret_cast<struct sockaddr_un*>(&aAddress); - - size_t namesiz = mSocketName.Length() + 1; // include trailing '\0' - - if (NS_WARN_IF((sNameOffset + namesiz) > sizeof(address->sun_path))) { - return NS_ERROR_FAILURE; - } - - address->sun_family = AF_UNIX; - memset(address->sun_path, '\0', sNameOffset); // abstract socket - memcpy(address->sun_path + sNameOffset, mSocketName.get(), namesiz); - - aAddressLength = - offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz; - - return NS_OK; -} - -// |UnixSocketConnector| - -nsresult -DaemonSocketConnector::ConvertAddressToString( - const struct sockaddr& aAddress, socklen_t aAddressLength, - nsACString& aAddressString) -{ - MOZ_ASSERT(aAddress.sa_family == AF_UNIX); - - const struct sockaddr_un* un = - reinterpret_cast<const struct sockaddr_un*>(&aAddress); - - size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path); - - aAddressString.Assign(un->sun_path, len); - - return NS_OK; -} - -nsresult -DaemonSocketConnector::CreateListenSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aListenFd) -{ - ScopedClose fd; - - nsresult rv = CreateSocket(fd.rwget()); - if (NS_FAILED(rv)) { - return rv; - } - rv = SetSocketFlags(fd); - if (NS_FAILED(rv)) { - return rv; - } - if (aAddress && aAddressLength) { - rv = CreateAddress(*aAddress, *aAddressLength); - if (NS_FAILED(rv)) { - return rv; - } - } - - aListenFd = fd.forget(); - - return NS_OK; -} - -nsresult -DaemonSocketConnector::AcceptStreamSocket(int aListenFd, - struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) -{ - ScopedClose fd( - TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength))); - if (fd < 0) { - CHROMIUM_LOG("Cannot accept file descriptor!"); - return NS_ERROR_FAILURE; - } - nsresult rv = SetSocketFlags(fd); - if (NS_FAILED(rv)) { - return rv; - } - - aStreamFd = fd.forget(); - - return NS_OK; -} - -nsresult -DaemonSocketConnector::CreateStreamSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) -{ - MOZ_CRASH("|DaemonSocketConnector| does not support " - "creating stream sockets."); - return NS_ERROR_ABORT; -} - -nsresult -DaemonSocketConnector::Duplicate(UnixSocketConnector*& aConnector) -{ - aConnector = new DaemonSocketConnector(*this); - - return NS_OK; -} - -} // namespace ipc -} // namespace mozilla diff --git a/ipc/hal/DaemonSocketConnector.h b/ipc/hal/DaemonSocketConnector.h deleted file mode 100644 index b7f2b8045..000000000 --- a/ipc/hal/DaemonSocketConnector.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 mozilla_ipc_DaemonSocketConnector_h -#define mozilla_ipc_DaemonSocketConnector_h - -#include "mozilla/ipc/UnixSocketConnector.h" -#include "nsString.h" - -namespace mozilla { -namespace ipc { - -class DaemonSocketConnector final : public UnixSocketConnector -{ -public: - static nsresult CreateRandomAddressString(const nsACString& aPrefix, - unsigned long aPostfixLength, - nsACString& aAddress); - - DaemonSocketConnector(const nsACString& aSocketName); - ~DaemonSocketConnector(); - - // Methods for |UnixSocketConnector| - // - - nsresult ConvertAddressToString(const struct sockaddr& aAddress, - socklen_t aAddressLength, - nsACString& aAddressString) override; - - nsresult CreateListenSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aListenFd) override; - - nsresult AcceptStreamSocket(int aListenFd, - struct sockaddr* aAddress, - socklen_t* aAddressLen, - int& aStreamFd) override; - - nsresult CreateStreamSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) override; - - nsresult Duplicate(UnixSocketConnector*& aConnector) override; - -private: - nsresult CreateSocket(int& aFd) const; - nsresult SetSocketFlags(int aFd) const; - nsresult CreateAddress(struct sockaddr& aAddress, - socklen_t& aAddressLength) const; - - nsCString mSocketName; -}; - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_ipc_DaemonSocketConnector_h diff --git a/ipc/hal/DaemonSocketConsumer.cpp b/ipc/hal/DaemonSocketConsumer.cpp deleted file mode 100644 index ad57d5f57..000000000 --- a/ipc/hal/DaemonSocketConsumer.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#include "DaemonSocketConsumer.h" - -namespace mozilla { -namespace ipc { - -// -// DaemonSocketIOConsumer -// - -DaemonSocketIOConsumer::DaemonSocketIOConsumer() -{ } - -DaemonSocketIOConsumer::~DaemonSocketIOConsumer() -{ } - -// -// DaemonSocketConsumer -// - -DaemonSocketConsumer::DaemonSocketConsumer() -{ } - -DaemonSocketConsumer::~DaemonSocketConsumer() -{ } - -} -} diff --git a/ipc/hal/DaemonSocketConsumer.h b/ipc/hal/DaemonSocketConsumer.h deleted file mode 100644 index ababab893..000000000 --- a/ipc/hal/DaemonSocketConsumer.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 mozilla_ipc_DaemonSocketConsumer_h -#define mozilla_ipc_DaemonSocketConsumer_h - -namespace mozilla { -namespace ipc { - -class DaemonSocketPDU; - -/** - * |DaemonSocketIOConsumer| processes incoming PDUs from the - * HAL daemon. Please note that its method |Handle| runs on a - * different than the consumer thread. - */ -class DaemonSocketIOConsumer -{ -public: - virtual ~DaemonSocketIOConsumer(); - - virtual void Handle(DaemonSocketPDU& aPDU) = 0; - virtual void StoreResultHandler(const DaemonSocketPDU& aPDU) = 0; - -protected: - DaemonSocketIOConsumer(); -}; - -/** - * |DaemonSocketConsumer| handles socket events. - */ -class DaemonSocketConsumer -{ -public: - /** - * Callback for socket success. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnConnectSuccess(int aIndex) = 0; - - /** - * Callback for socket errors. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnConnectError(int aIndex) = 0; - - /** - * Callback for socket disconnect. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnDisconnect(int aIndex) = 0; - -protected: - DaemonSocketConsumer(); - virtual ~DaemonSocketConsumer(); -}; - -} -} - -#endif - diff --git a/ipc/hal/DaemonSocketMessageHandlers.h b/ipc/hal/DaemonSocketMessageHandlers.h deleted file mode 100644 index 184e687f1..000000000 --- a/ipc/hal/DaemonSocketMessageHandlers.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- 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/. */ - -/* - * Message handlers - * - * This file contains base classes for message handling. - */ - -#ifndef mozilla_ipc_DaemonSocketMessageHandlers_h -#define mozilla_ipc_DaemonSocketMessageHandlers_h - -#include "nsISupportsImpl.h" // for ref-counting - -namespace mozilla { -namespace ipc { - -/** - * |DaemonSocketResultHandler| is the base class for all protocol-specific - * result handlers. It currently only manages the reference counting. - */ -class DaemonSocketResultHandler -{ -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DaemonSocketResultHandler); - -protected: - DaemonSocketResultHandler() - { } - virtual ~DaemonSocketResultHandler() - { } -}; - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_ipc_DaemonSocketMessageHandlers_h diff --git a/ipc/hal/DaemonSocketPDU.cpp b/ipc/hal/DaemonSocketPDU.cpp deleted file mode 100644 index de6aa0da7..000000000 --- a/ipc/hal/DaemonSocketPDU.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#include "DaemonSocketPDU.h" -#include "mozilla/ipc/DaemonSocketConsumer.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args); -#else -#include <stdio.h> -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -// -// DaemonSocketPDU -// - -DaemonSocketPDU::DaemonSocketPDU(uint8_t aService, uint8_t aOpcode, - uint16_t aPayloadSize) - : mConsumer(nullptr) -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer); - - // Allocate memory - size_t availableSpace = PDU_HEADER_SIZE + aPayloadSize; - ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace); - - // Reserve PDU header - uint8_t* data = Append(PDU_HEADER_SIZE); - MOZ_ASSERT(data); - - // Setup PDU header - data[PDU_OFF_SERVICE] = aService; - data[PDU_OFF_OPCODE] = aOpcode; - memcpy(data + PDU_OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize)); -} - -DaemonSocketPDU::DaemonSocketPDU(size_t aPayloadSize) - : mConsumer(nullptr) -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer); - - size_t availableSpace = PDU_HEADER_SIZE + aPayloadSize; - ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace); -} - -DaemonSocketPDU::~DaemonSocketPDU() -{ - MOZ_COUNT_DTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer); - - UniquePtr<uint8_t[]> data(GetBuffer()); - ResetBuffer(nullptr, 0, 0, 0); -} - -void -DaemonSocketPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode, - uint16_t& aPayloadSize) -{ - memcpy(&aService, GetData(PDU_OFF_SERVICE), sizeof(aService)); - memcpy(&aOpcode, GetData(PDU_OFF_OPCODE), sizeof(aOpcode)); - memcpy(&aPayloadSize, GetData(PDU_OFF_LENGTH), sizeof(aPayloadSize)); -} - -ssize_t -DaemonSocketPDU::Send(int aFd) -{ - struct iovec iv; - memset(&iv, 0, sizeof(iv)); - iv.iov_base = GetData(GetLeadingSpace()); - iv.iov_len = GetSize(); - - struct msghdr msg; - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - msg.msg_control = nullptr; - msg.msg_controllen = 0; - - ssize_t res = TEMP_FAILURE_RETRY(sendmsg(aFd, &msg, 0)); - if (res < 0) { - MOZ_ASSERT(errno != EBADF); /* internal error */ - OnError("sendmsg", errno); - return -1; - } - - Consume(res); - - if (mConsumer) { - // We successfully sent a PDU, now store the - // result handler in the consumer. - mConsumer->StoreResultHandler(*this); - } - - return res; -} - -#define CMSGHDR_CONTAINS_FD(_cmsghdr) \ - ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \ - ((_cmsghdr)->cmsg_type == SCM_RIGHTS) ) - -ssize_t -DaemonSocketPDU::Receive(int aFd) -{ - struct iovec iv; - memset(&iv, 0, sizeof(iv)); - iv.iov_base = GetData(0); - iv.iov_len = GetAvailableSpace(); - - uint8_t cmsgbuf[CMSG_SPACE(sizeof(int)* MAX_NFDS)]; - - struct msghdr msg; - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - - ssize_t res = TEMP_FAILURE_RETRY(recvmsg(aFd, &msg, MSG_NOSIGNAL)); - if (res < 0) { - MOZ_ASSERT(errno != EBADF); /* internal error */ - OnError("recvmsg", errno); - return -1; - } - if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) { - return -1; - } - - SetRange(0, res); - - struct cmsghdr* chdr = CMSG_FIRSTHDR(&msg); - - for (; chdr; chdr = CMSG_NXTHDR(&msg, chdr)) { - if (NS_WARN_IF(!CMSGHDR_CONTAINS_FD(chdr))) { - continue; - } - // Retrieve sent file descriptors. - size_t fdCount = (chdr->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr))) / sizeof(int); - for (size_t i = 0; i < fdCount; i++) { - int* receivedFd = static_cast<int*>(CMSG_DATA(chdr)) + i; - mReceivedFds.AppendElement(*receivedFd); - } - } - - return res; -} - -nsTArray<int> -DaemonSocketPDU::AcquireFds() -{ - // Forget all RAII object to avoid closing the fds. - nsTArray<int> fds; - for (auto& fd : mReceivedFds) { - fds.AppendElement(fd.forget()); - } - mReceivedFds.Clear(); - return fds; -} - -nsresult -DaemonSocketPDU::UpdateHeader() -{ - size_t len = GetPayloadSize(); - if (len >= PDU_MAX_PAYLOAD_LENGTH) { - return NS_ERROR_ILLEGAL_VALUE; - } - uint16_t len16 = static_cast<uint16_t>(len); - - memcpy(GetData(PDU_OFF_LENGTH), &len16, sizeof(len16)); - - return NS_OK; -} - -size_t -DaemonSocketPDU::GetPayloadSize() const -{ - MOZ_ASSERT(GetSize() >= PDU_HEADER_SIZE); - - return GetSize() - PDU_HEADER_SIZE; -} - -void -DaemonSocketPDU::OnError(const char* aFunction, int aErrno) -{ - CHROMIUM_LOG("%s failed with error %d (%s)", - aFunction, aErrno, strerror(aErrno)); -} - -} -} diff --git a/ipc/hal/DaemonSocketPDU.h b/ipc/hal/DaemonSocketPDU.h deleted file mode 100644 index ebc4e4419..000000000 --- a/ipc/hal/DaemonSocketPDU.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 mozilla_ipc_DaemonSocketPDU_h -#define mozilla_ipc_DaemonSocketPDU_h - -#include "mozilla/FileUtils.h" -#include "mozilla/ipc/SocketBase.h" -#include "mozilla/ipc/DaemonSocketMessageHandlers.h" -#include "nsTArray.h" - -namespace mozilla { -namespace ipc { - -static const size_t MAX_NFDS = 16; -class DaemonSocketIOConsumer; - -/** - * |DaemonSocketPDU| represents a single PDU that is transfered from or to - * the HAL daemon. Each PDU contains exactly one command. - * - * A PDU as the following format - * - * | 1 | 1 | 2 | n | - * | service | opcode | payload length | payload | - * - * Service and Opcode each require 1 byte, the payload length requires 2 - * bytes, and the payload requires the number of bytes as stored in the - * payload-length field. - * - * Each service and opcode can have a different payload with individual - * length. For the exact details of the HAL protocol, please refer to - * - * https://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/hal-ipc-api.txt?id=5.24 - * - */ -class DaemonSocketPDU final : public UnixSocketIOBuffer -{ -public: - enum { - PDU_OFF_SERVICE = 0, - PDU_OFF_OPCODE = 1, - PDU_OFF_LENGTH = 2, - PDU_OFF_PAYLOAD = 4, - PDU_HEADER_SIZE = PDU_OFF_PAYLOAD, - PDU_MAX_PAYLOAD_LENGTH = 1 << 16 - }; - - DaemonSocketPDU(uint8_t aService, uint8_t aOpcode, uint16_t aPayloadSize); - DaemonSocketPDU(size_t aPayloadSize); - ~DaemonSocketPDU(); - - void SetConsumer(DaemonSocketIOConsumer* aConsumer) - { - mConsumer = aConsumer; - } - - void SetResultHandler(DaemonSocketResultHandler* aRes) - { - mRes = aRes; - } - - DaemonSocketResultHandler* GetResultHandler() const - { - return mRes; - } - - void GetHeader(uint8_t& aService, uint8_t& aOpcode, - uint16_t& aPayloadSize); - - ssize_t Send(int aFd) override; - ssize_t Receive(int aFd) override; - - nsTArray<int> AcquireFds(); - - nsresult UpdateHeader(); - -private: - size_t GetPayloadSize() const; - void OnError(const char* aFunction, int aErrno); - - DaemonSocketIOConsumer* mConsumer; - RefPtr<DaemonSocketResultHandler> mRes; - nsTArray<ScopedClose> mReceivedFds; -}; - -} -} - -#endif - diff --git a/ipc/hal/DaemonSocketPDUHelpers.cpp b/ipc/hal/DaemonSocketPDUHelpers.cpp deleted file mode 100644 index 6aaf21c33..000000000 --- a/ipc/hal/DaemonSocketPDUHelpers.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* -*- 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/. */ - -#include "DaemonSocketPDUHelpers.h" -#include <limits> - -// Enable this constant to abort Gecko on IPC errors. This is helpful -// for debugging, but should *never* be enabled by default. -#define MOZ_HAL_ABORT_ON_IPC_ERRORS (0) - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) - -#include <android/log.h> - -#define CHROMIUM_LOG(args...) \ - __android_log_print(ANDROID_LOG_INFO, "HAL-IPC", args); - -#define CHROMIUM_LOG_VA(fmt, ap) \ - __android_log_vprint(ANDROID_LOG_INFO, "HAL-IPC", fmt, ap); - -#else - -#include <stdio.h> - -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) { printf(args); } -#define CHROMIUM_LOG_VA(fmt, ap) if (IODEBUG) { vprintf(fmt, ap); } - -#endif - -namespace mozilla { -namespace ipc { -namespace DaemonSocketPDUHelpers { - -// -// Logging -// - -namespace detail { - -void -LogProtocolError(const char* aFmt, ...) -{ - va_list ap; - - va_start(ap, aFmt); - CHROMIUM_LOG_VA(aFmt, ap); - va_end(ap); - - if (MOZ_HAL_ABORT_ON_IPC_ERRORS) { - MOZ_CRASH("HAL IPC protocol error"); - } -} - -} // namespace detail - -// -// Conversion -// - -nsresult -Convert(bool aIn, uint8_t& aOut) -{ - static const uint8_t sValue[] = { - [false] = 0x00, - [true] = 0x01 - }; - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn >= MOZ_ARRAY_LENGTH(sValue), bool, uint8_t)) { - aOut = 0; - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = sValue[aIn]; - return NS_OK; -} - -nsresult -Convert(bool aIn, int32_t& aOut) -{ - uint8_t out; - nsresult rv = Convert(aIn, out); - if (NS_FAILED(rv)) { - out = 0; // silence compiler warning - return rv; - } - aOut = static_cast<int32_t>(out); - return NS_OK; -} - -nsresult -Convert(int aIn, uint8_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<uint8_t>::min(), int, uint8_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<uint8_t>::max(), int, uint8_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<uint8_t>(aIn); - return NS_OK; -} - -nsresult -Convert(int aIn, int16_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<int16_t>::min(), int, int16_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<int16_t>::max(), int, int16_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<int16_t>(aIn); - return NS_OK; -} - -nsresult -Convert(int aIn, int32_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<int32_t>::min(), int, int32_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<int32_t>::max(), int, int32_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<int32_t>(aIn); - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, bool& aOut) -{ - static const bool sBool[] = { - [0x00] = false, - [0x01] = true - }; - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn >= MOZ_ARRAY_LENGTH(sBool), uint8_t, bool)) { - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = sBool[aIn]; - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, char& aOut) -{ - aOut = static_cast<char>(aIn); - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, int& aOut) -{ - aOut = static_cast<int>(aIn); - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, unsigned long& aOut) -{ - aOut = static_cast<unsigned long>(aIn); - return NS_OK; -} - -nsresult -Convert(uint32_t aIn, int& aOut) -{ - aOut = static_cast<int>(aIn); - return NS_OK; -} - -nsresult -Convert(uint32_t aIn, uint8_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<uint8_t>::min(), uint32_t, uint8_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<uint8_t>::max(), uint32_t, uint8_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<uint8_t>(aIn); - return NS_OK; -} - -nsresult -Convert(size_t aIn, uint16_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF(aIn >= (1ul << 16), size_t, uint16_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<uint16_t>(aIn); - return NS_OK; -} - -// -// Packing -// - -nsresult -PackPDU(bool aIn, DaemonSocketPDU& aPDU) -{ - return PackPDU(PackConversion<bool, uint8_t>(aIn), aPDU); -} - -nsresult -PackPDU(const DaemonSocketPDUHeader& aIn, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn.mService, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn.mOpcode, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn.mLength, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; -} - -// -// Unpacking -// - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, bool& aOut) -{ - return UnpackPDU(aPDU, UnpackConversion<uint8_t, bool>(aOut)); -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, char& aOut) -{ - return UnpackPDU(aPDU, UnpackConversion<uint8_t, char>(aOut)); -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, nsDependentCString& aOut) -{ - // We get a pointer to the first character in the PDU, a length - // of 1 ensures we consume the \0 byte. With 'str' pointing to - // the string in the PDU, we can copy the actual bytes. - - const char* str = reinterpret_cast<const char*>(aPDU.Consume(1)); - if (MOZ_HAL_IPC_UNPACK_WARN_IF(!str, nsDependentCString)) { - return NS_ERROR_ILLEGAL_VALUE; // end of PDU - } - - const char* end = static_cast<char*>(memchr(str, '\0', aPDU.GetSize() + 1)); - if (MOZ_HAL_IPC_UNPACK_WARN_IF(!end, nsDependentCString)) { - return NS_ERROR_ILLEGAL_VALUE; // no string terminator - } - - ptrdiff_t len = end - str; - - const uint8_t* rest = aPDU.Consume(len); - if (MOZ_HAL_IPC_UNPACK_WARN_IF(!rest, nsDependentCString)) { - // We couldn't consume bytes that should have been there. - return NS_ERROR_ILLEGAL_VALUE; - } - - aOut.Rebind(str, len); - - return NS_OK; -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackCString0& aOut) -{ - nsDependentCString cstring; - - nsresult rv = UnpackPDU(aPDU, cstring); - if (NS_FAILED(rv)) { - return NS_ERROR_ILLEGAL_VALUE; - } - - aOut.mString->AssignASCII(cstring.get(), cstring.Length()); - - return NS_OK; -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackString0& aOut) -{ - nsDependentCString cstring; - - nsresult rv = UnpackPDU(aPDU, cstring); - if (NS_FAILED(rv)) { - return NS_ERROR_ILLEGAL_VALUE; - } - - *aOut.mString = NS_ConvertUTF8toUTF16(cstring); - - return NS_OK; -} - -// -// Init operators -// - -void -PDUInitOp::WarnAboutTrailingData() const -{ - size_t size = mPDU->GetSize(); - - if (MOZ_LIKELY(!size)) { - return; - } - - uint8_t service, opcode; - uint16_t payloadSize; - mPDU->GetHeader(service, opcode, payloadSize); - - detail::LogProtocolError( - "Unpacked PDU of type (%x,%x) still contains %zu Bytes of data.", - service, opcode, size); -} - -} // namespace DaemonSocketPDUHelpers -} // namespace ipc -} // namespace mozilla diff --git a/ipc/hal/DaemonSocketPDUHelpers.h b/ipc/hal/DaemonSocketPDUHelpers.h deleted file mode 100644 index 38a848e46..000000000 --- a/ipc/hal/DaemonSocketPDUHelpers.h +++ /dev/null @@ -1,1283 +0,0 @@ -/* -*- 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 mozilla_ipc_DaemonSocketPDUHelpers_h -#define mozilla_ipc_DaemonSocketPDUHelpers_h - -#include <stdint.h> -#include "mozilla/ipc/DaemonSocketPDU.h" -#include "mozilla/UniquePtr.h" -#include "nsString.h" - -namespace mozilla { -namespace ipc { - -struct DaemonSocketPDUHeader { - DaemonSocketPDUHeader() - : mService(0x00) - , mOpcode(0x00) - , mLength(0x00) - { } - - DaemonSocketPDUHeader(uint8_t aService, uint8_t aOpcode, uint16_t aLength) - : mService(aService) - , mOpcode(aOpcode) - , mLength(aLength) - { } - - uint8_t mService; - uint8_t mOpcode; - uint16_t mLength; -}; - -namespace DaemonSocketPDUHelpers { - -// -// Logging -// -// The HAL IPC logging macros below print clear error messages for -// failed IPC operations. Use |MOZ_HAL_IPC_CONVERT_WARN_IF|, -// |MOZ_HAL_IPC_PACK_WARN_IF| and |MOZ_HAL_IPC_UNPACK_WARN_IF| to -// test for failures when processing PDUs. -// -// All macros accept the test condition as their first argument, and -// additional type information: the convert macro takes the input and -// output types, the pack macro takes the input type, and the unpack -// macro takes output type. All macros return the result of the test -// condition. If the test fails (i.e., the condition is true), they -// output a warning to the log. -// -// Don't call the functions in the detail namespace. They are helpers -// and not for general use. -// - -namespace detail { - -void -LogProtocolError(const char*, ...); - -inline bool -ConvertWarnIfImpl(const char* aFile, unsigned long aLine, - bool aCondition, const char* aExpr, const char* aIn, - const char* aOut) -{ - if (MOZ_UNLIKELY(aCondition)) { - LogProtocolError("%s:%d: Convert('%s' to '%s') failed: %s", - aFile, aLine, aIn, aOut, aExpr); - } - return aCondition; -} - -inline bool -PackWarnIfImpl(const char* aFile, unsigned long aLine, - bool aCondition, const char* aExpr, const char* aIn) -{ - if (MOZ_UNLIKELY(aCondition)) { - LogProtocolError("%s:%d: Pack('%s') failed: %s", - aFile, aLine, aIn, aExpr); - } - return aCondition; -} - -inline bool -UnpackWarnIfImpl(const char* aFile, unsigned long aLine, - bool aCondition, const char* aExpr, const char* aOut) -{ - if (MOZ_UNLIKELY(aCondition)) { - LogProtocolError("%s:%d: Unpack('%s') failed: %s", - aFile, aLine, aOut, aExpr); - } - return aCondition; -} - -} // namespace detail - -#define MOZ_HAL_IPC_CONVERT_WARN_IF(condition, in, out) \ - ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \ - ConvertWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in, #out) - -#define MOZ_HAL_IPC_PACK_WARN_IF(condition, in) \ - ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \ - PackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in) - -#define MOZ_HAL_IPC_UNPACK_WARN_IF(condition, out) \ - ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \ - UnpackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #out) - -// -// Conversion -// -// PDUs can only store primitive data types, such as integers or -// byte arrays. Gecko often uses more complex data types, such as -// enumators or stuctures. Conversion functions convert between -// primitive data and internal Gecko's data types during a PDU's -// packing and unpacking. -// - -nsresult -Convert(bool aIn, uint8_t& aOut); - -nsresult -Convert(bool aIn, int32_t& aOut); - -nsresult -Convert(int aIn, uint8_t& aOut); - -nsresult -Convert(int aIn, int16_t& aOut); - -nsresult -Convert(int aIn, int32_t& aOut); - -nsresult -Convert(uint8_t aIn, bool& aOut); - -nsresult -Convert(uint8_t aIn, char& aOut); - -nsresult -Convert(uint8_t aIn, int& aOut); - -nsresult -Convert(uint8_t aIn, unsigned long& aOut); - -nsresult -Convert(uint32_t aIn, int& aOut); - -nsresult -Convert(uint32_t aIn, uint8_t& aOut); - -nsresult -Convert(size_t aIn, uint16_t& aOut); - -// -// Packing -// - -// introduce link errors on non-handled data types -template <typename T> -nsresult -PackPDU(T aIn, DaemonSocketPDU& aPDU); - -nsresult -PackPDU(bool aIn, DaemonSocketPDU& aPDU); - -inline nsresult -PackPDU(uint8_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(uint16_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(int32_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(uint32_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(int64_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(uint64_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(float aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(double aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -nsresult -PackPDU(const DaemonSocketPDUHeader& aIn, DaemonSocketPDU& aPDU); - -/* |PackConversion| is a helper for packing converted values. Pass - * an instance of this structure to |PackPDU| to convert a value from - * the input type to the output type and and write it to the PDU. - */ -template<typename Tin, typename Tout> -struct PackConversion { - PackConversion(const Tin& aIn) - : mIn(aIn) - { } - - const Tin& mIn; -}; - -template<typename Tin, typename Tout> -inline nsresult -PackPDU(const PackConversion<Tin, Tout>& aIn, DaemonSocketPDU& aPDU) -{ - Tout out; - - nsresult rv = Convert(aIn.mIn, out); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(out, aPDU); -} - -/* |PackArray| is a helper for packing arrays. Pass an instance - * of this structure as the first argument to |PackPDU| to pack - * an array. The array's maximum default length is 255 elements. - */ -template <typename T> -struct PackArray -{ - PackArray(const T* aData, size_t aLength) - : mData(aData) - , mLength(aLength) - { } - - const T* mData; - size_t mLength; -}; - -/* This implementation of |PackPDU| packs the length of an array - * and the elements of the array one-by-one. - */ -template<typename T> -inline nsresult -PackPDU(const PackArray<T>& aIn, DaemonSocketPDU& aPDU) -{ - for (size_t i = 0; i < aIn.mLength; ++i) { - nsresult rv = PackPDU(aIn.mData[i], aPDU); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template<> -inline nsresult -PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, DaemonSocketPDU& aPDU) -{ - /* Write raw bytes in one pass */ - return aPDU.Write(aIn.mData, aIn.mLength); -} - -template<> -inline nsresult -PackPDU<char>(const PackArray<char>& aIn, DaemonSocketPDU& aPDU) -{ - /* Write raw bytes in one pass */ - return aPDU.Write(aIn.mData, aIn.mLength); -} - -/* |PackCString0| is a helper for packing 0-terminated C string, - * including the \0 character. Pass an instance of this structure - * as the first argument to |PackPDU| to pack a string. - */ -struct PackCString0 -{ - PackCString0(const nsCString& aString) - : mString(aString) - { } - - const nsCString& mString; -}; - -/* This implementation of |PackPDU| packs a 0-terminated C string. - */ -inline nsresult -PackPDU(const PackCString0& aIn, DaemonSocketPDU& aPDU) -{ - return PackPDU( - PackArray<uint8_t>(reinterpret_cast<const uint8_t*>(aIn.mString.get()), - aIn.mString.Length() + 1), aPDU); -} - -/* |PackReversed| is a helper for packing data in reversed order. Pass an - * instance of this structure as the first argument to |PackPDU| to pack data - * in reversed order. - */ -template<typename T> -struct PackReversed -{ - PackReversed(const T& aValue) - : mValue(aValue) - { } - - const T& mValue; -}; - -/* No general rules to pack data in reversed order. Signal a link error if the - * type |T| of |PackReversed| is not defined explicitly. - */ -template<typename T> -nsresult -PackPDU(const PackReversed<T>& aIn, DaemonSocketPDU& aPDU); - -/* This implementation of |PackPDU| packs elements in |PackArray| in reversed - * order. (ex. reversed GATT UUID, see bug 1171866) - */ -template<typename U> -inline nsresult -PackPDU(const PackReversed<PackArray<U>>& aIn, DaemonSocketPDU& aPDU) -{ - for (size_t i = 0; i < aIn.mValue.mLength; ++i) { - nsresult rv = PackPDU(aIn.mValue.mData[aIn.mValue.mLength - i - 1], aPDU); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -/* |PackArray<PackReversed<U>>| is a helper for packing data of each element in - * the reversed order. Pass an instance of this structure as the first argument - * to |PackPDU| to pack data of each array element in the reversed order. - * - * Unlike |PackReversed<PackArray<U>>| which packed array elements in the - * reversed order, here we use |PackReversed<U>| to pack data of each element - * of |PackArray| in the reversed order. - */ -template<typename U> -struct PackArray<PackReversed<U>> -{ - PackArray(const U* aData, size_t aLength) - : mData(aData) - , mLength(aLength) - { } - - const U* mData; - size_t mLength; -}; - -/* This implementation of |PackPDU| packs data of each element in |PackArray| - * in the reversed order. (ex. reversed GATT UUID, see bug 1171866) - */ -template<typename U> -inline nsresult -PackPDU(const PackArray<PackReversed<U>>& aIn, DaemonSocketPDU& aPDU) -{ - for (size_t i = 0; i < aIn.mLength; ++i) { - nsresult rv = PackPDU(PackReversed<U>(aIn.mData[i]), aPDU); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template <typename T1, typename T2> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn2, aPDU); -} - -template <typename T1, typename T2, typename T3> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn3, aPDU); -} - -template <typename T1, typename T2, typename T3, typename T4> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn4, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn5, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn6, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6, - typename T7> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - const T7& aIn7, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn6, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn7, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6, - typename T7, typename T8> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - const T7& aIn7, const T8& aIn8, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn6, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn7, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn8, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6, - typename T7, typename T8, typename T9, - typename T10, typename T11, typename T12, - typename T13> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - const T7& aIn7, const T8& aIn8, const T9& aIn9, - const T10& aIn10, const T11& aIn11, const T12& aIn12, - const T13& aIn13, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn6, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn7, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn8, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn9, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn10, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn11, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn12, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn13, aPDU); -} - -// -// Unpacking -// - -// introduce link errors on non-handled data types -template <typename T> -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, T& aOut); - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, bool& aOut); - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, char& aOut); - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, int8_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint8_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint16_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, int32_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint32_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, int64_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint64_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, float& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, double& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, DaemonSocketPDUHeader& aOut) -{ - nsresult rv = UnpackPDU(aPDU, aOut.mService); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(aPDU, aOut.mOpcode); - if (NS_FAILED(rv)) { - return rv; - } - return UnpackPDU(aPDU, aOut.mLength); -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, nsDependentCString& aOut); - -/* |UnpackCString0| is a helper for unpacking 0-terminated C string, - * including the \0 character. Pass an instance of this structure - * as the first argument to |UnpackPDU| to unpack a string. - */ -struct UnpackCString0 -{ - UnpackCString0(nsCString& aString) - : mString(&aString) - { } - - nsCString* mString; // non-null by construction -}; - -/* This implementation of |UnpackPDU| unpacks a 0-terminated C string. - */ -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackCString0& aOut); - -/* |UnpackString0| is a helper for unpacking 0-terminated C string, - * including the \0 character. Pass an instance of this structure - * as the first argument to |UnpackPDU| to unpack a C string and convert - * it to wide-character encoding. - */ -struct UnpackString0 -{ - UnpackString0(nsString& aString) - : mString(&aString) - { } - - nsString* mString; // non-null by construction -}; - -/* This implementation of |UnpackPDU| unpacks a 0-terminated C string - * and converts it to wide-character encoding. - */ -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackString0& aOut); - -/* |UnpackConversion| is a helper for convering unpacked values. Pass - * an instance of this structure to |UnpackPDU| to read a value from - * the PDU in the input type and convert it to the output type. - */ -template<typename Tin, typename Tout> -struct UnpackConversion { - UnpackConversion(Tout& aOut) - : mOut(aOut) - { } - - Tout& mOut; -}; - -template<typename Tin, typename Tout> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackConversion<Tin, Tout>& aOut) -{ - Tin in; - nsresult rv = UnpackPDU(aPDU, in); - if (NS_FAILED(rv)) { - return rv; - } - return Convert(in, aOut.mOut); -} - -/* |UnpackArray| is a helper for unpacking arrays. Pass an instance - * of this structure as the second argument to |UnpackPDU| to unpack - * an array. - */ -template <typename T> -struct UnpackArray -{ - UnpackArray(T* aData, size_t aLength) - : mData(aData) - , mLength(aLength) - { } - - UnpackArray(UniquePtr<T[]>& aData, size_t aLength) - : mData(nullptr) - , mLength(aLength) - { - aData.reset(new T[mLength]); - mData = aData.get(); - } - - UnpackArray(UniquePtr<T>& aData, size_t aSize, size_t aElemSize) - : mData(nullptr) - , mLength(aSize / aElemSize) - { - aData.reset(new T[mLength]); - mData = aData.get(); - } - - T* mData; - size_t mLength; -}; - -template<typename T> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackArray<T>& aOut) -{ - for (size_t i = 0; i < aOut.mLength; ++i) { - nsresult rv = UnpackPDU(aPDU, aOut.mData[i]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template<typename T> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, UnpackArray<T>& aOut) -{ - for (size_t i = 0; i < aOut.mLength; ++i) { - nsresult rv = UnpackPDU(aPDU, aOut.mData[i]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template<> -inline nsresult -UnpackPDU<uint8_t>(DaemonSocketPDU& aPDU, const UnpackArray<uint8_t>& aOut) -{ - /* Read raw bytes in one pass */ - return aPDU.Read(aOut.mData, aOut.mLength); -} - -template<typename T> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, nsTArray<T>& aOut) -{ - for (typename nsTArray<T>::size_type i = 0; i < aOut.Length(); ++i) { - nsresult rv = UnpackPDU(aPDU, aOut[i]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -/* |UnpackReversed| is a helper for unpacking data in reversed order. Pass an - * instance of this structure as the second argument to |UnpackPDU| to unpack - * data in reversed order. - */ -template<typename T> -struct UnpackReversed -{ - UnpackReversed(T& aValue) - : mValue(&aValue) - { } - - UnpackReversed(T&& aValue) - : mValue(&aValue) - { } - - T* mValue; -}; - -/* No general rules to unpack data in reversed order. Signal a link error if - * the type |T| of |UnpackReversed| is not defined explicitly. - */ -template<typename T> -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<T>& aOut); - -template<typename U> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<UnpackArray<U>>& aOut) -{ - for (size_t i = 0; i < aOut.mValue->mLength; ++i) { - nsresult rv = UnpackPDU(aPDU, - aOut.mValue->mData[aOut.mValue->mLength - i - 1]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -// -// Init operators -// - -// -// Below are general-purpose init operators for Bluetooth. The classes -// of type |ConstantInitOp[1..3]| initialize results or notifications -// with constant values. -// - -template <typename T1> -class ConstantInitOp1 final -{ -public: - ConstantInitOp1(const T1& aArg1) - : mArg1(aArg1) - { } - - nsresult operator () (T1& aArg1) const - { - aArg1 = mArg1; - - return NS_OK; - } - -private: - const T1& mArg1; -}; - -template <typename T1, typename T2> -class ConstantInitOp2 final -{ -public: - ConstantInitOp2(const T1& aArg1, const T2& aArg2) - : mArg1(aArg1) - , mArg2(aArg2) - { } - - nsresult operator () (T1& aArg1, T2& aArg2) const - { - aArg1 = mArg1; - aArg2 = mArg2; - - return NS_OK; - } - -private: - const T1& mArg1; - const T2& mArg2; -}; - -template <typename T1, typename T2, typename T3> -class ConstantInitOp3 final -{ -public: - ConstantInitOp3(const T1& aArg1, const T2& aArg2, const T3& aArg3) - : mArg1(aArg1) - , mArg2(aArg2) - , mArg3(aArg3) - { } - - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const - { - aArg1 = mArg1; - aArg2 = mArg2; - aArg3 = mArg3; - - return NS_OK; - } - -private: - const T1& mArg1; - const T2& mArg2; - const T3& mArg3; -}; - -// |PDUInitOP| provides functionality for init operators that unpack PDUs. -class PDUInitOp -{ -protected: - PDUInitOp(DaemonSocketPDU& aPDU) - : mPDU(&aPDU) - { } - - DaemonSocketPDU& GetPDU() const - { - return *mPDU; // cannot be nullptr - } - - void WarnAboutTrailingData() const; - -private: - DaemonSocketPDU* mPDU; // Hold pointer to allow for constant instances -}; - -// |UnpackPDUInitOp| is a general-purpose init operator for all variants -// of |DaemonResultRunnable| and |DaemonNotificationRunnable|. The call -// operators of |UnpackPDUInitOp| unpack a PDU into the supplied -// arguments. -class UnpackPDUInitOp final : private PDUInitOp -{ -public: - UnpackPDUInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult operator () () const - { - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1> - nsresult operator () (T1& aArg1) const - { - nsresult rv = UnpackPDU(GetPDU(), aArg1); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2> - nsresult operator () (T1& aArg1, T2& aArg2) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, - typename T5, typename T6> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6, T7& aArg7) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg7); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg7); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg8); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8, - T9& aArg9) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg7); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg8); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg9); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - -} // namespace DaemonSocketPDUHelpers - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_ipc_DaemonSocketPDUHelpers_h diff --git a/ipc/hal/moz.build b/ipc/hal/moz.build deleted file mode 100644 index e97963b1e..000000000 --- a/ipc/hal/moz.build +++ /dev/null @@ -1,27 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS.mozilla.ipc += [ - 'DaemonRunnables.h', - 'DaemonSocket.h', - 'DaemonSocketConnector.h', - 'DaemonSocketConsumer.h', - 'DaemonSocketMessageHandlers.h', - 'DaemonSocketPDU.h', - 'DaemonSocketPDUHelpers.h' -] - -UNIFIED_SOURCES += [ - 'DaemonSocket.cpp', - 'DaemonSocketConnector.cpp', - 'DaemonSocketConsumer.cpp', - 'DaemonSocketPDU.cpp', - 'DaemonSocketPDUHelpers.cpp' -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' |