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 "nsISeekableStream.h"
#include "pratom.h" #include "pratom.h"
#include "nsMediaPluginReader.h" #include "nsMediaPluginReader.h"
#include "nsIGfxInfo.h"
#include "MPAPI.h" #include "MPAPI.h"
@ -87,6 +88,29 @@ static PluginHost sPluginHost = {
void nsMediaPluginHost::TryLoad(const char *name) 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); PRLibrary *lib = PR_LoadLibrary(name);
if (lib) { if (lib) {
Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST")); 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.default-no-alpha", false);
pref("webgl.force-layers-readback", false); pref("webgl.force-layers-readback", false);
// Stagefright prefs
pref("stagefright.force-enabled", false);
pref("stagefright.disabled", false);
#ifdef XP_WIN #ifdef XP_WIN
// The default TCP send window on Windows is too small, and autotuning only occurs on receive // The default TCP send window on Windows is too small, and autotuning only occurs on receive
pref("network.tcp.sendbuffer", 131072); 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. // 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. // But we should really move this out of GfxInfo.
if (mozilla::AndroidBridge::Bridge()) { if (mozilla::AndroidBridge::Bridge()) {
nsAutoString str; if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MODEL", mModel)) {
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MODEL", str)) { mAdapterDescription.AppendPrintf(" -- Model: %s", NS_LossyConvertUTF16toASCII(mModel).get());
mAdapterDescription.AppendPrintf(" -- Model: %s", NS_LossyConvertUTF16toASCII(str).get());
} }
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "PRODUCT", str)) { if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "PRODUCT", mProduct)) {
mAdapterDescription.AppendPrintf(", Product: %s", NS_LossyConvertUTF16toASCII(str).get()); mAdapterDescription.AppendPrintf(", Product: %s", NS_LossyConvertUTF16toASCII(mProduct).get());
} }
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MANUFACTURER", str)) { if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MANUFACTURER", mManufacturer)) {
mAdapterDescription.AppendPrintf(", Manufacturer: %s", NS_LossyConvertUTF16toASCII(str).get()); mAdapterDescription.AppendPrintf(", Manufacturer: %s", NS_LossyConvertUTF16toASCII(mManufacturer).get());
} }
int32_t version; // the HARDWARE field isn't available on Android SDK < 8 int32_t signedVersion;
if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &version)) if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &signedVersion))
version = 0; signedVersion = 0;
mOSVersion = signedVersion;
if (version >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", str)) { // the HARDWARE field isn't available on Android SDK < 8
if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", str)) { if (mOSVersion >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", mHardware)) {
mAdapterDescription.AppendPrintf(", Hardware: %s", NS_LossyConvertUTF16toASCII(str).get()); mAdapterDescription.AppendPrintf(", Hardware: %s", NS_LossyConvertUTF16toASCII(mHardware).get());
}
} }
} }
@ -309,7 +308,7 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
NS_ENSURE_ARG_POINTER(aStatus); NS_ENSURE_ARG_POINTER(aStatus);
aSuggestedDriverVersion.SetIsVoid(true); aSuggestedDriverVersion.SetIsVoid(true);
*aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
OperatingSystem os = DRIVER_OS_ANDROID; OperatingSystem os = mOS;
if (aOS) if (aOS)
*aOS = os; *aOS = os;
@ -330,6 +329,27 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
return NS_OK; 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); 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); */ /* void spoofOSVersion (in unsigned long aVersion); */
NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion)
{ {
EnsureInitializedFromGfxInfoData(); // initialization from GfxInfo data overwrites mOSVersion
mOSVersion = aVersion;
return NS_OK; return NS_OK;
} }
#endif #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(); void EnsureInitializedFromGfxInfoData();
virtual const nsAString& Model() const;
virtual const nsAString& Hardware() const;
virtual const nsAString& Product() const;
virtual const nsAString& Manufacturer() const;
#ifdef DEBUG #ifdef DEBUG
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIGFXINFODEBUG NS_DECL_NSIGFXINFODEBUG
#endif #endif
virtual uint32_t OperatingSystemVersion() const { return mOSVersion; }
protected: protected:
virtual nsresult GetFeatureStatusImpl(int32_t aFeature, virtual nsresult GetFeatureStatusImpl(int32_t aFeature,
@ -76,6 +83,11 @@ private:
nsCString mError; nsCString mError;
nsCString mAdapterDescription; nsCString mAdapterDescription;
OperatingSystem mOS;
uint32_t mOSVersion;
nsString mModel, mHardware, mManufacturer, mProduct;
}; };
} // namespace widget } // namespace widget

View File

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

View File

@ -8,7 +8,7 @@
/* NOTE: this interface is completely undesigned, not stable and likely to change */ /* 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 interface nsIGfxInfo : nsISupports
{ {
/* /*
@ -77,6 +77,8 @@ interface nsIGfxInfo : nsISupports
const long FEATURE_WEBGL_ANGLE = 7; const long FEATURE_WEBGL_ANGLE = 7;
/* Whether WebGL antialiasing is supported. */ /* Whether WebGL antialiasing is supported. */
const long FEATURE_WEBGL_MSAA = 8; const long FEATURE_WEBGL_MSAA = 8;
/* Whether Stagefright is supported */
const long FEATURE_STAGEFRIGHT = 9;
/* /*
* A set of return values from GetFeatureStatus * A set of return values from GetFeatureStatus

View File

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

View File

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

View File

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

View File

@ -121,6 +121,9 @@ GetPrefNameForFeature(int32_t aFeature)
case nsIGfxInfo::FEATURE_WEBGL_MSAA: case nsIGfxInfo::FEATURE_WEBGL_MSAA:
name = BLACKLIST_PREF_BRANCH "webgl.msaa"; name = BLACKLIST_PREF_BRANCH "webgl.msaa";
break; break;
case nsIGfxInfo::FEATURE_STAGEFRIGHT:
name = BLACKLIST_PREF_BRANCH "stagefright";
break;
default: default:
break; break;
}; };
@ -270,7 +273,8 @@ BlacklistFeatureToGfxFeature(const nsAString& aFeature)
return nsIGfxInfo::FEATURE_WEBGL_ANGLE; return nsIGfxInfo::FEATURE_WEBGL_ANGLE;
else if (aFeature == NS_LITERAL_STRING("WEBGL_MSAA")) else if (aFeature == NS_LITERAL_STRING("WEBGL_MSAA"))
return nsIGfxInfo::FEATURE_WEBGL_MSAA; return nsIGfxInfo::FEATURE_WEBGL_MSAA;
else if (aFeature == NS_LITERAL_STRING("STAGEFRIGHT"))
return nsIGfxInfo::FEATURE_STAGEFRIGHT;
return 0; return 0;
} }
@ -379,6 +383,13 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
aDriverInfo.mOperatingSystem = BlacklistOSToOperatingSystem(dataValue); 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> // <vendor>0x8086</vendor>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("vendor"), if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("vendor"),
getter_AddRefs(dataNode))) { getter_AddRefs(dataNode))) {
@ -440,6 +451,31 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
aDriverInfo.mComparisonOp = BlacklistComparatorToComparisonOp(dataValue); 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. // We explicitly ignore unknown elements.
return true; return true;
@ -555,6 +591,10 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
continue; continue;
} }
if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
continue;
}
if (!info[i].mAdapterVendor.Equals(GfxDriverInfo::GetDeviceVendor(VendorAll), nsCaseInsensitiveStringComparator()) && if (!info[i].mAdapterVendor.Equals(GfxDriverInfo::GetDeviceVendor(VendorAll), nsCaseInsensitiveStringComparator()) &&
!info[i].mAdapterVendor.Equals(adapterVendorID, nsCaseInsensitiveStringComparator())) { !info[i].mAdapterVendor.Equals(adapterVendorID, nsCaseInsensitiveStringComparator())) {
continue; continue;
@ -576,6 +616,19 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
bool match = false; 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) #if defined(XP_WIN) || defined(ANDROID)
switch (info[i].mComparisonOp) { switch (info[i].mComparisonOp) {
case DRIVER_LESS_THAN: case DRIVER_LESS_THAN:
@ -741,6 +794,7 @@ GfxInfoBase::EvaluateDownloadedBlacklist(nsTArray<GfxDriverInfo>& aDriverInfo)
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_WEBGL_OPENGL,
nsIGfxInfo::FEATURE_WEBGL_ANGLE, nsIGfxInfo::FEATURE_WEBGL_ANGLE,
nsIGfxInfo::FEATURE_WEBGL_MSAA, nsIGfxInfo::FEATURE_WEBGL_MSAA,
nsIGfxInfo::FEATURE_STAGEFRIGHT,
0 0
}; };

View File

@ -68,6 +68,12 @@ public:
static nsTArray<GfxDriverInfo>* mDriverInfo; static nsTArray<GfxDriverInfo>* mDriverInfo;
static bool mDriverInfoObserverInitialized; 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: protected:
virtual nsresult GetFeatureStatusImpl(int32_t aFeature, int32_t* aStatus, virtual nsresult GetFeatureStatusImpl(int32_t aFeature, int32_t* aStatus,