зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1088130: Add to TestGMPCrossOrigin.cpp gtest to test that the APIs required for Output Protection on Windows work within the sandbox. r=cpearce
This commit is contained in:
Родитель
61fa9c2376
Коммит
de12f8c051
|
@ -2,3 +2,4 @@ Name: fake
|
|||
Description: Fake GMP Plugin
|
||||
Version: 1.0
|
||||
APIs: encode-video[h264], decode-video[h264], eme-decrypt[fake]
|
||||
Libraries: dxva2.dll
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "gmp-test-decryptor.h"
|
||||
#include "gmp-test-storage.h"
|
||||
#include "gmp-test-output-protection.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -325,6 +326,8 @@ FakeDecryptor::UpdateSession(uint32_t aPromiseId,
|
|||
}
|
||||
} else if (task == "retrieve-shutdown-token") {
|
||||
ReadRecord("shutdown-token", new ReportReadRecordContinuation("shutdown-token"));
|
||||
} else if (task == "test-op-apis") {
|
||||
mozilla::gmptest::TestOuputProtectionAPIs();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <d3d9.h> // needed to prevent re-definition of enums
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
#include "Opmapi.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmptest {
|
||||
|
||||
#if defined(XP_WIN)
|
||||
typedef HRESULT(STDAPICALLTYPE * OPMGetVideoOutputsFromHMONITORProc)
|
||||
(HMONITOR, OPM_VIDEO_OUTPUT_SEMANTICS, ULONG*, IOPMVideoOutput***);
|
||||
|
||||
static OPMGetVideoOutputsFromHMONITORProc sOPMGetVideoOutputsFromHMONITORProc = nullptr;
|
||||
|
||||
static BOOL CALLBACK EnumDisplayMonitorsCallback(HMONITOR hMonitor, HDC hdc,
|
||||
LPRECT lprc, LPARAM pData)
|
||||
{
|
||||
std::vector<std::string>* failureMsgs = (std::vector<std::string>*)pData;
|
||||
|
||||
MONITORINFOEXA miex;
|
||||
ZeroMemory(&miex, sizeof(miex));
|
||||
miex.cbSize = sizeof(miex);
|
||||
if (!GetMonitorInfoA(hMonitor, &miex)) {
|
||||
failureMsgs->push_back("FAIL GetMonitorInfoA call failed");
|
||||
}
|
||||
|
||||
DISPLAY_DEVICEA dd;
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
dd.cb = sizeof(dd);
|
||||
if (!EnumDisplayDevicesA(miex.szDevice, 0, &dd, 1)) {
|
||||
failureMsgs->push_back("FAIL EnumDisplayDevicesA call failed");
|
||||
}
|
||||
|
||||
ULONG numVideoOutputs = 0;
|
||||
IOPMVideoOutput** opmVideoOutputArray = nullptr;
|
||||
HRESULT hr = sOPMGetVideoOutputsFromHMONITORProc(hMonitor,
|
||||
OPM_VOS_OPM_SEMANTICS,
|
||||
&numVideoOutputs,
|
||||
&opmVideoOutputArray);
|
||||
if (S_OK != hr) {
|
||||
if (0x8007001f != hr && 0x80070032 != hr) {
|
||||
char msg[100];
|
||||
sprintf(msg, "FAIL OPMGetVideoOutputsFromHMONITOR call failed: HRESULT=0x%08x", hr);
|
||||
failureMsgs->push_back(msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (ULONG i = 0; i < numVideoOutputs; ++i) {
|
||||
OPM_RANDOM_NUMBER opmRandomNumber;
|
||||
BYTE* certificate = nullptr;
|
||||
ULONG certificateLength = 0;
|
||||
hr = opmVideoOutputArray[i]->StartInitialization(&opmRandomNumber,
|
||||
&certificate,
|
||||
&certificateLength);
|
||||
if (S_OK != hr) {
|
||||
char msg[100];
|
||||
sprintf(msg, "FAIL StartInitialization call failed: HRESULT=0x%08x", hr);
|
||||
failureMsgs->push_back(msg);
|
||||
}
|
||||
|
||||
if (certificate) {
|
||||
CoTaskMemFree(certificate);
|
||||
}
|
||||
|
||||
opmVideoOutputArray[i]->Release();
|
||||
}
|
||||
|
||||
if (opmVideoOutputArray) {
|
||||
CoTaskMemFree(opmVideoOutputArray);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
RunOutputProtectionAPITests()
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
// Get hold of OPMGetVideoOutputsFromHMONITOR function.
|
||||
HMODULE hDvax2DLL = GetModuleHandleW(L"dxva2.dll");
|
||||
if (!hDvax2DLL) {
|
||||
FakeDecryptor::Message("FAIL GetModuleHandleW call failed for dxva2.dll");
|
||||
return;
|
||||
}
|
||||
|
||||
sOPMGetVideoOutputsFromHMONITORProc = (OPMGetVideoOutputsFromHMONITORProc)
|
||||
GetProcAddress(hDvax2DLL, "OPMGetVideoOutputsFromHMONITOR");
|
||||
if (!sOPMGetVideoOutputsFromHMONITORProc) {
|
||||
FakeDecryptor::Message("FAIL GetProcAddress call failed for OPMGetVideoOutputsFromHMONITOR");
|
||||
return;
|
||||
}
|
||||
|
||||
// Test EnumDisplayMonitors.
|
||||
// Other APIs are tested in the callback function.
|
||||
std::vector<std::string> failureMsgs;
|
||||
if (!EnumDisplayMonitors(NULL, NULL, EnumDisplayMonitorsCallback,
|
||||
(LPARAM) &failureMsgs)) {
|
||||
FakeDecryptor::Message("FAIL EnumDisplayMonitors call failed");
|
||||
}
|
||||
|
||||
// Report any failures in the callback function.
|
||||
for (auto& msg : failureMsgs) {
|
||||
FakeDecryptor::Message(msg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
TestOuputProtectionAPIs()
|
||||
{
|
||||
RunOutputProtectionAPITests();
|
||||
FakeDecryptor::Message("OP tests completed");
|
||||
return;
|
||||
}
|
||||
|
||||
} // gmptest
|
||||
} // mozilla
|
|
@ -13,6 +13,11 @@ SOURCES += [
|
|||
|
||||
SharedLibrary("fake")
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
OS_LIBS += [
|
||||
'ole32',
|
||||
]
|
||||
|
||||
USE_STATIC_LIBS = True
|
||||
NO_VISIBILITY_FLAGS = True
|
||||
# Don't use STL wrappers; this isn't Gecko code
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include "mozilla/Atomics.h"
|
||||
#include "nsNSSComponent.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -553,6 +557,20 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
Update(NS_LITERAL_CSTRING("retrieve-shutdown-token"));
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
void TestOutputProtection() {
|
||||
Shutdown();
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example15.com"),
|
||||
NS_LITERAL_STRING("example16.com"),
|
||||
false);
|
||||
|
||||
Expect(NS_LITERAL_CSTRING("OP tests completed"),
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("test-op-apis"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void Expect(const nsCString& aMessage, nsIRunnable* aContinuation) {
|
||||
mExpected.AppendElement(ExpectedMessage(aMessage, aContinuation));
|
||||
}
|
||||
|
@ -602,7 +620,7 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
nsCString msg((const char*)aMessage.Elements(), aMessage.Length());
|
||||
EXPECT_TRUE(mExpected.Length() > 0);
|
||||
bool matches = mExpected[0].mMessage.Equals(msg);
|
||||
EXPECT_TRUE(matches);
|
||||
EXPECT_STREQ(mExpected[0].mMessage.get(), msg.get());
|
||||
if (mExpected.Length() > 0 && matches) {
|
||||
nsRefPtr<nsIRunnable> continuation = mExpected[0].mContinuation;
|
||||
mExpected.RemoveElementAt(0);
|
||||
|
@ -707,3 +725,15 @@ TEST(GeckoMediaPlugins, GMPStorageAsyncShutdownStorage) {
|
|||
nsRefPtr<GMPStorageTest> runner = new GMPStorageTest();
|
||||
runner->DoTest(&GMPStorageTest::TestAsyncShutdownStorage);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
TEST(GeckoMediaPlugins, GMPOutputProtection) {
|
||||
// Output Protection is not available pre-Vista.
|
||||
if (!IsVistaOrLater()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<GMPStorageTest> runner = new GMPStorageTest();
|
||||
runner->DoTest(&GMPStorageTest::TestOutputProtection);
|
||||
}
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче