SandboxTestingParent.cpp (4484B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 #include "SandboxTestingParent.h" 8 #include "SandboxTestingThread.h" 9 #include "nsIObserverService.h" 10 #include "mozilla/ipc/Endpoint.h" 11 #include "mozilla/Services.h" 12 #include "mozilla/SyncRunnable.h" 13 #include "nsDirectoryServiceUtils.h" 14 15 namespace mozilla { 16 17 /* static */ 18 already_AddRefed<SandboxTestingParent> SandboxTestingParent::Create( 19 Endpoint<PSandboxTestingParent>&& aParentEnd) { 20 SandboxTestingThread* thread = SandboxTestingThread::Create(); 21 if (!thread) { 22 return nullptr; 23 } 24 RefPtr<SandboxTestingParent> instance = new SandboxTestingParent(thread); 25 thread->Dispatch(NewRunnableMethod<Endpoint<PSandboxTestingParent>&&>( 26 "SandboxTestingParent::Bind", instance, &SandboxTestingParent::Bind, 27 std::move(aParentEnd))); 28 return instance.forget(); 29 } 30 31 SandboxTestingParent::SandboxTestingParent(SandboxTestingThread* aThread) 32 : mThread(aThread), 33 mMonitor("SandboxTestingParent Lock"), 34 mShutdownDone(false) {} 35 36 SandboxTestingParent::~SandboxTestingParent() = default; 37 38 void SandboxTestingParent::Bind(Endpoint<PSandboxTestingParent>&& aEnd) { 39 MOZ_RELEASE_ASSERT(mThread->IsOnThread()); 40 DebugOnly<bool> ok = aEnd.Bind(this); 41 MOZ_ASSERT(ok); 42 } 43 44 void SandboxTestingParent::ShutdownSandboxTestThread() { 45 MOZ_ASSERT(mThread->IsOnThread()); 46 Close(); 47 // Notify waiting thread that we are done. 48 MonitorAutoLock lock(mMonitor); 49 mShutdownDone = true; 50 mMonitor.Notify(); 51 } 52 53 void SandboxTestingParent::Destroy( 54 already_AddRefed<SandboxTestingParent> aInstance) { 55 MOZ_ASSERT(NS_IsMainThread()); 56 RefPtr<SandboxTestingParent> instance(aInstance); 57 if (!instance) { 58 return; 59 } 60 61 { 62 // Hold the lock while we destroy the actor on the test thread. 63 MonitorAutoLock lock(instance->mMonitor); 64 instance->mThread->Dispatch(NewRunnableMethod( 65 "SandboxTestingParent::ShutdownSandboxTestThread", instance, 66 &SandboxTestingParent::ShutdownSandboxTestThread)); 67 68 // Wait for test thread to complete destruction. 69 while (!instance->mShutdownDone) { 70 instance->mMonitor.Wait(); 71 } 72 } 73 } 74 75 void SandboxTestingParent::ActorDestroy(ActorDestroyReason aWhy) { 76 MOZ_RELEASE_ASSERT(mThread->IsOnThread()); 77 } 78 79 mozilla::ipc::IPCResult SandboxTestingParent::RecvReportTestResults( 80 const nsCString& testName, bool passed, const nsCString& resultMessage) { 81 NS_DispatchToMainThread( 82 NS_NewRunnableFunction("SandboxReportTestResults", [=]() { 83 nsCOMPtr<nsIObserverService> observerService = 84 mozilla::services::GetObserverService(); 85 MOZ_RELEASE_ASSERT(observerService); 86 nsCString passedStr(passed ? "true"_ns : "false"_ns); 87 nsString json; 88 json += u"{ \"testid\" : \""_ns + NS_ConvertUTF8toUTF16(testName) + 89 u"\", \"passed\" : "_ns + NS_ConvertUTF8toUTF16(passedStr) + 90 u", \"message\" : \""_ns + 91 NS_ConvertUTF8toUTF16(resultMessage) + u"\" }"_ns; 92 observerService->NotifyObservers(nullptr, "sandbox-test-result", 93 json.BeginReading()); 94 })); 95 return IPC_OK(); 96 } 97 98 mozilla::ipc::IPCResult SandboxTestingParent::RecvTestCompleted() { 99 (void)SendShutDown(); 100 NS_DispatchToMainThread( 101 NS_NewRunnableFunction("SandboxReportTestResults", []() { 102 nsCOMPtr<nsIObserverService> observerService = 103 mozilla::services::GetObserverService(); 104 MOZ_RELEASE_ASSERT(observerService); 105 observerService->NotifyObservers(nullptr, "sandbox-test-done", 0); 106 })); 107 return IPC_OK(); 108 } 109 110 mozilla::ipc::IPCResult SandboxTestingParent::RecvGetSpecialDirectory( 111 const nsCString& aSpecialDirName, nsString* aDirPath) { 112 RefPtr<Runnable> runnable = NS_NewRunnableFunction( 113 "SandboxTestingParent::RecvGetSpecialDirectory", [&]() { 114 nsCOMPtr<nsIFile> dir; 115 NS_GetSpecialDirectory(aSpecialDirName.get(), getter_AddRefs(dir)); 116 if (dir) { 117 dir->GetPath(*aDirPath); 118 } 119 }); 120 SyncRunnable::DispatchToThread(GetMainThreadSerialEventTarget(), runnable, 121 /*aForceDispatch*/ true); 122 return IPC_OK(); 123 } 124 125 } // namespace mozilla