widget/cocoa/GfxInfo.mm

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include <OpenGL/OpenGL.h>
     7 #include <OpenGL/CGLRenderers.h>
     9 #include "mozilla/ArrayUtils.h"
    11 #include "GfxInfo.h"
    12 #include "nsUnicharUtils.h"
    13 #include "nsCocoaFeatures.h"
    14 #include "mozilla/Preferences.h"
    15 #include <algorithm>
    17 #import <Foundation/Foundation.h>
    18 #import <IOKit/IOKitLib.h>
    19 #import <Cocoa/Cocoa.h>
    21 #if defined(MOZ_CRASHREPORTER)
    22 #include "nsExceptionHandler.h"
    23 #include "nsICrashReporter.h"
    24 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
    25 #endif
    27 #define MAC_OS_X_VERSION_MASK       0x0000FFFF
    28 #define MAC_OS_X_VERSION_MAJOR_MASK 0x0000FFF0
    29 #define MAC_OS_X_VERSION_10_6_HEX   0x00001060
    30 #define MAC_OS_X_VERSION_10_7_HEX   0x00001070
    31 #define MAC_OS_X_VERSION_10_8_HEX   0x00001080
    33 using namespace mozilla;
    34 using namespace mozilla::widget;
    36 #ifdef DEBUG
    37 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
    38 #endif
    40 GfxInfo::GfxInfo()
    41 {
    42 }
    44 static OperatingSystem
    45 OSXVersionToOperatingSystem(uint32_t aOSXVersion)
    46 {
    47   switch (aOSXVersion & MAC_OS_X_VERSION_MAJOR_MASK) {
    48     case MAC_OS_X_VERSION_10_6_HEX:
    49       return DRIVER_OS_OS_X_10_6;
    50     case MAC_OS_X_VERSION_10_7_HEX:
    51       return DRIVER_OS_OS_X_10_7;
    52     case MAC_OS_X_VERSION_10_8_HEX:
    53       return DRIVER_OS_OS_X_10_8;
    54   }
    56   return DRIVER_OS_UNKNOWN;
    57 }
    58 // The following three functions are derived from Chromium code
    59 static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
    60                                        CFStringRef propertyName)
    61 {
    62   return IORegistryEntrySearchCFProperty(dspPort,
    63                                          kIOServicePlane,
    64                                          propertyName,
    65                                          kCFAllocatorDefault,
    66                                          kIORegistryIterateRecursively |
    67                                          kIORegistryIterateParents);
    68 }
    70 static uint32_t IntValueOfCFData(CFDataRef d)
    71 {
    72   uint32_t value = 0;
    74   if (d) {
    75     const uint32_t *vp = reinterpret_cast<const uint32_t*>(CFDataGetBytePtr(d));
    76     if (vp != NULL)
    77       value = *vp;
    78   }
    80   return value;
    81 }
    83 void
    84 GfxInfo::GetDeviceInfo()
    85 {
    86   io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
    87   CFTypeRef vendor_id_ref = SearchPortForProperty(dsp_port, CFSTR("vendor-id"));
    88   if (vendor_id_ref) {
    89     mAdapterVendorID.AppendPrintf("0x%4x", IntValueOfCFData((CFDataRef)vendor_id_ref));
    90     CFRelease(vendor_id_ref);
    91   }
    92   CFTypeRef device_id_ref = SearchPortForProperty(dsp_port, CFSTR("device-id"));
    93   if (device_id_ref) {
    94     mAdapterDeviceID.AppendPrintf("0x%4x", IntValueOfCFData((CFDataRef)device_id_ref));
    95     CFRelease(device_id_ref);
    96   }
    97 }
    99 nsresult
   100 GfxInfo::Init()
   101 {
   102   nsresult rv = GfxInfoBase::Init();
   104   // Calling CGLQueryRendererInfo causes us to switch to the discrete GPU
   105   // even when we don't want to. We'll avoid doing so for now and just
   106   // use the device ids.
   108   GetDeviceInfo();
   110   AddCrashReportAnnotations();
   112   mOSXVersion = nsCocoaFeatures::OSXVersion();
   114   return rv;
   115 }
   117 NS_IMETHODIMP
   118 GfxInfo::GetD2DEnabled(bool *aEnabled)
   119 {
   120   return NS_ERROR_FAILURE;
   121 }
   123 NS_IMETHODIMP
   124 GfxInfo::GetDWriteEnabled(bool *aEnabled)
   125 {
   126   return NS_ERROR_FAILURE;
   127 }
   129 /* readonly attribute DOMString DWriteVersion; */
   130 NS_IMETHODIMP
   131 GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
   132 {
   133   return NS_ERROR_FAILURE;
   134 }
   136 /* readonly attribute DOMString cleartypeParameters; */
   137 NS_IMETHODIMP
   138 GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams)
   139 {
   140   return NS_ERROR_FAILURE;
   141 }
   143 /* readonly attribute DOMString adapterDescription; */
   144 NS_IMETHODIMP
   145 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
   146 {
   147   aAdapterDescription.AssignLiteral("");
   148   return NS_OK;
   149 }
   151 /* readonly attribute DOMString adapterDescription2; */
   152 NS_IMETHODIMP
   153 GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
   154 {
   155   return NS_ERROR_FAILURE;
   156 }
   158 /* readonly attribute DOMString adapterRAM; */
   159 NS_IMETHODIMP
   160 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
   161 {
   162   aAdapterRAM = mAdapterRAMString;
   163   return NS_OK;
   164 }
   166 /* readonly attribute DOMString adapterRAM2; */
   167 NS_IMETHODIMP
   168 GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
   169 {
   170   return NS_ERROR_FAILURE;
   171 }
   173 /* readonly attribute DOMString adapterDriver; */
   174 NS_IMETHODIMP
   175 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
   176 {
   177   aAdapterDriver.AssignLiteral("");
   178   return NS_OK;
   179 }
   181 /* readonly attribute DOMString adapterDriver2; */
   182 NS_IMETHODIMP
   183 GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
   184 {
   185   return NS_ERROR_FAILURE;
   186 }
   188 /* readonly attribute DOMString adapterDriverVersion; */
   189 NS_IMETHODIMP
   190 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
   191 {
   192   aAdapterDriverVersion.AssignLiteral("");
   193   return NS_OK;
   194 }
   196 /* readonly attribute DOMString adapterDriverVersion2; */
   197 NS_IMETHODIMP
   198 GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
   199 {
   200   return NS_ERROR_FAILURE;
   201 }
   203 /* readonly attribute DOMString adapterDriverDate; */
   204 NS_IMETHODIMP
   205 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
   206 {
   207   aAdapterDriverDate.AssignLiteral("");
   208   return NS_OK;
   209 }
   211 /* readonly attribute DOMString adapterDriverDate2; */
   212 NS_IMETHODIMP
   213 GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
   214 {
   215   return NS_ERROR_FAILURE;
   216 }
   218 /* readonly attribute DOMString adapterVendorID; */
   219 NS_IMETHODIMP
   220 GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID)
   221 {
   222   aAdapterVendorID = mAdapterVendorID;
   223   return NS_OK;
   224 }
   226 /* readonly attribute DOMString adapterVendorID2; */
   227 NS_IMETHODIMP
   228 GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID)
   229 {
   230   return NS_ERROR_FAILURE;
   231 }
   233 /* readonly attribute DOMString adapterDeviceID; */
   234 NS_IMETHODIMP
   235 GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID)
   236 {
   237   aAdapterDeviceID = mAdapterDeviceID;
   238   return NS_OK;
   239 }
   241 /* readonly attribute DOMString adapterDeviceID2; */
   242 NS_IMETHODIMP
   243 GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID)
   244 {
   245   return NS_ERROR_FAILURE;
   246 }
   248 /* readonly attribute boolean isGPU2Active; */
   249 NS_IMETHODIMP
   250 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active)
   251 {
   252   return NS_ERROR_FAILURE;
   253 }
   255 void
   256 GfxInfo::AddCrashReportAnnotations()
   257 {
   258 #if defined(MOZ_CRASHREPORTER)
   259   nsString deviceID, vendorID;
   260   nsAutoCString narrowDeviceID, narrowVendorID;
   262   GetAdapterDeviceID(deviceID);
   263   CopyUTF16toUTF8(deviceID, narrowDeviceID);
   264   GetAdapterVendorID(vendorID);
   265   CopyUTF16toUTF8(vendorID, narrowVendorID);
   267   CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
   268                                      narrowVendorID);
   269   CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
   270                                      narrowDeviceID);
   271   /* Add an App Note for now so that we get the data immediately. These
   272    * can go away after we store the above in the socorro db */
   273   nsAutoCString note;
   274   /* AppendPrintf only supports 32 character strings, mrghh. */
   275   note.Append("AdapterVendorID: ");
   276   note.Append(narrowVendorID);
   277   note.Append(", AdapterDeviceID: ");
   278   note.Append(narrowDeviceID);
   279   CrashReporter::AppendAppNotesToCrashReport(note);
   280 #endif
   281 }
   283 // We don't support checking driver versions on Mac.
   284 #define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn) \
   285   APPEND_TO_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn,           \
   286                              DRIVER_COMPARISON_IGNORED, V(0,0,0,0), "")
   289 const nsTArray<GfxDriverInfo>&
   290 GfxInfo::GetGfxDriverInfo()
   291 {
   292   if (!mDriverInfo->Length()) {
   293     IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
   294       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
   295       nsIGfxInfo::FEATURE_WEBGL_MSAA, nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION);
   296     IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
   297       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(RadeonX1000),
   298       nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE);
   299     IMPLEMENT_MAC_DRIVER_BLOCKLIST(DRIVER_OS_ALL,
   300       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(Geforce7300GT), 
   301       nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_BLOCKED_DEVICE);
   302   }
   303   return *mDriverInfo;
   304 }
   306 nsresult
   307 GfxInfo::GetFeatureStatusImpl(int32_t aFeature, 
   308                               int32_t* aStatus,
   309                               nsAString& aSuggestedDriverVersion,
   310                               const nsTArray<GfxDriverInfo>& aDriverInfo,
   311                               OperatingSystem* aOS /* = nullptr */)
   312 {
   313   NS_ENSURE_ARG_POINTER(aStatus);
   314   aSuggestedDriverVersion.SetIsVoid(true);
   315   *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
   316   OperatingSystem os = OSXVersionToOperatingSystem(mOSXVersion);
   317   if (aOS)
   318     *aOS = os;
   320   // Don't evaluate special cases when we're evaluating the downloaded blocklist.
   321   if (!aDriverInfo.Length()) {
   322     if (aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) {
   323       // Blacklist all ATI cards on OSX, except for
   324       // 0x6760 and 0x9488
   325       if (mAdapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorATI), nsCaseInsensitiveStringComparator()) && 
   326           (mAdapterDeviceID.LowerCaseEqualsLiteral("0x6760") ||
   327            mAdapterDeviceID.LowerCaseEqualsLiteral("0x9488"))) {
   328         *aStatus = nsIGfxInfo::FEATURE_NO_INFO;
   329         return NS_OK;
   330       }
   331     }
   332   }
   334   return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os);
   335 }
   337 #ifdef DEBUG
   339 // Implement nsIGfxInfoDebug
   341 /* void spoofVendorID (in DOMString aVendorID); */
   342 NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID)
   343 {
   344   mAdapterVendorID = aVendorID;
   345   return NS_OK;
   346 }
   348 /* void spoofDeviceID (in unsigned long aDeviceID); */
   349 NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID)
   350 {
   351   mAdapterDeviceID = aDeviceID;
   352   return NS_OK;
   353 }
   355 /* void spoofDriverVersion (in DOMString aDriverVersion); */
   356 NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion)
   357 {
   358   mDriverVersion = aDriverVersion;
   359   return NS_OK;
   360 }
   362 /* void spoofOSVersion (in unsigned long aVersion); */
   363 NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion)
   364 {
   365   mOSXVersion = aVersion;
   366   return NS_OK;
   367 }
   369 #endif

mercurial