Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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 "GfxInfo.h"
7 #include "GLContext.h"
8 #include "GLContextProvider.h"
9 #include "nsUnicharUtils.h"
10 #include "prenv.h"
11 #include "prprf.h"
12 #include "nsHashKeys.h"
13 #include "nsVersionComparator.h"
14 #include "AndroidBridge.h"
15 #include "nsIWindowWatcher.h"
16 #include "nsServiceManagerUtils.h"
18 #if defined(MOZ_CRASHREPORTER)
19 #include "nsExceptionHandler.h"
20 #include "nsICrashReporter.h"
21 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
22 #endif
24 namespace mozilla {
25 namespace widget {
27 class GfxInfo::GLStrings
28 {
29 nsCString mVendor;
30 nsCString mRenderer;
31 nsCString mVersion;
32 bool mReady;
34 public:
35 GLStrings()
36 : mReady(false)
37 {}
39 const nsCString& Vendor() {
40 EnsureInitialized();
41 return mVendor;
42 }
44 void SpoofVendor(const nsCString& s) {
45 EnsureInitialized();
46 mVendor = s;
47 }
49 const nsCString& Renderer() {
50 EnsureInitialized();
51 return mRenderer;
52 }
54 void SpoofRenderer(const nsCString& s) {
55 EnsureInitialized();
56 mRenderer = s;
57 }
59 const nsCString& Version() {
60 EnsureInitialized();
61 return mVersion;
62 }
64 void SpoofVersion(const nsCString& s) {
65 EnsureInitialized();
66 mVersion = s;
67 }
69 void EnsureInitialized() {
70 if (mReady) {
71 return;
72 }
74 nsRefPtr<gl::GLContext> gl = gl::GLContextProvider::CreateOffscreen(
75 gfxIntSize(16, 16),
76 gfx::SurfaceCaps::ForRGB());
78 if (!gl) {
79 // Setting mReady to true here means that we won't retry. Everything will
80 // remain blacklisted forever. Ideally, we would like to update that once
81 // any GLContext is successfully created, like the compositor's GLContext.
82 mReady = true;
83 return;
84 }
86 gl->MakeCurrent();
88 const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR");
89 if (spoofedVendor)
90 mVendor.Assign(spoofedVendor);
91 else
92 mVendor.Assign((const char*)gl->fGetString(LOCAL_GL_VENDOR));
93 const char *spoofedRenderer = PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER");
94 if (spoofedRenderer)
95 mRenderer.Assign(spoofedRenderer);
96 else
97 mRenderer.Assign((const char*)gl->fGetString(LOCAL_GL_RENDERER));
98 const char *spoofedVersion = PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION");
99 if (spoofedVersion)
100 mVersion.Assign(spoofedVersion);
101 else
102 mVersion.Assign((const char*)gl->fGetString(LOCAL_GL_VERSION));
104 mReady = true;
105 }
106 };
108 #ifdef DEBUG
109 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
110 #endif
112 GfxInfo::GfxInfo()
113 : mInitialized(false)
114 , mGLStrings(new GLStrings)
115 {
116 }
118 /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization
119 * has occurred because they depend on it for information. (See bug 591561) */
120 nsresult
121 GfxInfo::GetD2DEnabled(bool *aEnabled)
122 {
123 return NS_ERROR_FAILURE;
124 }
126 nsresult
127 GfxInfo::GetDWriteEnabled(bool *aEnabled)
128 {
129 return NS_ERROR_FAILURE;
130 }
132 /* readonly attribute DOMString DWriteVersion; */
133 NS_IMETHODIMP
134 GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
135 {
136 return NS_ERROR_FAILURE;
137 }
139 /* readonly attribute DOMString cleartypeParameters; */
140 NS_IMETHODIMP
141 GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams)
142 {
143 return NS_ERROR_FAILURE;
144 }
146 void
147 GfxInfo::EnsureInitialized()
148 {
149 if (mInitialized)
150 return;
152 mGLStrings->EnsureInitialized();
154 MOZ_ASSERT(mozilla::AndroidBridge::Bridge());
156 if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MODEL", mModel)) {
157 mAdapterDescription.AppendPrintf("Model: %s", NS_LossyConvertUTF16toASCII(mModel).get());
158 }
160 if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "PRODUCT", mProduct)) {
161 mAdapterDescription.AppendPrintf(", Product: %s", NS_LossyConvertUTF16toASCII(mProduct).get());
162 }
164 if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MANUFACTURER", mManufacturer)) {
165 mAdapterDescription.AppendPrintf(", Manufacturer: %s", NS_LossyConvertUTF16toASCII(mManufacturer).get());
166 }
168 int32_t sdkVersion;
169 if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &sdkVersion))
170 sdkVersion = 0;
172 // the HARDWARE field isn't available on Android SDK < 8
173 if (sdkVersion >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", mHardware)) {
174 mAdapterDescription.AppendPrintf(", Hardware: %s", NS_LossyConvertUTF16toASCII(mHardware).get());
175 }
177 nsString release;
178 mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", release);
179 mOSVersion = NS_LossyConvertUTF16toASCII(release);
181 mOSVersionInteger = 0;
182 char a[5], b[5], c[5], d[5];
183 SplitDriverVersion(mOSVersion.get(), a, b, c, d);
184 uint8_t na = atoi(a);
185 uint8_t nb = atoi(b);
186 uint8_t nc = atoi(c);
187 uint8_t nd = atoi(d);
189 mOSVersionInteger = (uint32_t(na) << 24) |
190 (uint32_t(nb) << 16) |
191 (uint32_t(nc) << 8) |
192 uint32_t(nd);
194 mAdapterDescription.AppendPrintf(", OpenGL: %s -- %s -- %s",
195 mGLStrings->Vendor().get(),
196 mGLStrings->Renderer().get(),
197 mGLStrings->Version().get());
199 AddCrashReportAnnotations();
201 mInitialized = true;
202 }
204 /* readonly attribute DOMString adapterDescription; */
205 NS_IMETHODIMP
206 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
207 {
208 EnsureInitialized();
209 aAdapterDescription = NS_ConvertASCIItoUTF16(mAdapterDescription);
210 return NS_OK;
211 }
213 /* readonly attribute DOMString adapterDescription2; */
214 NS_IMETHODIMP
215 GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
216 {
217 EnsureInitialized();
218 return NS_ERROR_FAILURE;
219 }
221 /* readonly attribute DOMString adapterRAM; */
222 NS_IMETHODIMP
223 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
224 {
225 EnsureInitialized();
226 aAdapterRAM.AssignLiteral("");
227 return NS_OK;
228 }
230 /* readonly attribute DOMString adapterRAM2; */
231 NS_IMETHODIMP
232 GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
233 {
234 EnsureInitialized();
235 return NS_ERROR_FAILURE;
236 }
238 /* readonly attribute DOMString adapterDriver; */
239 NS_IMETHODIMP
240 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
241 {
242 EnsureInitialized();
243 aAdapterDriver.AssignLiteral("");
244 return NS_OK;
245 }
247 /* readonly attribute DOMString adapterDriver2; */
248 NS_IMETHODIMP
249 GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
250 {
251 EnsureInitialized();
252 return NS_ERROR_FAILURE;
253 }
255 /* readonly attribute DOMString adapterDriverVersion; */
256 NS_IMETHODIMP
257 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
258 {
259 EnsureInitialized();
260 aAdapterDriverVersion = NS_ConvertASCIItoUTF16(mGLStrings->Version());
261 return NS_OK;
262 }
264 /* readonly attribute DOMString adapterDriverVersion2; */
265 NS_IMETHODIMP
266 GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
267 {
268 EnsureInitialized();
269 return NS_ERROR_FAILURE;
270 }
272 /* readonly attribute DOMString adapterDriverDate; */
273 NS_IMETHODIMP
274 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
275 {
276 EnsureInitialized();
277 aAdapterDriverDate.AssignLiteral("");
278 return NS_OK;
279 }
281 /* readonly attribute DOMString adapterDriverDate2; */
282 NS_IMETHODIMP
283 GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
284 {
285 EnsureInitialized();
286 return NS_ERROR_FAILURE;
287 }
289 /* readonly attribute DOMString adapterVendorID; */
290 NS_IMETHODIMP
291 GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID)
292 {
293 EnsureInitialized();
294 aAdapterVendorID = NS_ConvertASCIItoUTF16(mGLStrings->Vendor());
295 return NS_OK;
296 }
298 /* readonly attribute DOMString adapterVendorID2; */
299 NS_IMETHODIMP
300 GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID)
301 {
302 EnsureInitialized();
303 return NS_ERROR_FAILURE;
304 }
306 /* readonly attribute DOMString adapterDeviceID; */
307 NS_IMETHODIMP
308 GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID)
309 {
310 EnsureInitialized();
311 aAdapterDeviceID = NS_ConvertASCIItoUTF16(mGLStrings->Renderer());
312 return NS_OK;
313 }
315 /* readonly attribute DOMString adapterDeviceID2; */
316 NS_IMETHODIMP
317 GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID)
318 {
319 EnsureInitialized();
320 return NS_ERROR_FAILURE;
321 }
323 /* readonly attribute boolean isGPU2Active; */
324 NS_IMETHODIMP
325 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active)
326 {
327 EnsureInitialized();
328 return NS_ERROR_FAILURE;
329 }
331 void
332 GfxInfo::AddCrashReportAnnotations()
333 {
334 #if defined(MOZ_CRASHREPORTER)
335 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
336 mGLStrings->Vendor());
337 CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
338 mGLStrings->Renderer());
340 /* Add an App Note for now so that we get the data immediately. These
341 * can go away after we store the above in the socorro db */
342 nsAutoCString note;
343 note.AppendPrintf("AdapterDescription: '%s'\n", mAdapterDescription.get());
345 CrashReporter::AppendAppNotesToCrashReport(note);
346 #endif
347 }
349 const nsTArray<GfxDriverInfo>&
350 GfxInfo::GetGfxDriverInfo()
351 {
352 if (mDriverInfo->IsEmpty()) {
353 APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
354 (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAll), GfxDriverInfo::allDevices,
355 nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_NO_INFO,
356 DRIVER_COMPARISON_IGNORED, GfxDriverInfo::allDriverVersions );
357 }
359 return *mDriverInfo;
360 }
362 nsresult
363 GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
364 int32_t *aStatus,
365 nsAString & aSuggestedDriverVersion,
366 const nsTArray<GfxDriverInfo>& aDriverInfo,
367 OperatingSystem* aOS /* = nullptr */)
368 {
369 NS_ENSURE_ARG_POINTER(aStatus);
370 aSuggestedDriverVersion.SetIsVoid(true);
371 *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
372 OperatingSystem os = mOS;
373 if (aOS)
374 *aOS = os;
376 // OpenGL layers are never blacklisted on Android.
377 // This early return is so we avoid potentially slow
378 // GLStrings initialization on startup when we initialize GL layers.
379 if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS) {
380 *aStatus = nsIGfxInfo::FEATURE_NO_INFO;
381 return NS_OK;
382 }
384 EnsureInitialized();
386 if (mGLStrings->Vendor().IsEmpty() || mGLStrings->Renderer().IsEmpty()) {
387 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
388 return NS_OK;
389 }
391 // Don't evaluate special cases when evaluating the downloaded blocklist.
392 if (aDriverInfo.IsEmpty()) {
393 if (aFeature == FEATURE_WEBGL_OPENGL) {
394 if (mGLStrings->Renderer().Find("Adreno 200") != -1 ||
395 mGLStrings->Renderer().Find("Adreno 205") != -1)
396 {
397 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
398 return NS_OK;
399 }
401 if (mHardware.Equals(NS_LITERAL_STRING("ville"))) {
402 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
403 return NS_OK;
404 }
405 }
407 if (aFeature == FEATURE_STAGEFRIGHT) {
408 NS_LossyConvertUTF16toASCII cManufacturer(mManufacturer);
409 NS_LossyConvertUTF16toASCII cModel(mModel);
410 NS_LossyConvertUTF16toASCII cHardware(mHardware);
412 if (cHardware.Equals("antares") ||
413 cHardware.Equals("harmony") ||
414 cHardware.Equals("picasso") ||
415 cHardware.Equals("picasso_e") ||
416 cHardware.Equals("ventana") ||
417 cHardware.Equals("rk30board"))
418 {
419 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
420 return NS_OK;
421 }
423 if (CompareVersions(mOSVersion.get(), "2.2.0") >= 0 &&
424 CompareVersions(mOSVersion.get(), "2.3.0") < 0)
425 {
426 // Froyo LG devices are whitelisted.
427 // All other Froyo
428 bool isWhitelisted =
429 cManufacturer.Equals("lge", nsCaseInsensitiveCStringComparator());
431 if (!isWhitelisted) {
432 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
433 return NS_OK;
434 }
435 }
436 else if (CompareVersions(mOSVersion.get(), "2.3.0") >= 0 &&
437 CompareVersions(mOSVersion.get(), "2.4.0") < 0)
438 {
439 // Gingerbread HTC devices are whitelisted.
440 // Gingerbread Samsung devices are whitelisted except for:
441 // Samsung devices identified in Bug 847837
442 // Gingerbread Sony devices are whitelisted.
443 // All other Gingerbread devices are blacklisted.
444 bool isWhitelisted =
445 cManufacturer.Equals("htc", nsCaseInsensitiveCStringComparator()) ||
446 (cManufacturer.Find("sony", true) != -1) ||
447 cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator());
449 if (cModel.Equals("GT-I8160", nsCaseInsensitiveCStringComparator()) ||
450 cModel.Equals("GT-I8160L", nsCaseInsensitiveCStringComparator()) ||
451 cModel.Equals("GT-I8530", nsCaseInsensitiveCStringComparator()) ||
452 cModel.Equals("GT-I9070", nsCaseInsensitiveCStringComparator()) ||
453 cModel.Equals("GT-I9070P", nsCaseInsensitiveCStringComparator()) ||
454 cModel.Equals("GT-I8160P", nsCaseInsensitiveCStringComparator()) ||
455 cModel.Equals("GT-S7500", nsCaseInsensitiveCStringComparator()) ||
456 cModel.Equals("GT-S7500T", nsCaseInsensitiveCStringComparator()) ||
457 cModel.Equals("GT-S7500L", nsCaseInsensitiveCStringComparator()) ||
458 cModel.Equals("GT-S6500T", nsCaseInsensitiveCStringComparator()) ||
459 cHardware.Equals("smdkc110", nsCaseInsensitiveCStringComparator()) ||
460 cHardware.Equals("smdkc210", nsCaseInsensitiveCStringComparator()) ||
461 cHardware.Equals("herring", nsCaseInsensitiveCStringComparator()) ||
462 cHardware.Equals("shw-m110s", nsCaseInsensitiveCStringComparator()) ||
463 cHardware.Equals("shw-m180s", nsCaseInsensitiveCStringComparator()) ||
464 cHardware.Equals("n1", nsCaseInsensitiveCStringComparator()) ||
465 cHardware.Equals("latona", nsCaseInsensitiveCStringComparator()) ||
466 cHardware.Equals("aalto", nsCaseInsensitiveCStringComparator()) ||
467 cHardware.Equals("atlas", nsCaseInsensitiveCStringComparator()) ||
468 cHardware.Equals("qcom", nsCaseInsensitiveCStringComparator()))
469 {
470 isWhitelisted = false;
471 }
473 if (!isWhitelisted) {
474 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
475 return NS_OK;
476 }
477 }
478 else if (CompareVersions(mOSVersion.get(), "3.0.0") >= 0 &&
479 CompareVersions(mOSVersion.get(), "4.0.0") < 0)
480 {
481 // Honeycomb Samsung devices are whitelisted.
482 // All other Honeycomb devices are blacklisted.
483 bool isWhitelisted =
484 cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator());
486 if (!isWhitelisted) {
487 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
488 return NS_OK;
489 }
490 }
491 else if (CompareVersions(mOSVersion.get(), "4.0.0") < 0)
492 {
493 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION;
494 return NS_OK;
495 }
496 else if (CompareVersions(mOSVersion.get(), "4.1.0") < 0)
497 {
498 // Whitelist:
499 // All Samsung ICS devices, except for:
500 // Samsung SGH-I717 (Bug 845729)
501 // Samsung SGH-I727 (Bug 845729)
502 // Samsung SGH-I757 (Bug 845729)
503 // All Galaxy nexus ICS devices
504 // Sony Xperia Ion (LT28) ICS devices
505 bool isWhitelisted =
506 cModel.Equals("LT28h", nsCaseInsensitiveCStringComparator()) ||
507 cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator()) ||
508 cModel.Equals("galaxy nexus", nsCaseInsensitiveCStringComparator()); // some Galaxy Nexus have manufacturer=amazon
510 if (cModel.Find("SGH-I717", true) != -1 ||
511 cModel.Find("SGH-I727", true) != -1 ||
512 cModel.Find("SGH-I757", true) != -1)
513 {
514 isWhitelisted = false;
515 }
517 if (!isWhitelisted) {
518 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
519 return NS_OK;
520 }
521 }
522 else if (CompareVersions(mOSVersion.get(), "4.2.0") < 0)
523 {
524 // Whitelist:
525 // All JB phones except for those in blocklist below
526 // Blocklist:
527 // Samsung devices from bug 812881 and 853522.
528 // Motorola XT890 from bug 882342.
529 bool isBlocklisted =
530 cModel.Find("GT-P3100", true) != -1 ||
531 cModel.Find("GT-P3110", true) != -1 ||
532 cModel.Find("GT-P3113", true) != -1 ||
533 cModel.Find("GT-P5100", true) != -1 ||
534 cModel.Find("GT-P5110", true) != -1 ||
535 cModel.Find("GT-P5113", true) != -1 ||
536 cModel.Find("XT890", true) != -1;
538 if (isBlocklisted) {
539 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
540 return NS_OK;
541 }
542 }
543 else if (CompareVersions(mOSVersion.get(), "4.3.0") < 0)
544 {
545 // Blocklist all Sony devices
546 if (cManufacturer.Find("Sony", true) != -1) {
547 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
548 return NS_OK;
549 }
550 }
551 }
553 if (aFeature == FEATURE_WEBRTC_HW_ACCELERATION) {
554 NS_LossyConvertUTF16toASCII cManufacturer(mManufacturer);
555 NS_LossyConvertUTF16toASCII cModel(mModel);
556 NS_LossyConvertUTF16toASCII cHardware(mHardware);
558 if (cHardware.Equals("hammerhead") &&
559 CompareVersions(mOSVersion.get(), "4.4.2") >= 0 &&
560 cManufacturer.Equals("lge", nsCaseInsensitiveCStringComparator()) &&
561 cModel.Equals("nexus 5", nsCaseInsensitiveCStringComparator())) {
562 *aStatus = nsIGfxInfo::FEATURE_NO_INFO;
563 return NS_OK;
564 } else {
565 // Blocklist all other devices except Nexus 5 which VP8 hardware acceleration is supported
566 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
567 return NS_OK;
568 }
569 }
570 }
572 return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os);
573 }
575 #ifdef DEBUG
577 // Implement nsIGfxInfoDebug
579 /* void spoofVendorID (in DOMString aVendorID); */
580 NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID)
581 {
582 EnsureInitialized();
583 mGLStrings->SpoofVendor(NS_LossyConvertUTF16toASCII(aVendorID));
584 return NS_OK;
585 }
587 /* void spoofDeviceID (in unsigned long aDeviceID); */
588 NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID)
589 {
590 EnsureInitialized();
591 mGLStrings->SpoofRenderer(NS_LossyConvertUTF16toASCII(aDeviceID));
592 return NS_OK;
593 }
595 /* void spoofDriverVersion (in DOMString aDriverVersion); */
596 NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion)
597 {
598 EnsureInitialized();
599 mGLStrings->SpoofVersion(NS_LossyConvertUTF16toASCII(aDriverVersion));
600 return NS_OK;
601 }
603 /* void spoofOSVersion (in unsigned long aVersion); */
604 NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion)
605 {
606 EnsureInitialized();
607 mOSVersion = aVersion;
608 return NS_OK;
609 }
611 #endif
613 nsString GfxInfo::Model()
614 {
615 EnsureInitialized();
616 return mModel;
617 }
619 nsString GfxInfo::Hardware()
620 {
621 EnsureInitialized();
622 return mHardware;
623 }
625 nsString GfxInfo::Product()
626 {
627 EnsureInitialized();
628 return mProduct;
629 }
631 nsString GfxInfo::Manufacturer()
632 {
633 EnsureInitialized();
634 return mManufacturer;
635 }
637 uint32_t GfxInfo::OperatingSystemVersion()
638 {
639 EnsureInitialized();
640 return mOSVersionInteger;
641 }
643 }
644 }