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:
Bob Owen 2014-11-03 10:02:30 +00:00
Родитель 61fa9c2376
Коммит de12f8c051
5 изменённых файлов: 170 добавлений и 1 удалений

Просмотреть файл

@ -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