Bug 1162530 - Part 1: Add versioning to graphics blocklist. r=jmuizelaar

This commit is contained in:
Milan Sreckovic 2015-05-15 10:42:10 -04:00
parent 235e37952c
commit b39a1b5e61
4 changed files with 156 additions and 13 deletions

View File

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "gtest/gtest.h"
#include "GfxDriverInfo.h"
#include "nsVersionComparator.h"
using namespace mozilla::widget;
TEST(GfxWidgets, Split) {
char aStr[8], bStr[8], cStr[8], dStr[8];
ASSERT_TRUE(SplitDriverVersion("33.4.3.22", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 33 && atoi(bStr) == 4 && atoi(cStr) == 3 && atoi(dStr) == 22);
ASSERT_TRUE(SplitDriverVersion("28.74.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 28 && atoi(bStr) == 74 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("132.0.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 132 && atoi(bStr) == 0 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("2.3.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 2 && atoi(bStr) == 3 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("25.4.0.8", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 25 && atoi(bStr) == 4 && atoi(cStr) == 0 && atoi(dStr) == 8);
}
TEST(GfxWidgets, Versioning) {
ASSERT_TRUE(mozilla::Version("0") < mozilla::Version("41.0a1"));
ASSERT_TRUE(mozilla::Version("39.0.5b7") < mozilla::Version("41.0a1"));
ASSERT_TRUE(mozilla::Version("18.0.5b7") < mozilla::Version("18.2"));
ASSERT_TRUE(mozilla::Version("30.0.5b7") < mozilla::Version("41.0b9"));
ASSERT_TRUE(mozilla::Version("100") > mozilla::Version("43.0a1"));
ASSERT_FALSE(mozilla::Version("42.0") < mozilla::Version("42.0"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("42.0"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("42"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0.5") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.1") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42"));
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42.0.5"));
ASSERT_TRUE(mozilla::Version("42.0b7") < mozilla::Version("42.0.5"));
ASSERT_TRUE(mozilla::Version("") == mozilla::Version("0"));
// Note these two; one would expect for 42.0b1 and 42b1 to compare the
// same, but they do not. If this ever changes, we want to know, so
// leave the test here to fail.
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42.0b2"));
ASSERT_FALSE(mozilla::Version("42.0a1") < mozilla::Version("42b2"));
}

View File

@ -13,6 +13,7 @@ UNIFIED_SOURCES += [
'TestColorNames.cpp',
'TestCompositor.cpp',
'TestGfxPrefs.cpp',
'TestGfxWidgets.cpp',
'TestLayers.cpp',
'TestRegion.cpp',
'TestSkipChars.cpp',

View File

@ -16,6 +16,7 @@
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsUnicharUtils.h"
#include "nsVersionComparator.h"
#include "mozilla/Services.h"
#include "mozilla/Observer.h"
#include "nsIObserver.h"
@ -26,6 +27,7 @@
#include "nsIDOMNodeList.h"
#include "nsTArray.h"
#include "nsXULAppAPI.h"
#include "nsIXULAppInfo.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/2D.h"
@ -217,6 +219,29 @@ BlacklistNodeToTextValue(nsIDOMNode *aBlacklistNode, nsAString& aValue)
return true;
}
// <foo attr=Hello/> finds "Hello" if the aAttrName is "attr".
static bool
BlacklistAttrToTextValue(nsIDOMNode *aBlacklistNode,
const nsAString& aAttrName,
nsAString& aValue)
{
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aBlacklistNode);
if (!element) {
return false;
}
nsAutoString value;
if (NS_FAILED(element->GetAttribute(aAttrName, value))) {
return false;
}
value.Trim(" \t\r\n");
aValue = value;
return true;
}
static OperatingSystem
BlacklistOSToOperatingSystem(const nsAString& os)
{
@ -408,6 +433,42 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
nsCOMPtr<nsIDOMNode> dataNode;
nsAutoString dataValue;
// If we get an application version to be zero, something is not working
// and we are not going to bother checking the blocklist versions.
// See TestGfxWidgets.cpp for how version comparison works.
// <versionRange minVersion="42.0a1" maxVersion="45.0"></versionRange>
static mozilla::Version zeroV("0");
static mozilla::Version appV(GfxInfoBase::GetApplicationVersion().get());
if (appV <= zeroV) {
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Invalid application version " << GfxInfoBase::GetApplicationVersion().get();
} else if (BlacklistNodeGetChildByName(element,
NS_LITERAL_STRING("versionRange"),
getter_AddRefs(dataNode))) {
if (BlacklistAttrToTextValue(dataNode,
NS_LITERAL_STRING("minVersion"),
dataValue)) {
mozilla::Version minV(NS_ConvertUTF16toUTF8(dataValue).get());
if (minV > zeroV && appV < minV) {
// The version of the application is less than the minimal version
// this blocklist entry applies to, so we can just ignore it by
// returning false and letting the caller deal with it.
return false;
}
}
if (BlacklistAttrToTextValue(dataNode,
NS_LITERAL_STRING("maxVersion"),
dataValue)) {
mozilla::Version maxV(NS_ConvertUTF16toUTF8(dataValue).get());
if (maxV > zeroV && appV > maxV) {
// The version of the application is more than the maximal version
// this blocklist entry applies to, so we can just ignore it by
// returning false and letting the caller deal with it.
return false;
}
}
}
// <os>WINNT 6.0</os>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("os"),
getter_AddRefs(dataNode))) {
@ -532,9 +593,9 @@ BlacklistEntriesToDriverInfo(nsIDOMHTMLCollection* aBlacklistEntries,
GfxDriverInfo di;
if (BlacklistEntryToDriverInfo(blacklistEntry, di)) {
aDriverInfo[i] = di;
// Prevent di falling out of scope from destroying the devices.
di.mDeleteDevices = false;
}
// Prevent di falling out of scope from destroying the devices.
di.mDeleteDevices = false;
}
}
}
@ -613,6 +674,20 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
uint32_t i = 0;
for (; i < info.Length(); i++) {
// Do the operating system check first, no point in getting the driver
// info if we won't need to use it. Note that this also catches the
// application version mismatches that would leave operating system
// set to unknown.
if (info[i].mOperatingSystem != DRIVER_OS_ALL &&
info[i].mOperatingSystem != os)
{
continue;
}
if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
continue;
}
// XXX: it would be better not to do this everytime round the loop
nsAutoString adapterVendorID;
nsAutoString adapterDeviceID;
@ -638,17 +713,6 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
ParseDriverVersion(adapterDriverVersionString, &driverVersion);
#endif
if (info[i].mOperatingSystem != DRIVER_OS_ALL &&
info[i].mOperatingSystem != os)
{
continue;
}
if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
continue;
}
if (!info[i].mAdapterVendor.Equals(GfxDriverInfo::GetDeviceVendor(VendorAll), nsCaseInsensitiveStringComparator()) &&
!info[i].mAdapterVendor.Equals(adapterVendorID, nsCaseInsensitiveStringComparator())) {
continue;
@ -1019,6 +1083,24 @@ nsresult GfxInfoBase::GetInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aResu
return NS_OK;
}
const nsCString&
GfxInfoBase::GetApplicationVersion()
{
static nsAutoCString version;
static bool versionInitialized = false;
if (!versionInitialized) {
// If we fail to get the version, we will not try again.
versionInitialized = true;
// Get the version from xpcom/system/nsIXULAppInfo.idl
nsCOMPtr<nsIXULAppInfo> app = do_GetService("@mozilla.org/xre/app-info;1");
if (app) {
app->GetVersion(version);
}
}
return version;
}
void
GfxInfoBase::AddCollector(GfxInfoCollectorBase* collector)
{

View File

@ -82,6 +82,9 @@ public:
virtual nsString Manufacturer() { return EmptyString(); }
virtual uint32_t OperatingSystemVersion() { return 0; }
// Convenience to get the application version
static const nsCString& GetApplicationVersion();
protected:
virtual ~GfxInfoBase();