1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 ts=2 et tw=78: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 1998
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Travis Bogard <travis@netscape.com>
25 : * Brendan Eich <brendan@mozilla.org>
26 : * David Hyatt (hyatt@netscape.com)
27 : * Dan Rosen <dr@netscape.com>
28 : * Vidur Apparao <vidur@netscape.com>
29 : * Johnny Stenback <jst@netscape.com>
30 : * Mark Hammond <mhammond@skippinet.com.au>
31 : * Ryan Jones <sciguyryan@gmail.com>
32 : * Jeff Walden <jwalden+code@mit.edu>
33 : * Ben Bucksch <ben.bucksch beonex.com>
34 : * Emanuele Costa <emanuele.costa@gmail.com>
35 : *
36 : * Alternatively, the contents of this file may be used under the terms of
37 : * either of the GNU General Public License Version 2 or later (the "GPL"),
38 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
39 : * in which case the provisions of the GPL or the LGPL are applicable instead
40 : * of those above. If you wish to allow use of your version of this file only
41 : * under the terms of either the GPL or the LGPL, and not to allow others to
42 : * use your version of this file under the terms of the MPL, indicate your
43 : * decision by deleting the provisions above and replace them with the notice
44 : * and other provisions required by the GPL or the LGPL. If you do not delete
45 : * the provisions above, a recipient may use your version of this file under
46 : * the terms of any one of the MPL, the GPL or the LGPL.
47 : *
48 : * ***** END LICENSE BLOCK ***** */
49 :
50 : // Needs to be first.
51 : #include "base/basictypes.h"
52 :
53 : #include "Navigator.h"
54 : #include "nsIXULAppInfo.h"
55 : #include "nsPluginArray.h"
56 : #include "nsMimeTypeArray.h"
57 : #include "nsDesktopNotification.h"
58 : #include "nsGeolocation.h"
59 : #include "nsIHttpProtocolHandler.h"
60 : #include "nsICachingChannel.h"
61 : #include "nsIDocShell.h"
62 : #include "nsIWebContentHandlerRegistrar.h"
63 : #include "nsICookiePermission.h"
64 : #include "nsIScriptSecurityManager.h"
65 : #include "nsIJSContextStack.h"
66 : #include "nsCharSeparatedTokenizer.h"
67 : #include "nsContentUtils.h"
68 : #include "nsUnicharUtils.h"
69 : #include "mozilla/Preferences.h"
70 : #include "mozilla/Telemetry.h"
71 : #include "BatteryManager.h"
72 : #include "PowerManager.h"
73 : #include "nsIDOMWakeLock.h"
74 : #include "nsIPowerManagerService.h"
75 : #include "SmsManager.h"
76 : #include "nsISmsService.h"
77 : #include "mozilla/Hal.h"
78 : #include "nsIWebNavigation.h"
79 : #include "mozilla/ClearOnShutdown.h"
80 : #include "Connection.h"
81 :
82 : #ifdef MOZ_B2G_RIL
83 : #include "TelephonyFactory.h"
84 : #endif
85 : #ifdef MOZ_B2G_BT
86 : #include "nsIDOMBluetoothAdapter.h"
87 : #include "BluetoothAdapter.h"
88 : #endif
89 :
90 : // This should not be in the namespace.
91 : DOMCI_DATA(Navigator, mozilla::dom::Navigator)
92 :
93 : namespace mozilla {
94 : namespace dom {
95 :
96 : static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
97 :
98 : static bool sDoNotTrackEnabled = false;
99 : static bool sVibratorEnabled = false;
100 : static PRUint32 sMaxVibrateMS = 0;
101 : static PRUint32 sMaxVibrateListLen = 0;
102 :
103 : /* static */
104 : void
105 1404 : Navigator::Init()
106 : {
107 : Preferences::AddBoolVarCache(&sDoNotTrackEnabled,
108 : "privacy.donottrackheader.enabled",
109 1404 : false);
110 : Preferences::AddBoolVarCache(&sVibratorEnabled,
111 1404 : "dom.vibrator.enabled", true);
112 : Preferences::AddUintVarCache(&sMaxVibrateMS,
113 1404 : "dom.vibrator.max_vibrate_ms", 10000);
114 : Preferences::AddUintVarCache(&sMaxVibrateListLen,
115 1404 : "dom.vibrator.max_vibrate_list_len", 128);
116 1404 : }
117 :
118 0 : Navigator::Navigator(nsPIDOMWindow* aWindow)
119 0 : : mWindow(do_GetWeakReference(aWindow))
120 : {
121 0 : NS_ASSERTION(aWindow->IsInnerWindow(),
122 : "Navigator must get an inner window!");
123 0 : }
124 :
125 0 : Navigator::~Navigator()
126 : {
127 0 : Invalidate();
128 0 : }
129 :
130 0 : NS_INTERFACE_MAP_BEGIN(Navigator)
131 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
132 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
133 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
134 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
135 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorBattery)
136 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification)
137 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorSms)
138 : #ifdef MOZ_B2G_RIL
139 : NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorTelephony)
140 : #endif
141 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorNetwork)
142 : #ifdef MOZ_B2G_BT
143 : NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorBluetooth)
144 : #endif
145 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
146 0 : NS_INTERFACE_MAP_END
147 :
148 0 : NS_IMPL_ADDREF(Navigator)
149 0 : NS_IMPL_RELEASE(Navigator)
150 :
151 : void
152 0 : Navigator::Invalidate()
153 : {
154 0 : mWindow = nsnull;
155 :
156 0 : if (mPlugins) {
157 0 : mPlugins->Invalidate();
158 0 : mPlugins = nsnull;
159 : }
160 :
161 : // If there is a page transition, make sure delete the geolocation object.
162 0 : if (mGeolocation) {
163 0 : mGeolocation->Shutdown();
164 0 : mGeolocation = nsnull;
165 : }
166 :
167 0 : if (mNotification) {
168 0 : mNotification->Shutdown();
169 0 : mNotification = nsnull;
170 : }
171 :
172 0 : if (mBatteryManager) {
173 0 : mBatteryManager->Shutdown();
174 0 : mBatteryManager = nsnull;
175 : }
176 :
177 0 : if (mPowerManager) {
178 0 : mPowerManager->Shutdown();
179 0 : mPowerManager = nsnull;
180 : }
181 :
182 0 : if (mSmsManager) {
183 0 : mSmsManager->Shutdown();
184 0 : mSmsManager = nsnull;
185 : }
186 :
187 : #ifdef MOZ_B2G_RIL
188 : if (mTelephony) {
189 : mTelephony = nsnull;
190 : }
191 : #endif
192 :
193 0 : if (mConnection) {
194 0 : mConnection->Shutdown();
195 0 : mConnection = nsnull;
196 : }
197 :
198 : #ifdef MOZ_B2G_BT
199 : if (mBluetooth) {
200 : mBluetooth = nsnull;
201 : }
202 : #endif
203 0 : }
204 :
205 : nsPIDOMWindow *
206 0 : Navigator::GetWindow()
207 : {
208 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
209 :
210 0 : return win;
211 : }
212 :
213 :
214 : //*****************************************************************************
215 : // Navigator::nsIDOMNavigator
216 : //*****************************************************************************
217 :
218 : NS_IMETHODIMP
219 0 : Navigator::GetUserAgent(nsAString& aUserAgent)
220 : {
221 0 : return NS_GetNavigatorUserAgent(aUserAgent);
222 : }
223 :
224 : NS_IMETHODIMP
225 0 : Navigator::GetAppCodeName(nsAString& aAppCodeName)
226 : {
227 : nsresult rv;
228 :
229 : nsCOMPtr<nsIHttpProtocolHandler>
230 0 : service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
231 0 : NS_ENSURE_SUCCESS(rv, rv);
232 :
233 0 : nsCAutoString appName;
234 0 : rv = service->GetAppName(appName);
235 0 : CopyASCIItoUTF16(appName, aAppCodeName);
236 :
237 0 : return rv;
238 : }
239 :
240 : NS_IMETHODIMP
241 0 : Navigator::GetAppVersion(nsAString& aAppVersion)
242 : {
243 0 : return NS_GetNavigatorAppVersion(aAppVersion);
244 : }
245 :
246 : NS_IMETHODIMP
247 0 : Navigator::GetAppName(nsAString& aAppName)
248 : {
249 0 : return NS_GetNavigatorAppName(aAppName);
250 : }
251 :
252 : /**
253 : * JS property navigator.language, exposed to web content.
254 : * Take first value from Accept-Languages (HTTP header), which is
255 : * the "content language" freely set by the user in the Pref window.
256 : *
257 : * Do not use UI language (chosen app locale) here.
258 : * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers"
259 : *
260 : * "en", "en-US" and "i-cherokee" and "" are valid.
261 : * Fallback in case of invalid pref should be "" (empty string), to
262 : * let site do fallback, e.g. to site's local language.
263 : */
264 : NS_IMETHODIMP
265 0 : Navigator::GetLanguage(nsAString& aLanguage)
266 : {
267 : // E.g. "de-de, en-us,en".
268 : const nsAdoptingString& acceptLang =
269 0 : Preferences::GetLocalizedString("intl.accept_languages");
270 :
271 : // Take everything before the first "," or ";", without trailing space.
272 0 : nsCharSeparatedTokenizer langTokenizer(acceptLang, ',');
273 0 : const nsSubstring &firstLangPart = langTokenizer.nextToken();
274 0 : nsCharSeparatedTokenizer qTokenizer(firstLangPart, ';');
275 0 : aLanguage.Assign(qTokenizer.nextToken());
276 :
277 : // Checks and fixups:
278 : // replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
279 0 : if (aLanguage.Length() > 2 && aLanguage[2] == PRUnichar('_')) {
280 0 : aLanguage.Replace(2, 1, PRUnichar('-')); // TODO replace all
281 : }
282 :
283 : // Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
284 : // only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe".
285 0 : if (aLanguage.Length() <= 2) {
286 0 : return NS_OK;
287 : }
288 :
289 0 : nsCharSeparatedTokenizer localeTokenizer(aLanguage, '-');
290 0 : PRInt32 pos = 0;
291 0 : bool first = true;
292 0 : while (localeTokenizer.hasMoreTokens()) {
293 0 : const nsSubstring& code = localeTokenizer.nextToken();
294 :
295 0 : if (code.Length() == 2 && !first) {
296 0 : nsAutoString upper(code);
297 0 : ToUpperCase(upper);
298 0 : aLanguage.Replace(pos, code.Length(), upper);
299 : }
300 :
301 0 : pos += code.Length() + 1; // 1 is the separator
302 0 : first = false;
303 : }
304 :
305 0 : return NS_OK;
306 : }
307 :
308 : NS_IMETHODIMP
309 0 : Navigator::GetPlatform(nsAString& aPlatform)
310 : {
311 0 : return NS_GetNavigatorPlatform(aPlatform);
312 : }
313 :
314 : NS_IMETHODIMP
315 0 : Navigator::GetOscpu(nsAString& aOSCPU)
316 : {
317 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
318 : const nsAdoptingString& override =
319 0 : Preferences::GetString("general.oscpu.override");
320 :
321 0 : if (override) {
322 0 : aOSCPU = override;
323 0 : return NS_OK;
324 : }
325 : }
326 :
327 : nsresult rv;
328 :
329 : nsCOMPtr<nsIHttpProtocolHandler>
330 0 : service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
331 0 : NS_ENSURE_SUCCESS(rv, rv);
332 :
333 0 : nsCAutoString oscpu;
334 0 : rv = service->GetOscpu(oscpu);
335 0 : CopyASCIItoUTF16(oscpu, aOSCPU);
336 :
337 0 : return rv;
338 : }
339 :
340 : NS_IMETHODIMP
341 0 : Navigator::GetVendor(nsAString& aVendor)
342 : {
343 0 : aVendor.Truncate();
344 0 : return NS_OK;
345 : }
346 :
347 : NS_IMETHODIMP
348 0 : Navigator::GetVendorSub(nsAString& aVendorSub)
349 : {
350 0 : aVendorSub.Truncate();
351 0 : return NS_OK;
352 : }
353 :
354 : NS_IMETHODIMP
355 0 : Navigator::GetProduct(nsAString& aProduct)
356 : {
357 : nsresult rv;
358 :
359 : nsCOMPtr<nsIHttpProtocolHandler>
360 0 : service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
361 0 : NS_ENSURE_SUCCESS(rv, rv);
362 :
363 0 : nsCAutoString product;
364 0 : rv = service->GetProduct(product);
365 0 : CopyASCIItoUTF16(product, aProduct);
366 :
367 0 : return rv;
368 : }
369 :
370 : NS_IMETHODIMP
371 0 : Navigator::GetProductSub(nsAString& aProductSub)
372 : {
373 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
374 : const nsAdoptingString& override =
375 0 : Preferences::GetString("general.productSub.override");
376 :
377 0 : if (override) {
378 0 : aProductSub = override;
379 0 : return NS_OK;
380 : }
381 :
382 : // 'general.useragent.productSub' backwards compatible with 1.8 branch.
383 : const nsAdoptingString& override2 =
384 0 : Preferences::GetString("general.useragent.productSub");
385 :
386 0 : if (override2) {
387 0 : aProductSub = override2;
388 0 : return NS_OK;
389 : }
390 : }
391 :
392 : nsresult rv;
393 :
394 : nsCOMPtr<nsIHttpProtocolHandler>
395 0 : service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
396 0 : NS_ENSURE_SUCCESS(rv, rv);
397 :
398 0 : nsCAutoString productSub;
399 0 : rv = service->GetProductSub(productSub);
400 0 : CopyASCIItoUTF16(productSub, aProductSub);
401 :
402 0 : return rv;
403 : }
404 :
405 : NS_IMETHODIMP
406 0 : Navigator::GetMimeTypes(nsIDOMMimeTypeArray** aMimeTypes)
407 : {
408 0 : if (!mMimeTypes) {
409 0 : mMimeTypes = new nsMimeTypeArray(this);
410 : }
411 :
412 0 : NS_ADDREF(*aMimeTypes = mMimeTypes);
413 :
414 0 : return NS_OK;
415 : }
416 :
417 : NS_IMETHODIMP
418 0 : Navigator::GetPlugins(nsIDOMPluginArray** aPlugins)
419 : {
420 0 : if (!mPlugins) {
421 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
422 :
423 0 : mPlugins = new nsPluginArray(this, win ? win->GetDocShell() : nsnull);
424 : }
425 :
426 0 : NS_ADDREF(*aPlugins = mPlugins);
427 :
428 0 : return NS_OK;
429 : }
430 :
431 : // Values for the network.cookie.cookieBehavior pref are documented in
432 : // nsCookieService.cpp.
433 : #define COOKIE_BEHAVIOR_REJECT 2
434 :
435 : NS_IMETHODIMP
436 0 : Navigator::GetCookieEnabled(bool* aCookieEnabled)
437 : {
438 : *aCookieEnabled =
439 : (Preferences::GetInt("network.cookie.cookieBehavior",
440 0 : COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT);
441 :
442 : // Check whether an exception overrides the global cookie behavior
443 : // Note that the code for getting the URI here matches that in
444 : // nsHTMLDocument::SetCookie.
445 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
446 :
447 0 : if (!win || !win->GetDocShell()) {
448 0 : return NS_OK;
449 : }
450 :
451 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
452 0 : if (!doc) {
453 0 : return NS_OK;
454 : }
455 :
456 0 : nsCOMPtr<nsIURI> codebaseURI;
457 0 : doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
458 :
459 0 : if (!codebaseURI) {
460 : // Not a codebase, so technically can't set cookies, but let's
461 : // just return the default value.
462 0 : return NS_OK;
463 : }
464 :
465 : nsCOMPtr<nsICookiePermission> permMgr =
466 0 : do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
467 0 : NS_ENSURE_TRUE(permMgr, NS_OK);
468 :
469 : // Pass null for the channel, just like the cookie service does.
470 : nsCookieAccess access;
471 0 : nsresult rv = permMgr->CanAccess(codebaseURI, nsnull, &access);
472 0 : NS_ENSURE_SUCCESS(rv, NS_OK);
473 :
474 0 : if (access != nsICookiePermission::ACCESS_DEFAULT) {
475 0 : *aCookieEnabled = access != nsICookiePermission::ACCESS_DENY;
476 : }
477 :
478 0 : return NS_OK;
479 : }
480 :
481 : NS_IMETHODIMP
482 0 : Navigator::GetOnLine(bool* aOnline)
483 : {
484 0 : NS_PRECONDITION(aOnline, "Null out param");
485 :
486 0 : *aOnline = !NS_IsOffline();
487 0 : return NS_OK;
488 : }
489 :
490 : NS_IMETHODIMP
491 0 : Navigator::GetBuildID(nsAString& aBuildID)
492 : {
493 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
494 : const nsAdoptingString& override =
495 0 : Preferences::GetString("general.buildID.override");
496 :
497 0 : if (override) {
498 0 : aBuildID = override;
499 0 : return NS_OK;
500 : }
501 : }
502 :
503 : nsCOMPtr<nsIXULAppInfo> appInfo =
504 0 : do_GetService("@mozilla.org/xre/app-info;1");
505 0 : if (!appInfo) {
506 0 : return NS_ERROR_NOT_IMPLEMENTED;
507 : }
508 :
509 0 : nsCAutoString buildID;
510 0 : nsresult rv = appInfo->GetAppBuildID(buildID);
511 0 : if (NS_FAILED(rv)) {
512 0 : return rv;
513 : }
514 :
515 0 : aBuildID.Truncate();
516 0 : AppendASCIItoUTF16(buildID, aBuildID);
517 0 : return NS_OK;
518 : }
519 :
520 : NS_IMETHODIMP
521 0 : Navigator::GetDoNotTrack(nsAString &aResult)
522 : {
523 0 : if (sDoNotTrackEnabled) {
524 0 : aResult.AssignLiteral("yes");
525 : } else {
526 0 : aResult.AssignLiteral("unspecified");
527 : }
528 :
529 0 : return NS_OK;
530 : }
531 :
532 : NS_IMETHODIMP
533 0 : Navigator::JavaEnabled(bool* aReturn)
534 : {
535 0 : Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
536 : // Return true if we have a handler for "application/x-java-vm",
537 : // otherwise return false.
538 0 : *aReturn = false;
539 :
540 0 : if (!mMimeTypes) {
541 0 : mMimeTypes = new nsMimeTypeArray(this);
542 : }
543 :
544 0 : RefreshMIMEArray();
545 :
546 : PRUint32 count;
547 0 : mMimeTypes->GetLength(&count);
548 0 : for (PRUint32 i = 0; i < count; i++) {
549 : nsresult rv;
550 0 : nsIDOMMimeType* type = mMimeTypes->GetItemAt(i, &rv);
551 :
552 0 : if (NS_FAILED(rv) || !type) {
553 0 : continue;
554 : }
555 :
556 0 : nsAutoString mimeString;
557 0 : if (NS_FAILED(type->GetType(mimeString))) {
558 0 : continue;
559 : }
560 :
561 0 : if (mimeString.EqualsLiteral("application/x-java-vm")) {
562 0 : *aReturn = true;
563 : break;
564 : }
565 : }
566 :
567 0 : return NS_OK;
568 : }
569 :
570 : NS_IMETHODIMP
571 0 : Navigator::TaintEnabled(bool *aReturn)
572 : {
573 0 : *aReturn = false;
574 0 : return NS_OK;
575 : }
576 :
577 : void
578 0 : Navigator::RefreshMIMEArray()
579 : {
580 0 : if (mMimeTypes) {
581 0 : mMimeTypes->Refresh();
582 : }
583 0 : }
584 :
585 : bool
586 306 : Navigator::HasDesktopNotificationSupport()
587 : {
588 306 : return Preferences::GetBool("notification.feature.enabled", false);
589 : }
590 :
591 : namespace {
592 :
593 : class VibrateWindowListener : public nsIDOMEventListener
594 : {
595 : public:
596 0 : VibrateWindowListener(nsIDOMWindow *aWindow, nsIDOMDocument *aDocument)
597 0 : {
598 0 : mWindow = do_GetWeakReference(aWindow);
599 0 : mDocument = do_GetWeakReference(aDocument);
600 :
601 0 : nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(aDocument);
602 0 : NS_NAMED_LITERAL_STRING(visibilitychange, "mozvisibilitychange");
603 : target->AddSystemEventListener(visibilitychange,
604 : this, /* listener */
605 : true, /* use capture */
606 0 : false /* wants untrusted */);
607 0 : }
608 :
609 0 : virtual ~VibrateWindowListener()
610 0 : {
611 0 : }
612 :
613 : void RemoveListener();
614 :
615 : NS_DECL_ISUPPORTS
616 : NS_DECL_NSIDOMEVENTLISTENER
617 :
618 : private:
619 : nsWeakPtr mWindow;
620 : nsWeakPtr mDocument;
621 : };
622 :
623 0 : NS_IMPL_ISUPPORTS1(VibrateWindowListener, nsIDOMEventListener)
624 :
625 1464 : nsRefPtr<VibrateWindowListener> gVibrateWindowListener;
626 :
627 : NS_IMETHODIMP
628 0 : VibrateWindowListener::HandleEvent(nsIDOMEvent* aEvent)
629 : {
630 0 : nsCOMPtr<nsIDOMEventTarget> target;
631 0 : aEvent->GetTarget(getter_AddRefs(target));
632 0 : nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(target);
633 :
634 0 : bool hidden = true;
635 0 : if (doc) {
636 0 : doc->GetMozHidden(&hidden);
637 : }
638 :
639 0 : if (hidden) {
640 : // It's important that we call CancelVibrate(), not Vibrate() with an
641 : // empty list, because Vibrate() will fail if we're no longer focused, but
642 : // CancelVibrate() will succeed, so long as nobody else has started a new
643 : // vibration pattern.
644 0 : nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
645 0 : hal::CancelVibrate(window);
646 0 : RemoveListener();
647 0 : gVibrateWindowListener = NULL;
648 : // Careful: The line above might have deleted |this|!
649 : }
650 :
651 0 : return NS_OK;
652 : }
653 :
654 : void
655 0 : VibrateWindowListener::RemoveListener()
656 : {
657 0 : nsCOMPtr<nsIDOMEventTarget> target = do_QueryReferent(mDocument);
658 0 : if (!target) {
659 : return;
660 : }
661 0 : NS_NAMED_LITERAL_STRING(visibilitychange, "mozvisibilitychange");
662 0 : target->RemoveSystemEventListener(visibilitychange, this,
663 0 : true /* use capture */);
664 : }
665 :
666 : /**
667 : * Converts a jsval into a vibration duration, checking that the duration is in
668 : * bounds (non-negative and not larger than sMaxVibrateMS).
669 : *
670 : * Returns true on success, false on failure.
671 : */
672 : bool
673 0 : GetVibrationDurationFromJsval(const jsval& aJSVal, JSContext* cx,
674 : PRInt32 *aOut)
675 : {
676 0 : return JS_ValueToInt32(cx, aJSVal, aOut) &&
677 0 : *aOut >= 0 && static_cast<PRUint32>(*aOut) <= sMaxVibrateMS;
678 : }
679 :
680 : } // anonymous namespace
681 :
682 : NS_IMETHODIMP
683 0 : Navigator::MozVibrate(const jsval& aPattern, JSContext* cx)
684 : {
685 0 : nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
686 0 : NS_ENSURE_TRUE(win, NS_OK);
687 :
688 0 : nsIDOMDocument* domDoc = win->GetExtantDocument();
689 0 : NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
690 :
691 0 : bool hidden = true;
692 0 : domDoc->GetMozHidden(&hidden);
693 0 : if (hidden) {
694 : // Hidden documents cannot start or stop a vibration.
695 0 : return NS_OK;
696 : }
697 :
698 0 : nsAutoTArray<PRUint32, 8> pattern;
699 :
700 : // null or undefined pattern is an error.
701 0 : if (JSVAL_IS_NULL(aPattern) || JSVAL_IS_VOID(aPattern)) {
702 0 : return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
703 : }
704 :
705 0 : if (JSVAL_IS_PRIMITIVE(aPattern)) {
706 : PRInt32 p;
707 0 : if (GetVibrationDurationFromJsval(aPattern, cx, &p)) {
708 0 : pattern.AppendElement(p);
709 : }
710 : else {
711 0 : return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
712 : }
713 : }
714 : else {
715 0 : JSObject *obj = JSVAL_TO_OBJECT(aPattern);
716 : PRUint32 length;
717 0 : if (!JS_GetArrayLength(cx, obj, &length) || length > sMaxVibrateListLen) {
718 0 : return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
719 : }
720 0 : pattern.SetLength(length);
721 :
722 0 : for (PRUint32 i = 0; i < length; ++i) {
723 : jsval v;
724 : PRInt32 pv;
725 0 : if (JS_GetElement(cx, obj, i, &v) &&
726 0 : GetVibrationDurationFromJsval(v, cx, &pv)) {
727 0 : pattern[i] = pv;
728 : }
729 : else {
730 0 : return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
731 : }
732 : }
733 : }
734 :
735 : // The spec says we check sVibratorEnabled after we've done the sanity
736 : // checking on the pattern.
737 0 : if (!sVibratorEnabled) {
738 0 : return NS_OK;
739 : }
740 :
741 : // Add a listener to cancel the vibration if the document becomes hidden,
742 : // and remove the old mozvisibility listener, if there was one.
743 :
744 0 : if (!gVibrateWindowListener) {
745 : // If gVibrateWindowListener is null, this is the first time we've vibrated,
746 : // and we need to register a listener to clear gVibrateWindowListener on
747 : // shutdown.
748 0 : ClearOnShutdown(&gVibrateWindowListener);
749 : }
750 : else {
751 0 : gVibrateWindowListener->RemoveListener();
752 : }
753 0 : gVibrateWindowListener = new VibrateWindowListener(win, domDoc);
754 :
755 : nsCOMPtr<nsIDOMWindow> domWindow =
756 0 : do_QueryInterface(static_cast<nsIDOMWindow*>(win));
757 0 : hal::Vibrate(pattern, domWindow);
758 0 : return NS_OK;
759 : }
760 :
761 : //*****************************************************************************
762 : // Navigator::nsIDOMClientInformation
763 : //*****************************************************************************
764 :
765 : NS_IMETHODIMP
766 0 : Navigator::RegisterContentHandler(const nsAString& aMIMEType,
767 : const nsAString& aURI,
768 : const nsAString& aTitle)
769 : {
770 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
771 :
772 0 : if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
773 0 : return NS_OK;
774 : }
775 :
776 : nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
777 0 : do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
778 0 : if (!registrar) {
779 0 : return NS_OK;
780 : }
781 :
782 0 : return registrar->RegisterContentHandler(aMIMEType, aURI, aTitle,
783 0 : win->GetOuterWindow());
784 : }
785 :
786 : NS_IMETHODIMP
787 0 : Navigator::RegisterProtocolHandler(const nsAString& aProtocol,
788 : const nsAString& aURI,
789 : const nsAString& aTitle)
790 : {
791 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
792 :
793 0 : if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
794 0 : return NS_OK;
795 : }
796 :
797 : nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
798 0 : do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
799 0 : if (!registrar) {
800 0 : return NS_OK;
801 : }
802 :
803 0 : return registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle,
804 0 : win->GetOuterWindow());
805 : }
806 :
807 : NS_IMETHODIMP
808 0 : Navigator::MozIsLocallyAvailable(const nsAString &aURI,
809 : bool aWhenOffline,
810 : bool* aIsAvailable)
811 : {
812 0 : nsCOMPtr<nsIURI> uri;
813 0 : nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI);
814 0 : NS_ENSURE_SUCCESS(rv, rv);
815 :
816 : // This method of checking the cache will only work for http/https urls.
817 : bool match;
818 0 : rv = uri->SchemeIs("http", &match);
819 0 : NS_ENSURE_SUCCESS(rv, rv);
820 :
821 0 : if (!match) {
822 0 : rv = uri->SchemeIs("https", &match);
823 0 : NS_ENSURE_SUCCESS(rv, rv);
824 0 : if (!match) {
825 0 : return NS_ERROR_DOM_BAD_URI;
826 : }
827 : }
828 :
829 : // Same origin check.
830 0 : nsCOMPtr<nsIJSContextStack> stack = do_GetService(sJSStackContractID);
831 0 : NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE);
832 :
833 0 : JSContext* cx = nsnull;
834 0 : rv = stack->Peek(&cx);
835 0 : NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
836 :
837 0 : rv = nsContentUtils::GetSecurityManager()->CheckSameOrigin(cx, uri);
838 0 : NS_ENSURE_SUCCESS(rv, rv);
839 :
840 : // These load flags cause an error to be thrown if there is no
841 : // valid cache entry, and skip the load if there is.
842 : // If the cache is busy, assume that it is not yet available rather
843 : // than waiting for it to become available.
844 : PRUint32 loadFlags = nsIChannel::INHIBIT_CACHING |
845 : nsICachingChannel::LOAD_NO_NETWORK_IO |
846 : nsICachingChannel::LOAD_ONLY_IF_MODIFIED |
847 0 : nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
848 :
849 0 : if (aWhenOffline) {
850 : loadFlags |= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE |
851 : nsICachingChannel::LOAD_ONLY_FROM_CACHE |
852 0 : nsIRequest::LOAD_FROM_CACHE;
853 : }
854 :
855 0 : nsCOMPtr<nsIChannel> channel;
856 0 : rv = NS_NewChannel(getter_AddRefs(channel), uri,
857 0 : nsnull, nsnull, nsnull, loadFlags);
858 0 : NS_ENSURE_SUCCESS(rv, rv);
859 :
860 0 : nsCOMPtr<nsIInputStream> stream;
861 0 : rv = channel->Open(getter_AddRefs(stream));
862 0 : NS_ENSURE_SUCCESS(rv, rv);
863 :
864 0 : stream->Close();
865 :
866 : nsresult status;
867 0 : rv = channel->GetStatus(&status);
868 0 : NS_ENSURE_SUCCESS(rv, rv);
869 :
870 0 : if (NS_FAILED(status)) {
871 0 : *aIsAvailable = false;
872 0 : return NS_OK;
873 : }
874 :
875 0 : nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
876 0 : return httpChannel->GetRequestSucceeded(aIsAvailable);
877 : }
878 :
879 : //*****************************************************************************
880 : // Navigator::nsIDOMNavigatorGeolocation
881 : //*****************************************************************************
882 :
883 0 : NS_IMETHODIMP Navigator::GetGeolocation(nsIDOMGeoGeolocation** _retval)
884 : {
885 0 : NS_ENSURE_ARG_POINTER(_retval);
886 0 : *_retval = nsnull;
887 :
888 0 : if (!Preferences::GetBool("geo.enabled", true)) {
889 0 : return NS_OK;
890 : }
891 :
892 0 : if (mGeolocation) {
893 0 : NS_ADDREF(*_retval = mGeolocation);
894 0 : return NS_OK;
895 : }
896 :
897 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
898 :
899 0 : if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
900 0 : return NS_ERROR_FAILURE;
901 : }
902 :
903 0 : mGeolocation = new nsGeolocation();
904 0 : if (!mGeolocation) {
905 0 : return NS_ERROR_FAILURE;
906 : }
907 :
908 0 : if (NS_FAILED(mGeolocation->Init(win->GetOuterWindow()))) {
909 0 : mGeolocation = nsnull;
910 0 : return NS_ERROR_FAILURE;
911 : }
912 :
913 0 : NS_ADDREF(*_retval = mGeolocation);
914 0 : return NS_OK;
915 : }
916 :
917 : //*****************************************************************************
918 : // Navigator::nsIDOMNavigatorDesktopNotification
919 : //*****************************************************************************
920 :
921 0 : NS_IMETHODIMP Navigator::GetMozNotification(nsIDOMDesktopNotificationCenter** aRetVal)
922 : {
923 0 : NS_ENSURE_ARG_POINTER(aRetVal);
924 0 : *aRetVal = nsnull;
925 :
926 0 : if (mNotification) {
927 0 : NS_ADDREF(*aRetVal = mNotification);
928 0 : return NS_OK;
929 : }
930 :
931 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
932 0 : NS_ENSURE_TRUE(win && win->GetDocShell(), NS_ERROR_FAILURE);
933 :
934 0 : mNotification = new nsDesktopNotificationCenter(win);
935 :
936 0 : NS_ADDREF(*aRetVal = mNotification);
937 0 : return NS_OK;
938 : }
939 :
940 : //*****************************************************************************
941 : // Navigator::nsIDOMNavigatorBattery
942 : //*****************************************************************************
943 :
944 : NS_IMETHODIMP
945 0 : Navigator::GetMozBattery(nsIDOMMozBatteryManager** aBattery)
946 : {
947 0 : if (!mBatteryManager) {
948 0 : *aBattery = nsnull;
949 :
950 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
951 0 : NS_ENSURE_TRUE(win->GetDocShell(), NS_OK);
952 :
953 0 : mBatteryManager = new battery::BatteryManager();
954 0 : mBatteryManager->Init(win);
955 : }
956 :
957 0 : NS_ADDREF(*aBattery = mBatteryManager);
958 :
959 0 : return NS_OK;
960 : }
961 :
962 : NS_IMETHODIMP
963 0 : Navigator::GetMozPower(nsIDOMMozPowerManager** aPower)
964 : {
965 0 : *aPower = nsnull;
966 :
967 0 : if (!mPowerManager) {
968 0 : nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
969 0 : NS_ENSURE_TRUE(win, NS_OK);
970 :
971 0 : mPowerManager = new power::PowerManager();
972 0 : mPowerManager->Init(win);
973 : }
974 :
975 : nsCOMPtr<nsIDOMMozPowerManager> power =
976 0 : do_QueryInterface(NS_ISUPPORTS_CAST(nsIDOMMozPowerManager*, mPowerManager));
977 0 : power.forget(aPower);
978 :
979 0 : return NS_OK;
980 : }
981 :
982 : NS_IMETHODIMP
983 0 : Navigator::RequestWakeLock(const nsAString &aTopic, nsIDOMMozWakeLock **aWakeLock)
984 : {
985 0 : *aWakeLock = nsnull;
986 :
987 0 : nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
988 0 : NS_ENSURE_TRUE(win, NS_OK);
989 :
990 : nsCOMPtr<nsIPowerManagerService> pmService =
991 0 : do_GetService(POWERMANAGERSERVICE_CONTRACTID);
992 0 : NS_ENSURE_TRUE(pmService, NS_OK);
993 :
994 0 : return pmService->NewWakeLock(aTopic, win, aWakeLock);
995 : }
996 :
997 : //*****************************************************************************
998 : // Navigator::nsIDOMNavigatorSms
999 : //*****************************************************************************
1000 :
1001 : bool
1002 0 : Navigator::IsSmsAllowed() const
1003 : {
1004 : static const bool defaultSmsPermission = false;
1005 :
1006 : // First of all, the general pref has to be turned on.
1007 0 : if (!Preferences::GetBool("dom.sms.enabled", defaultSmsPermission)) {
1008 0 : return false;
1009 : }
1010 :
1011 : // In addition of having 'dom.sms.enabled' set to true, we require the
1012 : // website to be whitelisted. This is a temporary 'security model'.
1013 : // 'dom.sms.whitelist' has to contain comma-separated values of URI prepath.
1014 : // For local files, "file://" must be listed.
1015 : // For data-urls: "moz-nullprincipal:".
1016 : // Chrome files also have to be whitelisted for the moment.
1017 0 : nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
1018 :
1019 0 : if (!win || !win->GetDocShell()) {
1020 0 : return defaultSmsPermission;
1021 : }
1022 :
1023 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
1024 0 : if (!doc) {
1025 0 : return defaultSmsPermission;
1026 : }
1027 :
1028 0 : nsCOMPtr<nsIURI> uri;
1029 0 : doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
1030 :
1031 0 : if (!uri) {
1032 0 : return defaultSmsPermission;
1033 : }
1034 :
1035 0 : nsCAutoString uriPrePath;
1036 0 : uri->GetPrePath(uriPrePath);
1037 :
1038 : const nsAdoptingString& whitelist =
1039 0 : Preferences::GetString("dom.sms.whitelist");
1040 :
1041 : nsCharSeparatedTokenizer tokenizer(whitelist, ',',
1042 0 : nsCharSeparatedTokenizerTemplate<>::SEPARATOR_OPTIONAL);
1043 :
1044 0 : while (tokenizer.hasMoreTokens()) {
1045 0 : const nsSubstring& whitelistItem = tokenizer.nextToken();
1046 :
1047 0 : if (NS_ConvertUTF16toUTF8(whitelistItem).Equals(uriPrePath)) {
1048 0 : return true;
1049 : }
1050 : }
1051 :
1052 : // The current page hasn't been whitelisted.
1053 0 : return false;
1054 : }
1055 :
1056 : bool
1057 0 : Navigator::IsSmsSupported() const
1058 : {
1059 : #ifdef MOZ_WEBSMS_BACKEND
1060 : nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
1061 : NS_ENSURE_TRUE(smsService, false);
1062 :
1063 : bool result = false;
1064 : smsService->HasSupport(&result);
1065 :
1066 : return result;
1067 : #else
1068 0 : return false;
1069 : #endif
1070 : }
1071 :
1072 : NS_IMETHODIMP
1073 0 : Navigator::GetMozSms(nsIDOMMozSmsManager** aSmsManager)
1074 : {
1075 0 : *aSmsManager = nsnull;
1076 :
1077 0 : if (!mSmsManager) {
1078 0 : if (!IsSmsSupported() || !IsSmsAllowed()) {
1079 0 : return NS_OK;
1080 : }
1081 :
1082 0 : nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1083 0 : NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
1084 :
1085 0 : mSmsManager = new sms::SmsManager();
1086 0 : mSmsManager->Init(window);
1087 : }
1088 :
1089 0 : NS_ADDREF(*aSmsManager = mSmsManager);
1090 :
1091 0 : return NS_OK;
1092 : }
1093 :
1094 : #ifdef MOZ_B2G_RIL
1095 :
1096 : //*****************************************************************************
1097 : // nsNavigator::nsIDOMNavigatorTelephony
1098 : //*****************************************************************************
1099 :
1100 : NS_IMETHODIMP
1101 : Navigator::GetMozTelephony(nsIDOMTelephony** aTelephony)
1102 : {
1103 : nsCOMPtr<nsIDOMTelephony> telephony = mTelephony;
1104 :
1105 : if (!telephony) {
1106 : nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1107 : NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1108 :
1109 : nsresult rv = NS_NewTelephony(window, getter_AddRefs(mTelephony));
1110 : NS_ENSURE_SUCCESS(rv, rv);
1111 :
1112 : // mTelephony may be null here!
1113 : telephony = mTelephony;
1114 : }
1115 :
1116 : telephony.forget(aTelephony);
1117 : return NS_OK;
1118 : }
1119 :
1120 : #endif // MOZ_B2G_RIL
1121 :
1122 : //*****************************************************************************
1123 : // Navigator::nsIDOMNavigatorNetwork
1124 : //*****************************************************************************
1125 :
1126 : NS_IMETHODIMP
1127 0 : Navigator::GetMozConnection(nsIDOMMozConnection** aConnection)
1128 : {
1129 0 : *aConnection = nsnull;
1130 :
1131 0 : if (!mConnection) {
1132 0 : nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1133 0 : NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
1134 :
1135 0 : mConnection = new network::Connection();
1136 0 : mConnection->Init(window);
1137 : }
1138 :
1139 0 : NS_ADDREF(*aConnection = mConnection);
1140 0 : return NS_OK;
1141 : }
1142 :
1143 : #ifdef MOZ_B2G_BT
1144 : //*****************************************************************************
1145 : // nsNavigator::nsIDOMNavigatorBluetooth
1146 : //*****************************************************************************
1147 :
1148 : NS_IMETHODIMP
1149 : Navigator::GetMozBluetooth(nsIDOMBluetoothAdapter** aBluetooth)
1150 : {
1151 : nsCOMPtr<nsIDOMBluetoothAdapter> bluetooth = mBluetooth;
1152 :
1153 : if (!bluetooth) {
1154 : nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1155 : NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1156 :
1157 : mBluetooth = new bluetooth::BluetoothAdapter();
1158 :
1159 : bluetooth = mBluetooth;
1160 : }
1161 :
1162 : bluetooth.forget(aBluetooth);
1163 : return NS_OK;
1164 : }
1165 : #endif //MOZ_B2G_BT
1166 :
1167 : size_t
1168 0 : Navigator::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1169 : {
1170 0 : size_t n = aMallocSizeOf(this);
1171 :
1172 : // TODO: add SizeOfIncludingThis() to nsMimeTypeArray, bug 674113.
1173 : // TODO: add SizeOfIncludingThis() to nsPluginArray, bug 674114.
1174 : // TODO: add SizeOfIncludingThis() to nsGeolocation, bug 674115.
1175 : // TODO: add SizeOfIncludingThis() to nsDesktopNotificationCenter, bug 674116.
1176 :
1177 0 : return n;
1178 : }
1179 :
1180 : void
1181 0 : Navigator::SetWindow(nsPIDOMWindow *aInnerWindow)
1182 : {
1183 0 : NS_ASSERTION(aInnerWindow->IsInnerWindow(),
1184 : "Navigator must get an inner window!");
1185 0 : mWindow = do_GetWeakReference(aInnerWindow);
1186 0 : }
1187 :
1188 : } // namespace dom
1189 : } // namespace mozilla
1190 :
1191 : nsresult
1192 0 : NS_GetNavigatorUserAgent(nsAString& aUserAgent)
1193 : {
1194 : nsresult rv;
1195 :
1196 : nsCOMPtr<nsIHttpProtocolHandler>
1197 0 : service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
1198 0 : NS_ENSURE_SUCCESS(rv, rv);
1199 :
1200 0 : nsCAutoString ua;
1201 0 : rv = service->GetUserAgent(ua);
1202 0 : CopyASCIItoUTF16(ua, aUserAgent);
1203 :
1204 0 : return rv;
1205 : }
1206 :
1207 : nsresult
1208 0 : NS_GetNavigatorPlatform(nsAString& aPlatform)
1209 : {
1210 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
1211 : const nsAdoptingString& override =
1212 0 : mozilla::Preferences::GetString("general.platform.override");
1213 :
1214 0 : if (override) {
1215 0 : aPlatform = override;
1216 0 : return NS_OK;
1217 : }
1218 : }
1219 :
1220 : nsresult rv;
1221 :
1222 : nsCOMPtr<nsIHttpProtocolHandler>
1223 0 : service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
1224 0 : NS_ENSURE_SUCCESS(rv, rv);
1225 :
1226 : // Sorry for the #if platform ugliness, but Communicator is likewise
1227 : // hardcoded and we are seeking backward compatibility here (bug 47080).
1228 : #if defined(_WIN64)
1229 : aPlatform.AssignLiteral("Win64");
1230 : #elif defined(WIN32)
1231 : aPlatform.AssignLiteral("Win32");
1232 : #elif defined(XP_MACOSX) && defined(__ppc__)
1233 : aPlatform.AssignLiteral("MacPPC");
1234 : #elif defined(XP_MACOSX) && defined(__i386__)
1235 : aPlatform.AssignLiteral("MacIntel");
1236 : #elif defined(XP_MACOSX) && defined(__x86_64__)
1237 : aPlatform.AssignLiteral("MacIntel");
1238 : #elif defined(XP_OS2)
1239 : aPlatform.AssignLiteral("OS/2");
1240 : #else
1241 : // XXX Communicator uses compiled-in build-time string defines
1242 : // to indicate the platform it was compiled *for*, not what it is
1243 : // currently running *on* which is what this does.
1244 0 : nsCAutoString plat;
1245 0 : rv = service->GetOscpu(plat);
1246 0 : CopyASCIItoUTF16(plat, aPlatform);
1247 : #endif
1248 :
1249 0 : return rv;
1250 : }
1251 : nsresult
1252 0 : NS_GetNavigatorAppVersion(nsAString& aAppVersion)
1253 : {
1254 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
1255 : const nsAdoptingString& override =
1256 0 : mozilla::Preferences::GetString("general.appversion.override");
1257 :
1258 0 : if (override) {
1259 0 : aAppVersion = override;
1260 0 : return NS_OK;
1261 : }
1262 : }
1263 :
1264 : nsresult rv;
1265 :
1266 : nsCOMPtr<nsIHttpProtocolHandler>
1267 0 : service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
1268 0 : NS_ENSURE_SUCCESS(rv, rv);
1269 :
1270 0 : nsCAutoString str;
1271 0 : rv = service->GetAppVersion(str);
1272 0 : CopyASCIItoUTF16(str, aAppVersion);
1273 0 : NS_ENSURE_SUCCESS(rv, rv);
1274 :
1275 0 : aAppVersion.AppendLiteral(" (");
1276 :
1277 0 : rv = service->GetPlatform(str);
1278 0 : NS_ENSURE_SUCCESS(rv, rv);
1279 :
1280 0 : AppendASCIItoUTF16(str, aAppVersion);
1281 0 : aAppVersion.Append(PRUnichar(')'));
1282 :
1283 0 : return rv;
1284 : }
1285 :
1286 : nsresult
1287 0 : NS_GetNavigatorAppName(nsAString& aAppName)
1288 : {
1289 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
1290 : const nsAdoptingString& override =
1291 0 : mozilla::Preferences::GetString("general.appname.override");
1292 :
1293 0 : if (override) {
1294 0 : aAppName = override;
1295 0 : return NS_OK;
1296 : }
1297 : }
1298 :
1299 0 : aAppName.AssignLiteral("Netscape");
1300 0 : return NS_OK;
1301 4392 : }
|