michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "GfxInfo.h" michael@0: #include "GLContext.h" michael@0: #include "GLContextProvider.h" michael@0: #include "nsUnicharUtils.h" michael@0: #include "prenv.h" michael@0: #include "prprf.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsVersionComparator.h" michael@0: #include "AndroidBridge.h" michael@0: #include "nsIWindowWatcher.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: michael@0: #if defined(MOZ_CRASHREPORTER) michael@0: #include "nsExceptionHandler.h" michael@0: #include "nsICrashReporter.h" michael@0: #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" michael@0: #endif michael@0: michael@0: namespace mozilla { michael@0: namespace widget { michael@0: michael@0: class GfxInfo::GLStrings michael@0: { michael@0: nsCString mVendor; michael@0: nsCString mRenderer; michael@0: nsCString mVersion; michael@0: bool mReady; michael@0: michael@0: public: michael@0: GLStrings() michael@0: : mReady(false) michael@0: {} michael@0: michael@0: const nsCString& Vendor() { michael@0: EnsureInitialized(); michael@0: return mVendor; michael@0: } michael@0: michael@0: void SpoofVendor(const nsCString& s) { michael@0: EnsureInitialized(); michael@0: mVendor = s; michael@0: } michael@0: michael@0: const nsCString& Renderer() { michael@0: EnsureInitialized(); michael@0: return mRenderer; michael@0: } michael@0: michael@0: void SpoofRenderer(const nsCString& s) { michael@0: EnsureInitialized(); michael@0: mRenderer = s; michael@0: } michael@0: michael@0: const nsCString& Version() { michael@0: EnsureInitialized(); michael@0: return mVersion; michael@0: } michael@0: michael@0: void SpoofVersion(const nsCString& s) { michael@0: EnsureInitialized(); michael@0: mVersion = s; michael@0: } michael@0: michael@0: void EnsureInitialized() { michael@0: if (mReady) { michael@0: return; michael@0: } michael@0: michael@0: nsRefPtr gl = gl::GLContextProvider::CreateOffscreen( michael@0: gfxIntSize(16, 16), michael@0: gfx::SurfaceCaps::ForRGB()); michael@0: michael@0: if (!gl) { michael@0: // Setting mReady to true here means that we won't retry. Everything will michael@0: // remain blacklisted forever. Ideally, we would like to update that once michael@0: // any GLContext is successfully created, like the compositor's GLContext. michael@0: mReady = true; michael@0: return; michael@0: } michael@0: michael@0: gl->MakeCurrent(); michael@0: michael@0: const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR"); michael@0: if (spoofedVendor) michael@0: mVendor.Assign(spoofedVendor); michael@0: else michael@0: mVendor.Assign((const char*)gl->fGetString(LOCAL_GL_VENDOR)); michael@0: const char *spoofedRenderer = PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER"); michael@0: if (spoofedRenderer) michael@0: mRenderer.Assign(spoofedRenderer); michael@0: else michael@0: mRenderer.Assign((const char*)gl->fGetString(LOCAL_GL_RENDERER)); michael@0: const char *spoofedVersion = PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION"); michael@0: if (spoofedVersion) michael@0: mVersion.Assign(spoofedVersion); michael@0: else michael@0: mVersion.Assign((const char*)gl->fGetString(LOCAL_GL_VERSION)); michael@0: michael@0: mReady = true; michael@0: } michael@0: }; michael@0: michael@0: #ifdef DEBUG michael@0: NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug) michael@0: #endif michael@0: michael@0: GfxInfo::GfxInfo() michael@0: : mInitialized(false) michael@0: , mGLStrings(new GLStrings) michael@0: { michael@0: } michael@0: michael@0: /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization michael@0: * has occurred because they depend on it for information. (See bug 591561) */ michael@0: nsresult michael@0: GfxInfo::GetD2DEnabled(bool *aEnabled) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nsresult michael@0: GfxInfo::GetDWriteEnabled(bool *aEnabled) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString DWriteVersion; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString cleartypeParameters; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: void michael@0: GfxInfo::EnsureInitialized() michael@0: { michael@0: if (mInitialized) michael@0: return; michael@0: michael@0: mGLStrings->EnsureInitialized(); michael@0: michael@0: MOZ_ASSERT(mozilla::AndroidBridge::Bridge()); michael@0: michael@0: if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MODEL", mModel)) { michael@0: mAdapterDescription.AppendPrintf("Model: %s", NS_LossyConvertUTF16toASCII(mModel).get()); michael@0: } michael@0: michael@0: if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "PRODUCT", mProduct)) { michael@0: mAdapterDescription.AppendPrintf(", Product: %s", NS_LossyConvertUTF16toASCII(mProduct).get()); michael@0: } michael@0: michael@0: if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MANUFACTURER", mManufacturer)) { michael@0: mAdapterDescription.AppendPrintf(", Manufacturer: %s", NS_LossyConvertUTF16toASCII(mManufacturer).get()); michael@0: } michael@0: michael@0: int32_t sdkVersion; michael@0: if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &sdkVersion)) michael@0: sdkVersion = 0; michael@0: michael@0: // the HARDWARE field isn't available on Android SDK < 8 michael@0: if (sdkVersion >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", mHardware)) { michael@0: mAdapterDescription.AppendPrintf(", Hardware: %s", NS_LossyConvertUTF16toASCII(mHardware).get()); michael@0: } michael@0: michael@0: nsString release; michael@0: mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", release); michael@0: mOSVersion = NS_LossyConvertUTF16toASCII(release); michael@0: michael@0: mOSVersionInteger = 0; michael@0: char a[5], b[5], c[5], d[5]; michael@0: SplitDriverVersion(mOSVersion.get(), a, b, c, d); michael@0: uint8_t na = atoi(a); michael@0: uint8_t nb = atoi(b); michael@0: uint8_t nc = atoi(c); michael@0: uint8_t nd = atoi(d); michael@0: michael@0: mOSVersionInteger = (uint32_t(na) << 24) | michael@0: (uint32_t(nb) << 16) | michael@0: (uint32_t(nc) << 8) | michael@0: uint32_t(nd); michael@0: michael@0: mAdapterDescription.AppendPrintf(", OpenGL: %s -- %s -- %s", michael@0: mGLStrings->Vendor().get(), michael@0: mGLStrings->Renderer().get(), michael@0: mGLStrings->Version().get()); michael@0: michael@0: AddCrashReportAnnotations(); michael@0: michael@0: mInitialized = true; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDescription; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription) michael@0: { michael@0: EnsureInitialized(); michael@0: aAdapterDescription = NS_ConvertASCIItoUTF16(mAdapterDescription); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDescription2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterRAM; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM) michael@0: { michael@0: EnsureInitialized(); michael@0: aAdapterRAM.AssignLiteral(""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterRAM2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriver; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver) michael@0: { michael@0: EnsureInitialized(); michael@0: aAdapterDriver.AssignLiteral(""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriver2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverVersion; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) michael@0: { michael@0: EnsureInitialized(); michael@0: aAdapterDriverVersion = NS_ConvertASCIItoUTF16(mGLStrings->Version()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverVersion2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverDate; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate) michael@0: { michael@0: EnsureInitialized(); michael@0: aAdapterDriverDate.AssignLiteral(""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverDate2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterVendorID; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID) michael@0: { michael@0: EnsureInitialized(); michael@0: aAdapterVendorID = NS_ConvertASCIItoUTF16(mGLStrings->Vendor()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterVendorID2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDeviceID; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID) michael@0: { michael@0: EnsureInitialized(); michael@0: aAdapterDeviceID = NS_ConvertASCIItoUTF16(mGLStrings->Renderer()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDeviceID2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute boolean isGPU2Active; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) michael@0: { michael@0: EnsureInitialized(); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: void michael@0: GfxInfo::AddCrashReportAnnotations() michael@0: { michael@0: #if defined(MOZ_CRASHREPORTER) michael@0: CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), michael@0: mGLStrings->Vendor()); michael@0: CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), michael@0: mGLStrings->Renderer()); michael@0: michael@0: /* Add an App Note for now so that we get the data immediately. These michael@0: * can go away after we store the above in the socorro db */ michael@0: nsAutoCString note; michael@0: note.AppendPrintf("AdapterDescription: '%s'\n", mAdapterDescription.get()); michael@0: michael@0: CrashReporter::AppendAppNotesToCrashReport(note); michael@0: #endif michael@0: } michael@0: michael@0: const nsTArray& michael@0: GfxInfo::GetGfxDriverInfo() michael@0: { michael@0: if (mDriverInfo->IsEmpty()) { michael@0: APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, michael@0: (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAll), GfxDriverInfo::allDevices, michael@0: nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_NO_INFO, michael@0: DRIVER_COMPARISON_IGNORED, GfxDriverInfo::allDriverVersions ); michael@0: } michael@0: michael@0: return *mDriverInfo; michael@0: } michael@0: michael@0: nsresult michael@0: GfxInfo::GetFeatureStatusImpl(int32_t aFeature, michael@0: int32_t *aStatus, michael@0: nsAString & aSuggestedDriverVersion, michael@0: const nsTArray& aDriverInfo, michael@0: OperatingSystem* aOS /* = nullptr */) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aStatus); michael@0: aSuggestedDriverVersion.SetIsVoid(true); michael@0: *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; michael@0: OperatingSystem os = mOS; michael@0: if (aOS) michael@0: *aOS = os; michael@0: michael@0: // OpenGL layers are never blacklisted on Android. michael@0: // This early return is so we avoid potentially slow michael@0: // GLStrings initialization on startup when we initialize GL layers. michael@0: if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS) { michael@0: *aStatus = nsIGfxInfo::FEATURE_NO_INFO; michael@0: return NS_OK; michael@0: } michael@0: michael@0: EnsureInitialized(); michael@0: michael@0: if (mGLStrings->Vendor().IsEmpty() || mGLStrings->Renderer().IsEmpty()) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: michael@0: // Don't evaluate special cases when evaluating the downloaded blocklist. michael@0: if (aDriverInfo.IsEmpty()) { michael@0: if (aFeature == FEATURE_WEBGL_OPENGL) { michael@0: if (mGLStrings->Renderer().Find("Adreno 200") != -1 || michael@0: mGLStrings->Renderer().Find("Adreno 205") != -1) michael@0: { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (mHardware.Equals(NS_LITERAL_STRING("ville"))) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: if (aFeature == FEATURE_STAGEFRIGHT) { michael@0: NS_LossyConvertUTF16toASCII cManufacturer(mManufacturer); michael@0: NS_LossyConvertUTF16toASCII cModel(mModel); michael@0: NS_LossyConvertUTF16toASCII cHardware(mHardware); michael@0: michael@0: if (cHardware.Equals("antares") || michael@0: cHardware.Equals("harmony") || michael@0: cHardware.Equals("picasso") || michael@0: cHardware.Equals("picasso_e") || michael@0: cHardware.Equals("ventana") || michael@0: cHardware.Equals("rk30board")) michael@0: { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (CompareVersions(mOSVersion.get(), "2.2.0") >= 0 && michael@0: CompareVersions(mOSVersion.get(), "2.3.0") < 0) michael@0: { michael@0: // Froyo LG devices are whitelisted. michael@0: // All other Froyo michael@0: bool isWhitelisted = michael@0: cManufacturer.Equals("lge", nsCaseInsensitiveCStringComparator()); michael@0: michael@0: if (!isWhitelisted) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: else if (CompareVersions(mOSVersion.get(), "2.3.0") >= 0 && michael@0: CompareVersions(mOSVersion.get(), "2.4.0") < 0) michael@0: { michael@0: // Gingerbread HTC devices are whitelisted. michael@0: // Gingerbread Samsung devices are whitelisted except for: michael@0: // Samsung devices identified in Bug 847837 michael@0: // Gingerbread Sony devices are whitelisted. michael@0: // All other Gingerbread devices are blacklisted. michael@0: bool isWhitelisted = michael@0: cManufacturer.Equals("htc", nsCaseInsensitiveCStringComparator()) || michael@0: (cManufacturer.Find("sony", true) != -1) || michael@0: cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator()); michael@0: michael@0: if (cModel.Equals("GT-I8160", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-I8160L", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-I8530", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-I9070", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-I9070P", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-I8160P", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-S7500", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-S7500T", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-S7500L", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("GT-S6500T", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("smdkc110", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("smdkc210", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("herring", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("shw-m110s", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("shw-m180s", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("n1", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("latona", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("aalto", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("atlas", nsCaseInsensitiveCStringComparator()) || michael@0: cHardware.Equals("qcom", nsCaseInsensitiveCStringComparator())) michael@0: { michael@0: isWhitelisted = false; michael@0: } michael@0: michael@0: if (!isWhitelisted) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: else if (CompareVersions(mOSVersion.get(), "3.0.0") >= 0 && michael@0: CompareVersions(mOSVersion.get(), "4.0.0") < 0) michael@0: { michael@0: // Honeycomb Samsung devices are whitelisted. michael@0: // All other Honeycomb devices are blacklisted. michael@0: bool isWhitelisted = michael@0: cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator()); michael@0: michael@0: if (!isWhitelisted) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: else if (CompareVersions(mOSVersion.get(), "4.0.0") < 0) michael@0: { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION; michael@0: return NS_OK; michael@0: } michael@0: else if (CompareVersions(mOSVersion.get(), "4.1.0") < 0) michael@0: { michael@0: // Whitelist: michael@0: // All Samsung ICS devices, except for: michael@0: // Samsung SGH-I717 (Bug 845729) michael@0: // Samsung SGH-I727 (Bug 845729) michael@0: // Samsung SGH-I757 (Bug 845729) michael@0: // All Galaxy nexus ICS devices michael@0: // Sony Xperia Ion (LT28) ICS devices michael@0: bool isWhitelisted = michael@0: cModel.Equals("LT28h", nsCaseInsensitiveCStringComparator()) || michael@0: cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator()) || michael@0: cModel.Equals("galaxy nexus", nsCaseInsensitiveCStringComparator()); // some Galaxy Nexus have manufacturer=amazon michael@0: michael@0: if (cModel.Find("SGH-I717", true) != -1 || michael@0: cModel.Find("SGH-I727", true) != -1 || michael@0: cModel.Find("SGH-I757", true) != -1) michael@0: { michael@0: isWhitelisted = false; michael@0: } michael@0: michael@0: if (!isWhitelisted) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: else if (CompareVersions(mOSVersion.get(), "4.2.0") < 0) michael@0: { michael@0: // Whitelist: michael@0: // All JB phones except for those in blocklist below michael@0: // Blocklist: michael@0: // Samsung devices from bug 812881 and 853522. michael@0: // Motorola XT890 from bug 882342. michael@0: bool isBlocklisted = michael@0: cModel.Find("GT-P3100", true) != -1 || michael@0: cModel.Find("GT-P3110", true) != -1 || michael@0: cModel.Find("GT-P3113", true) != -1 || michael@0: cModel.Find("GT-P5100", true) != -1 || michael@0: cModel.Find("GT-P5110", true) != -1 || michael@0: cModel.Find("GT-P5113", true) != -1 || michael@0: cModel.Find("XT890", true) != -1; michael@0: michael@0: if (isBlocklisted) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: else if (CompareVersions(mOSVersion.get(), "4.3.0") < 0) michael@0: { michael@0: // Blocklist all Sony devices michael@0: if (cManufacturer.Find("Sony", true) != -1) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (aFeature == FEATURE_WEBRTC_HW_ACCELERATION) { michael@0: NS_LossyConvertUTF16toASCII cManufacturer(mManufacturer); michael@0: NS_LossyConvertUTF16toASCII cModel(mModel); michael@0: NS_LossyConvertUTF16toASCII cHardware(mHardware); michael@0: michael@0: if (cHardware.Equals("hammerhead") && michael@0: CompareVersions(mOSVersion.get(), "4.4.2") >= 0 && michael@0: cManufacturer.Equals("lge", nsCaseInsensitiveCStringComparator()) && michael@0: cModel.Equals("nexus 5", nsCaseInsensitiveCStringComparator())) { michael@0: *aStatus = nsIGfxInfo::FEATURE_NO_INFO; michael@0: return NS_OK; michael@0: } else { michael@0: // Blocklist all other devices except Nexus 5 which VP8 hardware acceleration is supported michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: } michael@0: michael@0: return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os); michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: michael@0: // Implement nsIGfxInfoDebug michael@0: michael@0: /* void spoofVendorID (in DOMString aVendorID); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID) michael@0: { michael@0: EnsureInitialized(); michael@0: mGLStrings->SpoofVendor(NS_LossyConvertUTF16toASCII(aVendorID)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void spoofDeviceID (in unsigned long aDeviceID); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID) michael@0: { michael@0: EnsureInitialized(); michael@0: mGLStrings->SpoofRenderer(NS_LossyConvertUTF16toASCII(aDeviceID)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void spoofDriverVersion (in DOMString aDriverVersion); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion) michael@0: { michael@0: EnsureInitialized(); michael@0: mGLStrings->SpoofVersion(NS_LossyConvertUTF16toASCII(aDriverVersion)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void spoofOSVersion (in unsigned long aVersion); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) michael@0: { michael@0: EnsureInitialized(); michael@0: mOSVersion = aVersion; michael@0: return NS_OK; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: nsString GfxInfo::Model() michael@0: { michael@0: EnsureInitialized(); michael@0: return mModel; michael@0: } michael@0: michael@0: nsString GfxInfo::Hardware() michael@0: { michael@0: EnsureInitialized(); michael@0: return mHardware; michael@0: } michael@0: michael@0: nsString GfxInfo::Product() michael@0: { michael@0: EnsureInitialized(); michael@0: return mProduct; michael@0: } michael@0: michael@0: nsString GfxInfo::Manufacturer() michael@0: { michael@0: EnsureInitialized(); michael@0: return mManufacturer; michael@0: } michael@0: michael@0: uint32_t GfxInfo::OperatingSystemVersion() michael@0: { michael@0: EnsureInitialized(); michael@0: return mOSVersionInteger; michael@0: } michael@0: michael@0: } michael@0: }