TestGMPCrossOrigin.cpp (7184B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "GMPServiceParent.h" 8 #include "GMPTestMonitor.h" 9 #include "GMPVideoDecoderProxy.h" 10 #include "GMPVideoEncoderProxy.h" 11 #include "gtest/gtest.h" 12 #include "mozilla/StaticPtr.h" 13 #include "mozilla/gtest/MozAssertions.h" 14 #include "nsAppDirectoryServiceDefs.h" 15 #include "nsThreadUtils.h" 16 17 using namespace mozilla; 18 using namespace mozilla::gmp; 19 20 struct GMPTestRunner { 21 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPTestRunner) 22 23 GMPTestRunner() = default; 24 void DoTest(void (GMPTestRunner::*aTestMethod)(GMPTestMonitor&)); 25 void RunTestGMPTestCodec1(GMPTestMonitor& aMonitor); 26 void RunTestGMPTestCodec2(GMPTestMonitor& aMonitor); 27 void RunTestGMPTestCodec3(GMPTestMonitor& aMonitor); 28 void RunTestGMPCrossOrigin1(GMPTestMonitor& aMonitor); 29 void RunTestGMPCrossOrigin2(GMPTestMonitor& aMonitor); 30 void RunTestGMPCrossOrigin3(GMPTestMonitor& aMonitor); 31 void RunTestGMPCrossOrigin4(GMPTestMonitor& aMonitor); 32 33 private: 34 ~GMPTestRunner() = default; 35 }; 36 37 template <class T, class Base, 38 nsresult (NS_STDCALL GeckoMediaPluginService::*Getter)( 39 GMPCrashHelper*, nsTArray<nsCString>*, const nsACString&, 40 UniquePtr<Base>&&)> 41 class RunTestGMPVideoCodec : public Base { 42 public: 43 void Done(T* aGMP, GMPVideoHost* aHost) override { 44 EXPECT_TRUE(aGMP); 45 EXPECT_TRUE(aHost); 46 if (aGMP) { 47 aGMP->Close(); 48 } 49 mMonitor.SetFinished(); 50 } 51 52 static void Run(GMPTestMonitor& aMonitor, const nsCString& aOrigin) { 53 UniquePtr<GMPCallbackType> callback(new RunTestGMPVideoCodec(aMonitor)); 54 Get(aOrigin, std::move(callback)); 55 } 56 57 protected: 58 typedef T GMPCodecType; 59 typedef Base GMPCallbackType; 60 61 explicit RunTestGMPVideoCodec(GMPTestMonitor& aMonitor) 62 : mMonitor(aMonitor) {} 63 64 static nsresult Get(const nsACString& aNodeId, UniquePtr<Base>&& aCallback) { 65 nsTArray<nsCString> tags; 66 tags.AppendElement("h264"_ns); 67 tags.AppendElement("fake"_ns); 68 69 RefPtr<GeckoMediaPluginService> service = 70 GeckoMediaPluginService::GetGeckoMediaPluginService(); 71 return ((*service).*Getter)(nullptr, &tags, aNodeId, std::move(aCallback)); 72 } 73 74 GMPTestMonitor& mMonitor; 75 }; 76 77 typedef RunTestGMPVideoCodec<GMPVideoDecoderProxy, GetGMPVideoDecoderCallback, 78 &GeckoMediaPluginService::GetGMPVideoDecoder> 79 RunTestGMPVideoDecoder; 80 typedef RunTestGMPVideoCodec<GMPVideoEncoderProxy, GetGMPVideoEncoderCallback, 81 &GeckoMediaPluginService::GetGMPVideoEncoder> 82 RunTestGMPVideoEncoder; 83 84 void GMPTestRunner::RunTestGMPTestCodec1(GMPTestMonitor& aMonitor) { 85 RunTestGMPVideoDecoder::Run(aMonitor, "o"_ns); 86 } 87 88 void GMPTestRunner::RunTestGMPTestCodec2(GMPTestMonitor& aMonitor) { 89 RunTestGMPVideoDecoder::Run(aMonitor, ""_ns); 90 } 91 92 void GMPTestRunner::RunTestGMPTestCodec3(GMPTestMonitor& aMonitor) { 93 RunTestGMPVideoEncoder::Run(aMonitor, ""_ns); 94 } 95 96 template <class Base> 97 class RunTestGMPCrossOrigin : public Base { 98 public: 99 void Done(typename Base::GMPCodecType* aGMP, GMPVideoHost* aHost) override { 100 EXPECT_TRUE(aGMP); 101 102 UniquePtr<typename Base::GMPCallbackType> callback( 103 new Step2(Base::mMonitor, aGMP, mShouldBeEqual)); 104 nsresult rv = Base::Get(mOrigin2, std::move(callback)); 105 EXPECT_NS_SUCCEEDED(rv); 106 if (NS_FAILED(rv)) { 107 Base::mMonitor.SetFinished(); 108 } 109 } 110 111 static void Run(GMPTestMonitor& aMonitor, const nsCString& aOrigin1, 112 const nsCString& aOrigin2) { 113 UniquePtr<typename Base::GMPCallbackType> callback( 114 new RunTestGMPCrossOrigin<Base>(aMonitor, aOrigin1, aOrigin2)); 115 nsresult rv = Base::Get(aOrigin1, std::move(callback)); 116 EXPECT_NS_SUCCEEDED(rv); 117 if (NS_FAILED(rv)) { 118 aMonitor.SetFinished(); 119 } 120 } 121 122 private: 123 RunTestGMPCrossOrigin(GMPTestMonitor& aMonitor, const nsCString& aOrigin1, 124 const nsCString& aOrigin2) 125 : Base(aMonitor), 126 mGMP(nullptr), 127 mOrigin2(aOrigin2), 128 mShouldBeEqual(aOrigin1.Equals(aOrigin2)) {} 129 130 class Step2 : public Base { 131 public: 132 Step2(GMPTestMonitor& aMonitor, typename Base::GMPCodecType* aGMP, 133 bool aShouldBeEqual) 134 : Base(aMonitor), mGMP(aGMP), mShouldBeEqual(aShouldBeEqual) {} 135 void Done(typename Base::GMPCodecType* aGMP, GMPVideoHost* aHost) override { 136 EXPECT_TRUE(aGMP); 137 if (aGMP) { 138 EXPECT_TRUE(mGMP && (mGMP->GetPluginId() == aGMP->GetPluginId()) == 139 mShouldBeEqual); 140 } 141 if (mGMP) { 142 mGMP->Close(); 143 } 144 Base::Done(aGMP, aHost); 145 } 146 147 private: 148 typename Base::GMPCodecType* mGMP; 149 bool mShouldBeEqual; 150 }; 151 152 typename Base::GMPCodecType* mGMP; 153 nsCString mOrigin2; 154 bool mShouldBeEqual; 155 }; 156 157 typedef RunTestGMPCrossOrigin<RunTestGMPVideoDecoder> 158 RunTestGMPVideoDecoderCrossOrigin; 159 typedef RunTestGMPCrossOrigin<RunTestGMPVideoEncoder> 160 RunTestGMPVideoEncoderCrossOrigin; 161 162 void GMPTestRunner::RunTestGMPCrossOrigin1(GMPTestMonitor& aMonitor) { 163 RunTestGMPVideoDecoderCrossOrigin::Run(aMonitor, "origin1"_ns, "origin2"_ns); 164 } 165 166 void GMPTestRunner::RunTestGMPCrossOrigin2(GMPTestMonitor& aMonitor) { 167 RunTestGMPVideoEncoderCrossOrigin::Run(aMonitor, "origin1"_ns, "origin2"_ns); 168 } 169 170 void GMPTestRunner::RunTestGMPCrossOrigin3(GMPTestMonitor& aMonitor) { 171 RunTestGMPVideoDecoderCrossOrigin::Run(aMonitor, "origin1"_ns, "origin1"_ns); 172 } 173 174 void GMPTestRunner::RunTestGMPCrossOrigin4(GMPTestMonitor& aMonitor) { 175 RunTestGMPVideoEncoderCrossOrigin::Run(aMonitor, "origin1"_ns, "origin1"_ns); 176 } 177 178 void GMPTestRunner::DoTest( 179 void (GMPTestRunner::*aTestMethod)(GMPTestMonitor&)) { 180 RefPtr<GeckoMediaPluginService> service = 181 GeckoMediaPluginService::GetGeckoMediaPluginService(); 182 nsCOMPtr<nsIThread> thread; 183 EXPECT_NS_SUCCEEDED(service->GetThread(getter_AddRefs(thread))); 184 185 GMPTestMonitor monitor; 186 thread->Dispatch(NewRunnableMethod<GMPTestMonitor&>( 187 "GMPTestRunner::DoTest", this, aTestMethod, monitor), 188 NS_DISPATCH_NORMAL); 189 monitor.AwaitFinished(); 190 } 191 192 // Bug 1776767 - Skip all GMP tests on Windows ASAN 193 #if !(defined(XP_WIN) && (defined(MOZ_ASAN) || defined(MOZ_CODE_COVERAGE))) 194 TEST(GeckoMediaPlugins, GMPTestCodec) 195 { 196 RefPtr<GMPTestRunner> runner = new GMPTestRunner(); 197 runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec1); 198 runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec2); 199 runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec3); 200 } 201 202 TEST(GeckoMediaPlugins, GMPCrossOrigin) 203 { 204 RefPtr<GMPTestRunner> runner = new GMPTestRunner(); 205 runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin1); 206 runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin2); 207 runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin3); 208 runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin4); 209 } 210 #endif // !(defined(XP_WIN) && (defined(MOZ_ASAN) || 211 // defined(MOZ_CODE_COVERAGE)))