Bug 806369 - Stagefright blacklisting. Also extends Android Gfxinfo to support blacklist rules by Android API version, Model, Product, Hardware, Manufacturer - r=joe,doublec

This commit is contained in:
Benoit Jacob 2012-11-01 17:13:10 -04:00
parent 548d04b119
commit cc10ea918f
11 changed files with 171 additions and 17 deletions

View File

@ -13,6 +13,7 @@
#include "nsISeekableStream.h"
#include "pratom.h"
#include "nsMediaPluginReader.h"
#include "nsIGfxInfo.h"
#include "MPAPI.h"
@ -87,6 +88,29 @@ static PluginHost sPluginHost = {
void nsMediaPluginHost::TryLoad(const char *name)
{
bool forceEnabled =
Preferences::GetBool("stagefright.force-enabled", false);
bool disabled =
Preferences::GetBool("stagefright.disabled", false);
if (disabled) {
NS_WARNING("XXX stagefright disabled\n");
return;
}
if (!forceEnabled) {
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
if (gfxInfo) {
int32_t status;
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_STAGEFRIGHT, &status))) {
if (status != nsIGfxInfo::FEATURE_NO_INFO) {
NS_WARNING("XXX stagefright blacklisted\n");
return;
}
}
}
}
PRLibrary *lib = PR_LoadLibrary(name);
if (lib) {
Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));

View File

@ -3629,6 +3629,10 @@ pref("webgl.prefer-16bpp", false);
pref("webgl.default-no-alpha", false);
pref("webgl.force-layers-readback", false);
// Stagefright prefs
pref("stagefright.force-enabled", false);
pref("stagefright.disabled", false);
#ifdef XP_WIN
// The default TCP send window on Windows is too small, and autotuning only occurs on receive
pref("network.tcp.sendbuffer", 131072);

View File

@ -122,27 +122,26 @@ GfxInfo::EnsureInitializedFromGfxInfoData()
// as it's useful information that isn't given anywhere else in about:support of in crash reports.
// But we should really move this out of GfxInfo.
if (mozilla::AndroidBridge::Bridge()) {
nsAutoString str;
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MODEL", str)) {
mAdapterDescription.AppendPrintf(" -- Model: %s", NS_LossyConvertUTF16toASCII(str).get());
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MODEL", mModel)) {
mAdapterDescription.AppendPrintf(" -- Model: %s", NS_LossyConvertUTF16toASCII(mModel).get());
}
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "PRODUCT", str)) {
mAdapterDescription.AppendPrintf(", Product: %s", NS_LossyConvertUTF16toASCII(str).get());
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "PRODUCT", mProduct)) {
mAdapterDescription.AppendPrintf(", Product: %s", NS_LossyConvertUTF16toASCII(mProduct).get());
}
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MANUFACTURER", str)) {
mAdapterDescription.AppendPrintf(", Manufacturer: %s", NS_LossyConvertUTF16toASCII(str).get());
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MANUFACTURER", mManufacturer)) {
mAdapterDescription.AppendPrintf(", Manufacturer: %s", NS_LossyConvertUTF16toASCII(mManufacturer).get());
}
int32_t version; // the HARDWARE field isn't available on Android SDK < 8
if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &version))
version = 0;
int32_t signedVersion;
if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &signedVersion))
signedVersion = 0;
mOSVersion = signedVersion;
if (version >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", str)) {
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", str)) {
mAdapterDescription.AppendPrintf(", Hardware: %s", NS_LossyConvertUTF16toASCII(str).get());
}
// the HARDWARE field isn't available on Android SDK < 8
if (mOSVersion >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", mHardware)) {
mAdapterDescription.AppendPrintf(", Hardware: %s", NS_LossyConvertUTF16toASCII(mHardware).get());
}
}
@ -309,7 +308,7 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
NS_ENSURE_ARG_POINTER(aStatus);
aSuggestedDriverVersion.SetIsVoid(true);
*aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
OperatingSystem os = DRIVER_OS_ANDROID;
OperatingSystem os = mOS;
if (aOS)
*aOS = os;
@ -330,6 +329,27 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
return NS_OK;
}
}
if (aFeature == FEATURE_STAGEFRIGHT) {
NS_LossyConvertUTF16toASCII cManufacturer(mManufacturer);
NS_LossyConvertUTF16toASCII cModel(mModel);
if (mOSVersion < 14 /* Before version 4.0 */ )
{
*aStatus = nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION;
return NS_OK;
}
else if (mOSVersion < 16 /* Before version 4.1 */ )
{
bool isWhitelisted =
cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator()) ||
cModel.Equals("galaxy nexus", nsCaseInsensitiveCStringComparator()); // some Galaxy Nexus have manufacturer=amazon
if (!isWhitelisted) {
*aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
return NS_OK;
}
}
}
}
return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os);
@ -366,7 +386,29 @@ NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion)
/* void spoofOSVersion (in unsigned long aVersion); */
NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion)
{
EnsureInitializedFromGfxInfoData(); // initialization from GfxInfo data overwrites mOSVersion
mOSVersion = aVersion;
return NS_OK;
}
#endif
const nsAString& GfxInfo::Model() const
{
return mModel;
}
const nsAString& GfxInfo::Hardware() const
{
return mHardware;
}
const nsAString& GfxInfo::Product() const
{
return mProduct;
}
const nsAString& GfxInfo::Manufacturer() const
{
return mManufacturer;
}

View File

@ -48,11 +48,18 @@ public:
void EnsureInitializedFromGfxInfoData();
virtual const nsAString& Model() const;
virtual const nsAString& Hardware() const;
virtual const nsAString& Product() const;
virtual const nsAString& Manufacturer() const;
#ifdef DEBUG
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIGFXINFODEBUG
#endif
virtual uint32_t OperatingSystemVersion() const { return mOSVersion; }
protected:
virtual nsresult GetFeatureStatusImpl(int32_t aFeature,
@ -76,6 +83,11 @@ private:
nsCString mError;
nsCString mAdapterDescription;
OperatingSystem mOS;
uint32_t mOSVersion;
nsString mModel, mHardware, mManufacturer, mProduct;
};
} // namespace widget

View File

@ -53,6 +53,8 @@ public:
NS_DECL_NSIGFXINFODEBUG
#endif
virtual uint32_t OperatingSystemVersion() const { return mOSXVersion; }
protected:
virtual nsresult GetFeatureStatusImpl(int32_t aFeature,

View File

@ -8,7 +8,7 @@
/* NOTE: this interface is completely undesigned, not stable and likely to change */
[scriptable, uuid(a67c77af-2952-4028-93ab-e7bc3b43cf81)]
[scriptable, uuid(8a9797ae-22d4-431d-a628-18fd5900c53c)]
interface nsIGfxInfo : nsISupports
{
/*
@ -77,6 +77,8 @@ interface nsIGfxInfo : nsISupports
const long FEATURE_WEBGL_ANGLE = 7;
/* Whether WebGL antialiasing is supported. */
const long FEATURE_WEBGL_MSAA = 8;
/* Whether Stagefright is supported */
const long FEATURE_STAGEFRIGHT = 9;
/*
* A set of return values from GetFeatureStatus

View File

@ -45,6 +45,8 @@ public:
virtual nsresult Init();
virtual uint32_t OperatingSystemVersion() const { return mWindowsVersion; }
#ifdef DEBUG
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIGFXINFODEBUG

View File

@ -17,6 +17,7 @@ nsAString* GfxDriverInfo::mDeviceVendors[DeviceVendorMax];
GfxDriverInfo::GfxDriverInfo()
: mOperatingSystem(DRIVER_OS_UNKNOWN),
mOperatingSystemVersion(0),
mAdapterVendor(GfxDriverInfo::GetDeviceVendor(VendorAll)),
mDevices(allDevices),
mDeleteDevices(false),
@ -36,6 +37,7 @@ GfxDriverInfo::GfxDriverInfo(OperatingSystem os, nsAString& vendor,
const char *suggestedVersion /* = nullptr */,
bool ownDevices /* = false */)
: mOperatingSystem(os),
mOperatingSystemVersion(0),
mAdapterVendor(vendor),
mDevices(devices),
mDeleteDevices(ownDevices),
@ -49,6 +51,7 @@ GfxDriverInfo::GfxDriverInfo(OperatingSystem os, nsAString& vendor,
GfxDriverInfo::GfxDriverInfo(const GfxDriverInfo& aOrig)
: mOperatingSystem(aOrig.mOperatingSystem),
mOperatingSystemVersion(aOrig.mOperatingSystemVersion),
mAdapterVendor(aOrig.mAdapterVendor),
mFeature(aOrig.mFeature),
mFeatureStatus(aOrig.mFeatureStatus),

View File

@ -86,6 +86,7 @@ struct GfxDriverInfo
~GfxDriverInfo();
OperatingSystem mOperatingSystem;
uint32_t mOperatingSystemVersion;
nsString mAdapterVendor;
@ -117,6 +118,8 @@ struct GfxDriverInfo
static const nsAString& GetDeviceVendor(DeviceVendor id);
static nsAString* mDeviceVendors[DeviceVendorMax];
nsString mModel, mHardware, mProduct, mManufacturer;
};
#define GFX_DRIVER_VERSION(a,b,c,d) \

View File

@ -121,6 +121,9 @@ GetPrefNameForFeature(int32_t aFeature)
case nsIGfxInfo::FEATURE_WEBGL_MSAA:
name = BLACKLIST_PREF_BRANCH "webgl.msaa";
break;
case nsIGfxInfo::FEATURE_STAGEFRIGHT:
name = BLACKLIST_PREF_BRANCH "stagefright";
break;
default:
break;
};
@ -270,7 +273,8 @@ BlacklistFeatureToGfxFeature(const nsAString& aFeature)
return nsIGfxInfo::FEATURE_WEBGL_ANGLE;
else if (aFeature == NS_LITERAL_STRING("WEBGL_MSAA"))
return nsIGfxInfo::FEATURE_WEBGL_MSAA;
else if (aFeature == NS_LITERAL_STRING("STAGEFRIGHT"))
return nsIGfxInfo::FEATURE_STAGEFRIGHT;
return 0;
}
@ -379,6 +383,13 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
aDriverInfo.mOperatingSystem = BlacklistOSToOperatingSystem(dataValue);
}
// <osversion>14</osversion> currently only used for Android
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("osversion"),
getter_AddRefs(dataNode))) {
BlacklistNodeToTextValue(dataNode, dataValue);
aDriverInfo.mOperatingSystemVersion = strtoul(NS_LossyConvertUTF16toASCII(dataValue).get(), NULL, 10);
}
// <vendor>0x8086</vendor>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("vendor"),
getter_AddRefs(dataNode))) {
@ -440,6 +451,31 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
aDriverInfo.mComparisonOp = BlacklistComparatorToComparisonOp(dataValue);
}
// <model>foo</model>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("model"),
getter_AddRefs(dataNode))) {
BlacklistNodeToTextValue(dataNode, dataValue);
aDriverInfo.mModel = dataValue;
}
// <product>foo</product>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("product"),
getter_AddRefs(dataNode))) {
BlacklistNodeToTextValue(dataNode, dataValue);
aDriverInfo.mProduct = dataValue;
}
// <manufacturer>foo</manufacturer>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("manufacturer"),
getter_AddRefs(dataNode))) {
BlacklistNodeToTextValue(dataNode, dataValue);
aDriverInfo.mManufacturer = dataValue;
}
// <hardware>foo</hardware>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("hardware"),
getter_AddRefs(dataNode))) {
BlacklistNodeToTextValue(dataNode, dataValue);
aDriverInfo.mHardware = dataValue;
}
// We explicitly ignore unknown elements.
return true;
@ -555,6 +591,10 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
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;
@ -576,6 +616,19 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
bool match = false;
if (!info[i].mHardware.IsEmpty() && !info[i].mHardware.Equals(Hardware())) {
continue;
}
if (!info[i].mModel.IsEmpty() && !info[i].mModel.Equals(Model())) {
continue;
}
if (!info[i].mProduct.IsEmpty() && !info[i].mProduct.Equals(Product())) {
continue;
}
if (!info[i].mManufacturer.IsEmpty() && !info[i].mManufacturer.Equals(Manufacturer())) {
continue;
}
#if defined(XP_WIN) || defined(ANDROID)
switch (info[i].mComparisonOp) {
case DRIVER_LESS_THAN:
@ -741,6 +794,7 @@ GfxInfoBase::EvaluateDownloadedBlacklist(nsTArray<GfxDriverInfo>& aDriverInfo)
nsIGfxInfo::FEATURE_WEBGL_OPENGL,
nsIGfxInfo::FEATURE_WEBGL_ANGLE,
nsIGfxInfo::FEATURE_WEBGL_MSAA,
nsIGfxInfo::FEATURE_STAGEFRIGHT,
0
};

View File

@ -68,6 +68,12 @@ public:
static nsTArray<GfxDriverInfo>* mDriverInfo;
static bool mDriverInfoObserverInitialized;
virtual const nsAString& Model() const { return nsString(); }
virtual const nsAString& Hardware() const { return nsString(); }
virtual const nsAString& Product() const { return nsString(); }
virtual const nsAString& Manufacturer() const { return nsString(); }
virtual uint32_t OperatingSystemVersion() const { return 0; }
protected:
virtual nsresult GetFeatureStatusImpl(int32_t aFeature, int32_t* aStatus,