LCOV - code coverage report
Current view: top level - xpfe/appshell - nsAppShellService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 124 373 33.2 %
Date: 2017-07-14 16:53:18 Functions: 11 79 13.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : 
       7             : #include "nsIAppShellService.h"
       8             : #include "nsIComponentManager.h"
       9             : #include "nsIURL.h"
      10             : #include "nsNetUtil.h"
      11             : #include "nsIServiceManager.h"
      12             : #include "nsIObserverService.h"
      13             : #include "nsIObserver.h"
      14             : #include "nsIXPConnect.h"
      15             : #include "nsIXULRuntime.h"
      16             : 
      17             : #include "nsIWindowMediator.h"
      18             : #include "nsIWindowWatcher.h"
      19             : #include "nsPIWindowWatcher.h"
      20             : #include "nsIDOMWindow.h"
      21             : #include "nsPIDOMWindow.h"
      22             : #include "nsWebShellWindow.h"
      23             : 
      24             : #include "nsWidgetInitData.h"
      25             : #include "nsWidgetsCID.h"
      26             : #include "nsIWidget.h"
      27             : #include "nsIRequestObserver.h"
      28             : #include "nsIEmbeddingSiteWindow.h"
      29             : 
      30             : #include "nsAppShellService.h"
      31             : #include "nsContentUtils.h"
      32             : #include "nsThreadUtils.h"
      33             : #include "nsISupportsPrimitives.h"
      34             : #include "nsILoadContext.h"
      35             : #include "nsIWebNavigation.h"
      36             : #include "nsIWindowlessBrowser.h"
      37             : 
      38             : #include "mozilla/Attributes.h"
      39             : #include "mozilla/Preferences.h"
      40             : #include "mozilla/Services.h"
      41             : #include "mozilla/StartupTimeline.h"
      42             : #include "mozilla/intl/LocaleService.h"
      43             : 
      44             : #include "nsEmbedCID.h"
      45             : #include "nsIWebBrowser.h"
      46             : #include "nsIDocShell.h"
      47             : #include "gfxPlatform.h"
      48             : 
      49             : #ifdef MOZ_INSTRUMENT_EVENT_LOOP
      50             : #include "EventTracer.h"
      51             : #endif
      52             : 
      53             : using namespace mozilla;
      54             : using mozilla::intl::LocaleService;
      55             : 
      56             : // Default URL for the hidden window, can be overridden by a pref on Mac
      57             : #define DEFAULT_HIDDENWINDOW_URL "resource://gre-resources/hiddenWindow.html"
      58             : 
      59             : class nsIAppShell;
      60             : 
      61           1 : nsAppShellService::nsAppShellService() :
      62             :   mXPCOMWillShutDown(false),
      63             :   mXPCOMShuttingDown(false),
      64             :   mModalWindowCount(0),
      65             :   mApplicationProvidedHiddenWindow(false),
      66           1 :   mScreenId(0)
      67             : {
      68           2 :   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
      69             : 
      70           1 :   if (obs) {
      71           1 :     obs->AddObserver(this, "xpcom-will-shutdown", false);
      72           1 :     obs->AddObserver(this, "xpcom-shutdown", false);
      73             :   }
      74           1 : }
      75             : 
      76           0 : nsAppShellService::~nsAppShellService()
      77             : {
      78           0 : }
      79             : 
      80             : 
      81             : /*
      82             :  * Implement the nsISupports methods...
      83             :  */
      84          69 : NS_IMPL_ISUPPORTS(nsAppShellService,
      85             :                   nsIAppShellService,
      86             :                   nsIObserver)
      87             : 
      88             : NS_IMETHODIMP
      89           1 : nsAppShellService::CreateHiddenWindow()
      90             : {
      91           1 :   return CreateHiddenWindowHelper(false);
      92             : }
      93             : 
      94             : NS_IMETHODIMP
      95           0 : nsAppShellService::SetScreenId(uint32_t aScreenId)
      96             : {
      97           0 :   mScreenId = aScreenId;
      98           0 :   return NS_OK;
      99             : }
     100             : 
     101             : void
     102           0 : nsAppShellService::EnsurePrivateHiddenWindow()
     103             : {
     104           0 :   if (!mHiddenPrivateWindow) {
     105           0 :     CreateHiddenWindowHelper(true);
     106             :   }
     107           0 : }
     108             : 
     109             : nsresult
     110           1 : nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
     111             : {
     112             :   nsresult rv;
     113           1 :   int32_t initialHeight = 100, initialWidth = 100;
     114             : 
     115             : #ifdef XP_MACOSX
     116             :   uint32_t    chromeMask = 0;
     117             :   nsAdoptingCString prefVal =
     118             :       Preferences::GetCString("browser.hiddenWindowChromeURL");
     119             :   const char* hiddenWindowURL = prefVal.get() ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
     120             :   if (aIsPrivate) {
     121             :     hiddenWindowURL = DEFAULT_HIDDENWINDOW_URL;
     122             :   } else {
     123             :     mApplicationProvidedHiddenWindow = prefVal.get() ? true : false;
     124             :   }
     125             : #else
     126             :   static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL;
     127           1 :   uint32_t    chromeMask =  nsIWebBrowserChrome::CHROME_ALL;
     128             : #endif
     129             : 
     130           2 :   nsCOMPtr<nsIURI> url;
     131           1 :   rv = NS_NewURI(getter_AddRefs(url), hiddenWindowURL);
     132           1 :   NS_ENSURE_SUCCESS(rv, rv);
     133             : 
     134           1 :   if (aIsPrivate) {
     135           0 :     chromeMask |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
     136             :   }
     137             : 
     138           2 :   RefPtr<nsWebShellWindow> newWindow;
     139           1 :   rv = JustCreateTopWindow(nullptr, url,
     140             :                            chromeMask, initialWidth, initialHeight,
     141           2 :                            true, nullptr, nullptr, getter_AddRefs(newWindow));
     142           1 :   NS_ENSURE_SUCCESS(rv, rv);
     143             : 
     144           2 :   nsCOMPtr<nsIDocShell> docShell;
     145           1 :   newWindow->GetDocShell(getter_AddRefs(docShell));
     146           1 :   if (docShell) {
     147           1 :     docShell->SetIsActive(false);
     148           1 :     if (aIsPrivate) {
     149           0 :       docShell->SetAffectPrivateSessionLifetime(false);
     150             :     }
     151             :   }
     152             : 
     153           1 :   if (aIsPrivate) {
     154           0 :     mHiddenPrivateWindow.swap(newWindow);
     155             :   } else {
     156           1 :     mHiddenWindow.swap(newWindow);
     157             :   }
     158             : 
     159           1 :   return NS_OK;
     160             : }
     161             : 
     162             : NS_IMETHODIMP
     163           0 : nsAppShellService::DestroyHiddenWindow()
     164             : {
     165           0 :   if (mHiddenWindow) {
     166           0 :     mHiddenWindow->Destroy();
     167             : 
     168           0 :     mHiddenWindow = nullptr;
     169             :   }
     170             : 
     171           0 :   if (mHiddenPrivateWindow) {
     172           0 :     mHiddenPrivateWindow->Destroy();
     173             : 
     174           0 :     mHiddenPrivateWindow = nullptr;
     175             :   }
     176             : 
     177           0 :   return NS_OK;
     178             : }
     179             : 
     180             : /*
     181             :  * Create a new top level window and display the given URL within it...
     182             :  */
     183             : NS_IMETHODIMP
     184           1 : nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
     185             :                                         nsIURI *aUrl,
     186             :                                         uint32_t aChromeMask,
     187             :                                         int32_t aInitialWidth,
     188             :                                         int32_t aInitialHeight,
     189             :                                         nsITabParent *aOpeningTab,
     190             :                                         mozIDOMWindowProxy *aOpenerWindow,
     191             :                                         nsIXULWindow **aResult)
     192             : 
     193             : {
     194             :   nsresult rv;
     195             : 
     196           1 :   StartupTimeline::RecordOnce(StartupTimeline::CREATE_TOP_LEVEL_WINDOW);
     197             : 
     198           2 :   RefPtr<nsWebShellWindow> newWindow;
     199           1 :   rv = JustCreateTopWindow(aParent, aUrl,
     200             :                            aChromeMask, aInitialWidth, aInitialHeight,
     201             :                            false, aOpeningTab, aOpenerWindow,
     202           2 :                            getter_AddRefs(newWindow));
     203           1 :   newWindow.forget(aResult);
     204             : 
     205           1 :   if (NS_SUCCEEDED(rv)) {
     206             :     // the addref resulting from this is the owning addref for this window
     207           1 :     RegisterTopLevelWindow(*aResult);
     208           2 :     nsCOMPtr<nsIXULWindow> parent;
     209           1 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT)
     210           0 :       parent = aParent;
     211           1 :     (*aResult)->SetZLevel(CalculateWindowZLevel(parent, aChromeMask));
     212             :   }
     213             : 
     214           2 :   return rv;
     215             : }
     216             : 
     217             : /*
     218             :  * This class provides a stub implementation of nsIWebBrowserChrome2, as needed
     219             :  * by nsAppShellService::CreateWindowlessBrowser
     220             :  */
     221             : class WebBrowserChrome2Stub : public nsIWebBrowserChrome2,
     222             :                               public nsIEmbeddingSiteWindow,
     223             :                               public nsIInterfaceRequestor,
     224             :                               public nsSupportsWeakReference {
     225             : protected:
     226             :     nsCOMPtr<nsIWebBrowser> mBrowser;
     227           0 :     virtual ~WebBrowserChrome2Stub() {}
     228             : public:
     229           0 :     explicit WebBrowserChrome2Stub(nsIWebBrowser *aBrowser) : mBrowser(aBrowser) {}
     230             :     NS_DECL_ISUPPORTS
     231             :     NS_DECL_NSIWEBBROWSERCHROME
     232             :     NS_DECL_NSIWEBBROWSERCHROME2
     233             :     NS_DECL_NSIINTERFACEREQUESTOR
     234             :     NS_DECL_NSIEMBEDDINGSITEWINDOW
     235             : };
     236             : 
     237           0 : NS_INTERFACE_MAP_BEGIN(WebBrowserChrome2Stub)
     238           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
     239           0 :   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
     240           0 :   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
     241           0 :   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
     242           0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     243           0 :   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
     244           0 : NS_INTERFACE_MAP_END
     245             : 
     246           0 : NS_IMPL_ADDREF(WebBrowserChrome2Stub)
     247           0 : NS_IMPL_RELEASE(WebBrowserChrome2Stub)
     248             : 
     249             : NS_IMETHODIMP
     250           0 : WebBrowserChrome2Stub::SetStatus(uint32_t aStatusType, const char16_t* aStatus)
     251             : {
     252           0 :   return NS_OK;
     253             : }
     254             : 
     255             : NS_IMETHODIMP
     256           0 : WebBrowserChrome2Stub::GetWebBrowser(nsIWebBrowser** aWebBrowser)
     257             : {
     258           0 :   NS_NOTREACHED("WebBrowserChrome2Stub::GetWebBrowser is not supported");
     259           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     260             : }
     261             : 
     262             : NS_IMETHODIMP
     263           0 : WebBrowserChrome2Stub::SetWebBrowser(nsIWebBrowser* aWebBrowser)
     264             : {
     265           0 :   NS_NOTREACHED("WebBrowserChrome2Stub::SetWebBrowser is not supported");
     266           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     267             : }
     268             : 
     269             : NS_IMETHODIMP
     270           0 : WebBrowserChrome2Stub::GetChromeFlags(uint32_t* aChromeFlags)
     271             : {
     272           0 :   *aChromeFlags = 0;
     273           0 :   return NS_OK;
     274             : }
     275             : 
     276             : NS_IMETHODIMP
     277           0 : WebBrowserChrome2Stub::SetChromeFlags(uint32_t aChromeFlags)
     278             : {
     279           0 :   NS_NOTREACHED("WebBrowserChrome2Stub::SetChromeFlags is not supported");
     280           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     281             : }
     282             : 
     283             : NS_IMETHODIMP
     284           0 : WebBrowserChrome2Stub::DestroyBrowserWindow()
     285             : {
     286           0 :   NS_NOTREACHED("WebBrowserChrome2Stub::DestroyBrowserWindow is not supported");
     287           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     288             : }
     289             : 
     290             : NS_IMETHODIMP
     291           0 : WebBrowserChrome2Stub::SizeBrowserTo(int32_t aCX, int32_t aCY)
     292             : {
     293           0 :   NS_NOTREACHED("WebBrowserChrome2Stub::SizeBrowserTo is not supported");
     294           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     295             : }
     296             : 
     297             : NS_IMETHODIMP
     298           0 : WebBrowserChrome2Stub::ShowAsModal()
     299             : {
     300           0 :   NS_NOTREACHED("WebBrowserChrome2Stub::ShowAsModal is not supported");
     301           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     302             : }
     303             : 
     304             : NS_IMETHODIMP
     305           0 : WebBrowserChrome2Stub::IsWindowModal(bool* aResult)
     306             : {
     307           0 :   *aResult = false;
     308           0 :   return NS_OK;
     309             : }
     310             : 
     311             : NS_IMETHODIMP
     312           0 : WebBrowserChrome2Stub::ExitModalEventLoop(nsresult aStatus)
     313             : {
     314           0 :   NS_NOTREACHED("WebBrowserChrome2Stub::ExitModalEventLoop is not supported");
     315           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     316             : }
     317             : 
     318             : NS_IMETHODIMP
     319           0 : WebBrowserChrome2Stub::SetStatusWithContext(uint32_t aStatusType,
     320             :                                             const nsAString& aStatusText,
     321             :                                             nsISupports* aStatusContext)
     322             : {
     323           0 :   return NS_OK;
     324             : }
     325             : 
     326             : NS_IMETHODIMP
     327           0 : WebBrowserChrome2Stub::GetInterface(const nsIID& aIID, void** aSink)
     328             : {
     329           0 :     return QueryInterface(aIID, aSink);
     330             : }
     331             : 
     332             : // nsIEmbeddingSiteWindow impl
     333             : NS_IMETHODIMP
     334           0 : WebBrowserChrome2Stub::GetDimensions(uint32_t flags, int32_t* x, int32_t* y, int32_t* cx, int32_t* cy)
     335             : {
     336           0 :   if (x) {
     337           0 :     *x = 0;
     338             :   }
     339             : 
     340           0 :   if (y) {
     341           0 :     *y = 0;
     342             :   }
     343             : 
     344           0 :   if (cx) {
     345           0 :     *cx = 0;
     346             :   }
     347             : 
     348           0 :   if (cy) {
     349           0 :     *cy = 0;
     350             :   }
     351             : 
     352           0 :   return NS_OK;
     353             : }
     354             : 
     355             : NS_IMETHODIMP
     356           0 : WebBrowserChrome2Stub::SetDimensions(uint32_t flags, int32_t x, int32_t y, int32_t cx, int32_t cy)
     357             : {
     358           0 :   nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(mBrowser);
     359           0 :   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
     360           0 :   window->SetSize(cx, cy, true);
     361           0 :   return NS_OK;
     362             : }
     363             : 
     364             : NS_IMETHODIMP
     365           0 : WebBrowserChrome2Stub::SetFocus()
     366             : {
     367           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     368             : }
     369             : 
     370             : NS_IMETHODIMP
     371           0 : WebBrowserChrome2Stub::GetVisibility(bool* aVisibility)
     372             : {
     373           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     374             : }
     375             : NS_IMETHODIMP
     376           0 : WebBrowserChrome2Stub::SetVisibility(bool aVisibility)
     377             : {
     378           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     379             : }
     380             : 
     381             : NS_IMETHODIMP
     382           0 : WebBrowserChrome2Stub::GetTitle(char16_t** aTitle)
     383             : {
     384           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     385             : }
     386             : NS_IMETHODIMP
     387           0 : WebBrowserChrome2Stub::SetTitle(const char16_t* aTitle)
     388             : {
     389           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     390             : }
     391             : 
     392             : NS_IMETHODIMP
     393           0 : WebBrowserChrome2Stub::GetSiteWindow(void** aSiteWindow)
     394             : {
     395           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     396             : }
     397             : 
     398             : NS_IMETHODIMP
     399           0 : WebBrowserChrome2Stub::Blur()
     400             : {
     401           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     402             : }
     403             : 
     404             : class BrowserDestroyer final : public Runnable
     405             : {
     406             : public:
     407           0 :   BrowserDestroyer(nsIWebBrowser* aBrowser, nsISupports* aContainer)
     408           0 :     : mozilla::Runnable("BrowserDestroyer")
     409             :     , mBrowser(aBrowser)
     410           0 :     , mContainer(aContainer)
     411             :   {
     412           0 :   }
     413             : 
     414             :   NS_IMETHOD
     415           0 :   Run() override
     416             :   {
     417             :     // Explicitly destroy the browser, in case this isn't the last reference.
     418           0 :     nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(mBrowser);
     419           0 :     return window->Destroy();
     420             :   }
     421             : 
     422             : protected:
     423           0 :   virtual ~BrowserDestroyer() {}
     424             : 
     425             : private:
     426             :   nsCOMPtr<nsIWebBrowser> mBrowser;
     427             :   nsCOMPtr<nsISupports> mContainer;
     428             : };
     429             : 
     430             : // This is the "stub" we return from CreateWindowlessBrowser - it exists
     431             : // to manage the lifetimes of the nsIWebBrowser and container window.
     432             : // In particular, it keeps a strong reference to both, to prevent them from
     433             : // being collected while this object remains alive, and ensures that they
     434             : // aren't destroyed when it's not safe to run scripts.
     435             : class WindowlessBrowser final : public nsIWindowlessBrowser,
     436             :                                 public nsIInterfaceRequestor
     437             : {
     438             : public:
     439           0 :   WindowlessBrowser(nsIWebBrowser *aBrowser, nsISupports *aContainer) :
     440             :     mBrowser(aBrowser),
     441             :     mContainer(aContainer),
     442           0 :     mClosed(false)
     443             :   {
     444           0 :     mWebNavigation = do_QueryInterface(aBrowser);
     445           0 :     mInterfaceRequestor = do_QueryInterface(aBrowser);
     446           0 :   }
     447             :   NS_DECL_ISUPPORTS
     448           0 :   NS_FORWARD_SAFE_NSIWEBNAVIGATION(mWebNavigation)
     449           0 :   NS_FORWARD_SAFE_NSIINTERFACEREQUESTOR(mInterfaceRequestor)
     450             : 
     451             :   NS_IMETHOD
     452           0 :   Close() override
     453             :   {
     454           0 :     NS_ENSURE_TRUE(!mClosed, NS_ERROR_UNEXPECTED);
     455           0 :     NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
     456             :                  "WindowlessBrowser::Close called when not safe to run scripts");
     457             : 
     458           0 :     mClosed = true;
     459             : 
     460           0 :     mWebNavigation = nullptr;
     461           0 :     mInterfaceRequestor = nullptr;
     462             : 
     463           0 :     nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(mBrowser);
     464           0 :     return window->Destroy();
     465             :   }
     466             : 
     467             : protected:
     468           0 :   virtual ~WindowlessBrowser()
     469           0 :   {
     470           0 :     if (mClosed) {
     471           0 :       return;
     472             :     }
     473             : 
     474           0 :     NS_WARNING("Windowless browser was not closed prior to destruction");
     475             : 
     476             :     // The docshell destructor needs to dispatch events, and can only run
     477             :     // when it's safe to run scripts. If this was triggered by GC, it may
     478             :     // not always be safe to run scripts, in which cases we need to delay
     479             :     // destruction until it is.
     480           0 :     nsCOMPtr<nsIRunnable> runnable = new BrowserDestroyer(mBrowser, mContainer);
     481           0 :     nsContentUtils::AddScriptRunner(runnable);
     482           0 :   }
     483             : 
     484             : private:
     485             :   nsCOMPtr<nsIWebBrowser> mBrowser;
     486             :   nsCOMPtr<nsIWebNavigation> mWebNavigation;
     487             :   nsCOMPtr<nsIInterfaceRequestor> mInterfaceRequestor;
     488             :   // we don't use the container but just hold a reference to it.
     489             :   nsCOMPtr<nsISupports> mContainer;
     490             : 
     491             :   bool mClosed;
     492             : };
     493             : 
     494           0 : NS_IMPL_ISUPPORTS(WindowlessBrowser, nsIWindowlessBrowser, nsIWebNavigation, nsIInterfaceRequestor)
     495             : 
     496             : 
     497             : NS_IMETHODIMP
     498           0 : nsAppShellService::CreateWindowlessBrowser(bool aIsChrome, nsIWindowlessBrowser **aResult)
     499             : {
     500             :   /* First, we create an instance of nsWebBrowser. Instances of this class have
     501             :    * an associated doc shell, which is what we're interested in.
     502             :    */
     503           0 :   nsCOMPtr<nsIWebBrowser> browser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
     504           0 :   if (!browser) {
     505           0 :     NS_ERROR("Couldn't create instance of nsWebBrowser!");
     506           0 :     return NS_ERROR_FAILURE;
     507             :   }
     508             : 
     509             :   /* Next, we set the container window for our instance of nsWebBrowser. Since
     510             :    * we don't actually have a window, we instead set the container window to be
     511             :    * an instance of WebBrowserChrome2Stub, which provides a stub implementation
     512             :    * of nsIWebBrowserChrome2.
     513             :    */
     514           0 :   RefPtr<WebBrowserChrome2Stub> stub = new WebBrowserChrome2Stub(browser);
     515           0 :   browser->SetContainerWindow(stub);
     516             : 
     517           0 :   nsCOMPtr<nsIWebNavigation> navigation = do_QueryInterface(browser);
     518             : 
     519           0 :   nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(navigation);
     520           0 :   item->SetItemType(aIsChrome ? nsIDocShellTreeItem::typeChromeWrapper
     521           0 :                               : nsIDocShellTreeItem::typeContentWrapper);
     522             : 
     523             :   /* A windowless web browser doesn't have an associated OS level window. To
     524             :    * accomplish this, we initialize the window associated with our instance of
     525             :    * nsWebBrowser with an instance of HeadlessWidget/PuppetWidget, which provide
     526             :    * a stub implementation of nsIWidget.
     527             :    */
     528           0 :   nsCOMPtr<nsIWidget> widget;
     529           0 :   if (gfxPlatform::IsHeadless()) {
     530           0 :     widget = nsIWidget::CreateHeadlessWidget();
     531             :   } else {
     532           0 :     widget = nsIWidget::CreatePuppetWidget(nullptr);
     533             :   }
     534           0 :   if (!widget) {
     535           0 :     NS_ERROR("Couldn't create instance of stub widget");
     536           0 :     return NS_ERROR_FAILURE;
     537             :   }
     538             :   nsresult rv =
     539           0 :     widget->Create(nullptr, 0, LayoutDeviceIntRect(0, 0, 0, 0), nullptr);
     540           0 :   NS_ENSURE_SUCCESS(rv, rv);
     541           0 :   nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(navigation);
     542           0 :   window->InitWindow(0, widget, 0, 0, 0, 0);
     543           0 :   window->Create();
     544             : 
     545           0 :   nsISupports *isstub = NS_ISUPPORTS_CAST(nsIWebBrowserChrome2*, stub);
     546           0 :   RefPtr<nsIWindowlessBrowser> result = new WindowlessBrowser(browser, isstub);
     547           0 :   nsCOMPtr<nsIDocShell> docshell = do_GetInterface(result);
     548           0 :   docshell->SetInvisible(true);
     549             : 
     550           0 :   result.forget(aResult);
     551           0 :   return NS_OK;
     552             : }
     553             : 
     554             : uint32_t
     555           1 : nsAppShellService::CalculateWindowZLevel(nsIXULWindow *aParent,
     556             :                                          uint32_t      aChromeMask)
     557             : {
     558             :   uint32_t zLevel;
     559             : 
     560           1 :   zLevel = nsIXULWindow::normalZ;
     561           1 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_RAISED)
     562           0 :     zLevel = nsIXULWindow::raisedZ;
     563           1 :   else if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_LOWERED)
     564           0 :     zLevel = nsIXULWindow::loweredZ;
     565             : 
     566             : #ifdef XP_MACOSX
     567             :   /* Platforms on which modal windows are always application-modal, not
     568             :      window-modal (that's just the Mac, right?) want modal windows to
     569             :      be stacked on top of everyone else.
     570             : 
     571             :      On Mac OS X, bind modality to parent window instead of app (ala Mac OS 9)
     572             :   */
     573             :   uint32_t modalDepMask = nsIWebBrowserChrome::CHROME_MODAL |
     574             :                           nsIWebBrowserChrome::CHROME_DEPENDENT;
     575             :   if (aParent && (aChromeMask & modalDepMask)) {
     576             :     aParent->GetZLevel(&zLevel);
     577             :   }
     578             : #else
     579             :   /* Platforms with native support for dependent windows (that's everyone
     580             :       but pre-Mac OS X, right?) know how to stack dependent windows. On these
     581             :       platforms, give the dependent window the same level as its parent,
     582             :       so we won't try to override the normal platform behaviour. */
     583           1 :   if ((aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT) && aParent)
     584           0 :     aParent->GetZLevel(&zLevel);
     585             : #endif
     586             : 
     587           1 :   return zLevel;
     588             : }
     589             : 
     590             : #ifdef XP_WIN
     591             : /*
     592             :  * Checks to see if any existing window is currently in fullscreen mode.
     593             :  */
     594             : static bool
     595             : CheckForFullscreenWindow()
     596             : {
     597             :   nsCOMPtr<nsIWindowMediator> wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     598             :   if (!wm)
     599             :     return false;
     600             : 
     601             :   nsCOMPtr<nsISimpleEnumerator> windowList;
     602             :   wm->GetXULWindowEnumerator(nullptr, getter_AddRefs(windowList));
     603             :   if (!windowList)
     604             :     return false;
     605             : 
     606             :   for (;;) {
     607             :     bool more = false;
     608             :     windowList->HasMoreElements(&more);
     609             :     if (!more)
     610             :       return false;
     611             : 
     612             :     nsCOMPtr<nsISupports> supportsWindow;
     613             :     windowList->GetNext(getter_AddRefs(supportsWindow));
     614             :     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(supportsWindow));
     615             :     if (baseWin) {
     616             :       nsCOMPtr<nsIWidget> widget;
     617             :       baseWin->GetMainWidget(getter_AddRefs(widget));
     618             :       if (widget && widget->SizeMode() == nsSizeMode_Fullscreen) {
     619             :         return true;
     620             :       }
     621             :     }
     622             :   }
     623             :   return false;
     624             : }
     625             : #endif
     626             : 
     627             : /*
     628             :  * Just do the window-making part of CreateTopLevelWindow
     629             :  */
     630             : nsresult
     631           2 : nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
     632             :                                        nsIURI *aUrl,
     633             :                                        uint32_t aChromeMask,
     634             :                                        int32_t aInitialWidth,
     635             :                                        int32_t aInitialHeight,
     636             :                                        bool aIsHiddenWindow,
     637             :                                        nsITabParent *aOpeningTab,
     638             :                                        mozIDOMWindowProxy *aOpenerWindow,
     639             :                                        nsWebShellWindow **aResult)
     640             : {
     641           2 :   *aResult = nullptr;
     642           2 :   NS_ENSURE_STATE(!mXPCOMWillShutDown);
     643             : 
     644           4 :   nsCOMPtr<nsIXULWindow> parent;
     645           2 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT)
     646           0 :     parent = aParent;
     647             : 
     648           4 :   RefPtr<nsWebShellWindow> window = new nsWebShellWindow(aChromeMask);
     649             : 
     650             : #ifdef XP_WIN
     651             :   // If the parent is currently fullscreen, tell the child to ignore persisted
     652             :   // full screen states. This way new browser windows open on top of fullscreen
     653             :   // windows normally.
     654             :   if (window && CheckForFullscreenWindow())
     655             :     window->IgnoreXULSizeMode(true);
     656             : #endif
     657             : 
     658           2 :   nsWidgetInitData widgetInitData;
     659             : 
     660           2 :   if (aIsHiddenWindow)
     661           1 :     widgetInitData.mWindowType = eWindowType_invisible;
     662             :   else
     663           1 :     widgetInitData.mWindowType = aChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG ?
     664             :       eWindowType_dialog : eWindowType_toplevel;
     665             : 
     666           2 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_POPUP)
     667           0 :     widgetInitData.mWindowType = eWindowType_popup;
     668             : 
     669           2 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_SUPPRESS_ANIMATION)
     670           1 :     widgetInitData.mIsAnimationSuppressed = true;
     671             : 
     672             : #ifdef XP_MACOSX
     673             :   // Mac OS X sheet support
     674             :   // Adding CHROME_OPENAS_CHROME to sheetMask makes modal windows opened from
     675             :   // nsGlobalWindow::ShowModalDialog() be dialogs (not sheets), while modal
     676             :   // windows opened from nsPromptService::DoDialog() still are sheets.  This
     677             :   // fixes bmo bug 395465 (see nsCocoaWindow::StandardCreate() and
     678             :   // nsCocoaWindow::SetModal()).
     679             :   uint32_t sheetMask = nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
     680             :                        nsIWebBrowserChrome::CHROME_MODAL |
     681             :                        nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
     682             :   if (parent &&
     683             :       (parent != mHiddenWindow && parent != mHiddenPrivateWindow) &&
     684             :       ((aChromeMask & sheetMask) == sheetMask)) {
     685             :     widgetInitData.mWindowType = eWindowType_sheet;
     686             :   }
     687             : #endif
     688             : 
     689             : #if defined(XP_WIN)
     690             :   if (widgetInitData.mWindowType == eWindowType_toplevel ||
     691             :       widgetInitData.mWindowType == eWindowType_dialog)
     692             :     widgetInitData.clipChildren = true;
     693             : #endif
     694             : 
     695             :   // note default chrome overrides other OS chrome settings, but
     696             :   // not internal chrome
     697           2 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_DEFAULT)
     698           0 :     widgetInitData.mBorderStyle = eBorderStyle_default;
     699           2 :   else if ((aChromeMask & nsIWebBrowserChrome::CHROME_ALL) == nsIWebBrowserChrome::CHROME_ALL)
     700           2 :     widgetInitData.mBorderStyle = eBorderStyle_all;
     701             :   else {
     702           0 :     widgetInitData.mBorderStyle = eBorderStyle_none; // assumes none == 0x00
     703           0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_BORDERS)
     704           0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_border);
     705           0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_TITLEBAR)
     706           0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_title);
     707           0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_CLOSE)
     708           0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_close);
     709           0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) {
     710           0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_resizeh);
     711             :       // only resizable windows get the maximize button (but not dialogs)
     712           0 :       if (!(aChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG))
     713           0 :         widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_maximize);
     714             :     }
     715             :     // all windows (except dialogs) get minimize buttons and the system menu
     716           0 :     if (!(aChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG))
     717           0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_minimize | eBorderStyle_menu);
     718             :     // but anyone can explicitly ask for a minimize button
     719           0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_MIN) {
     720           0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_minimize);
     721             :     }
     722             :   }
     723             : 
     724           2 :   if (aInitialWidth == nsIAppShellService::SIZE_TO_CONTENT ||
     725             :       aInitialHeight == nsIAppShellService::SIZE_TO_CONTENT) {
     726           1 :     aInitialWidth = 1;
     727           1 :     aInitialHeight = 1;
     728           1 :     window->SetIntrinsicallySized(true);
     729             :   }
     730             : 
     731           2 :   bool center = aChromeMask & nsIWebBrowserChrome::CHROME_CENTER_SCREEN;
     732             : 
     733           2 :   widgetInitData.mRTL = LocaleService::GetInstance()->IsAppLocaleRTL();
     734             : 
     735             : #ifdef MOZ_WIDGET_GONK
     736             :   // B2G multi-screen support. Screen ID is for differentiating screens of
     737             :   // windows, and due to the hardware limitation, it is platform-specific for
     738             :   // now, which align with the value of display type defined in HWC.
     739             :   widgetInitData.mScreenId = mScreenId;
     740             : #endif
     741             : 
     742           2 :   nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
     743             :                                    aUrl, aInitialWidth, aInitialHeight,
     744             :                                    aIsHiddenWindow, aOpeningTab,
     745           2 :                                    aOpenerWindow, widgetInitData);
     746             : 
     747           2 :   NS_ENSURE_SUCCESS(rv, rv);
     748             : 
     749             :   // Enforce the Private Browsing autoStart pref first.
     750             :   bool isPrivateBrowsingWindow =
     751           2 :     Preferences::GetBool("browser.privatebrowsing.autostart");
     752           2 :   bool isUsingRemoteTabs = mozilla::BrowserTabsRemoteAutostart();
     753             : 
     754           2 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW) {
     755             :     // Caller requested a private window
     756           0 :     isPrivateBrowsingWindow = true;
     757             :   }
     758           2 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW) {
     759           1 :     isUsingRemoteTabs = true;
     760             :   }
     761             : 
     762           4 :   nsCOMPtr<mozIDOMWindowProxy> domWin = do_GetInterface(aParent);
     763           4 :   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(domWin);
     764           4 :   nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(webNav);
     765             : 
     766           2 :   if (!isPrivateBrowsingWindow && parentContext) {
     767             :     // Ensure that we propagate any existing private browsing status
     768             :     // from the parent, even if it will not actually be used
     769             :     // as a parent value.
     770           0 :     isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
     771             :   }
     772             : 
     773           2 :   if (parentContext) {
     774           0 :     isUsingRemoteTabs = parentContext->UseRemoteTabs();
     775             :   }
     776             : 
     777             :   nsCOMPtr<mozIDOMWindowProxy> newDomWin =
     778           4 :       do_GetInterface(NS_ISUPPORTS_CAST(nsIBaseWindow*, window));
     779           4 :   nsCOMPtr<nsIWebNavigation> newWebNav = do_GetInterface(newDomWin);
     780           4 :   nsCOMPtr<nsILoadContext> thisContext = do_GetInterface(newWebNav);
     781           2 :   if (thisContext) {
     782           2 :     thisContext->SetPrivateBrowsing(isPrivateBrowsingWindow);
     783           2 :     thisContext->SetRemoteTabs(isUsingRemoteTabs);
     784             :   }
     785             : 
     786           2 :   window.forget(aResult);
     787           2 :   if (parent)
     788           0 :     parent->AddChildWindow(*aResult);
     789             : 
     790           2 :   if (center)
     791           0 :     rv = (*aResult)->Center(parent, parent ? false : true, false);
     792             : 
     793           2 :   return rv;
     794             : }
     795             : 
     796             : NS_IMETHODIMP
     797           0 : nsAppShellService::GetHiddenWindow(nsIXULWindow **aWindow)
     798             : {
     799           0 :   NS_ENSURE_ARG_POINTER(aWindow);
     800             : 
     801           0 :   *aWindow = mHiddenWindow;
     802           0 :   NS_IF_ADDREF(*aWindow);
     803           0 :   return *aWindow ? NS_OK : NS_ERROR_FAILURE;
     804             : }
     805             : 
     806             : NS_IMETHODIMP
     807           1 : nsAppShellService::GetHiddenDOMWindow(mozIDOMWindowProxy **aWindow)
     808             : {
     809             :   nsresult rv;
     810           2 :   nsCOMPtr<nsIDocShell> docShell;
     811           1 :   NS_ENSURE_TRUE(mHiddenWindow, NS_ERROR_FAILURE);
     812             : 
     813           1 :   rv = mHiddenWindow->GetDocShell(getter_AddRefs(docShell));
     814           1 :   NS_ENSURE_SUCCESS(rv, rv);
     815           1 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     816             : 
     817           2 :   nsCOMPtr<nsPIDOMWindowOuter> hiddenDOMWindow(docShell->GetWindow());
     818           1 :   hiddenDOMWindow.forget(aWindow);
     819           1 :   return *aWindow ? NS_OK : NS_ERROR_FAILURE;
     820             : }
     821             : 
     822             : NS_IMETHODIMP
     823           0 : nsAppShellService::GetHiddenPrivateWindow(nsIXULWindow **aWindow)
     824             : {
     825           0 :   NS_ENSURE_ARG_POINTER(aWindow);
     826             : 
     827           0 :   EnsurePrivateHiddenWindow();
     828             : 
     829           0 :   *aWindow = mHiddenPrivateWindow;
     830           0 :   NS_IF_ADDREF(*aWindow);
     831           0 :   return *aWindow ? NS_OK : NS_ERROR_FAILURE;
     832             : }
     833             : 
     834             : NS_IMETHODIMP
     835           0 : nsAppShellService::GetHiddenPrivateDOMWindow(mozIDOMWindowProxy **aWindow)
     836             : {
     837           0 :   EnsurePrivateHiddenWindow();
     838             : 
     839             :   nsresult rv;
     840           0 :   nsCOMPtr<nsIDocShell> docShell;
     841           0 :   NS_ENSURE_TRUE(mHiddenPrivateWindow, NS_ERROR_FAILURE);
     842             : 
     843           0 :   rv = mHiddenPrivateWindow->GetDocShell(getter_AddRefs(docShell));
     844           0 :   NS_ENSURE_SUCCESS(rv, rv);
     845           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     846             : 
     847           0 :   nsCOMPtr<nsPIDOMWindowOuter> hiddenPrivateDOMWindow(docShell->GetWindow());
     848           0 :   hiddenPrivateDOMWindow.forget(aWindow);
     849           0 :   return *aWindow ? NS_OK : NS_ERROR_FAILURE;
     850             : }
     851             : 
     852             : NS_IMETHODIMP
     853           0 : nsAppShellService::GetHasHiddenPrivateWindow(bool* aHasPrivateWindow)
     854             : {
     855           0 :   NS_ENSURE_ARG_POINTER(aHasPrivateWindow);
     856             : 
     857           0 :   *aHasPrivateWindow = !!mHiddenPrivateWindow;
     858           0 :   return NS_OK;
     859             : }
     860             : 
     861             : NS_IMETHODIMP
     862           0 : nsAppShellService::GetApplicationProvidedHiddenWindow(bool* aAPHW)
     863             : {
     864           0 :     *aAPHW = mApplicationProvidedHiddenWindow;
     865           0 :     return NS_OK;
     866             : }
     867             : 
     868             : /*
     869             :  * Register a new top level window (created elsewhere)
     870             :  */
     871             : NS_IMETHODIMP
     872           1 : nsAppShellService::RegisterTopLevelWindow(nsIXULWindow* aWindow)
     873             : {
     874           1 :   NS_ENSURE_ARG_POINTER(aWindow);
     875             : 
     876           2 :   nsCOMPtr<nsIDocShell> docShell;
     877           1 :   aWindow->GetDocShell(getter_AddRefs(docShell));
     878           1 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     879             : 
     880           2 :   nsCOMPtr<nsPIDOMWindowOuter> domWindow(docShell->GetWindow());
     881           1 :   NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
     882           1 :   domWindow->SetInitialPrincipalToSubject();
     883             : 
     884             :   // tell the window mediator about the new window
     885             :   nsCOMPtr<nsIWindowMediator> mediator
     886           2 :     ( do_GetService(NS_WINDOWMEDIATOR_CONTRACTID) );
     887           1 :   NS_ASSERTION(mediator, "Couldn't get window mediator.");
     888             : 
     889           1 :   if (mediator)
     890           1 :     mediator->RegisterWindow(aWindow);
     891             : 
     892             :   // tell the window watcher about the new window
     893           2 :   nsCOMPtr<nsPIWindowWatcher> wwatcher ( do_GetService(NS_WINDOWWATCHER_CONTRACTID) );
     894           1 :   NS_ASSERTION(wwatcher, "No windowwatcher?");
     895           1 :   if (wwatcher && domWindow) {
     896           1 :     wwatcher->AddWindow(domWindow, 0);
     897             :   }
     898             : 
     899             :   // an ongoing attempt to quit is stopped by a newly opened window
     900           2 :   nsCOMPtr<nsIObserverService> obssvc = services::GetObserverService();
     901           1 :   NS_ASSERTION(obssvc, "Couldn't get observer service.");
     902             : 
     903           1 :   if (obssvc) {
     904           1 :     obssvc->NotifyObservers(aWindow, "xul-window-registered", nullptr);
     905           1 :     nsXULWindow* xulWindow = static_cast<nsXULWindow*>(aWindow);
     906           1 :     xulWindow->WasRegistered();
     907             :   }
     908             : 
     909           1 :   return NS_OK;
     910             : }
     911             : 
     912             : 
     913             : NS_IMETHODIMP
     914           0 : nsAppShellService::UnregisterTopLevelWindow(nsIXULWindow* aWindow)
     915             : {
     916           0 :   if (mXPCOMShuttingDown) {
     917             :     /* return an error code in order to:
     918             :        - avoid doing anything with other member variables while we are in
     919             :          the destructor
     920             :        - notify the caller not to release the AppShellService after
     921             :          unregistering the window
     922             :          (we don't want to be deleted twice consecutively to
     923             :          mHiddenWindow->Destroy() in our destructor)
     924             :     */
     925           0 :     return NS_ERROR_FAILURE;
     926             :   }
     927             : 
     928           0 :   NS_ENSURE_ARG_POINTER(aWindow);
     929             : 
     930           0 :   if (aWindow == mHiddenWindow) {
     931             :     // CreateHiddenWindow() does not register the window, so we're done.
     932           0 :     return NS_OK;
     933             :   }
     934           0 :   if (aWindow == mHiddenPrivateWindow) {
     935             :     // CreateHiddenWindow() does not register the window, so we're done.
     936           0 :     return NS_OK;
     937             :   }
     938             : 
     939             :   // tell the window mediator
     940             :   nsCOMPtr<nsIWindowMediator> mediator
     941           0 :     ( do_GetService(NS_WINDOWMEDIATOR_CONTRACTID) );
     942           0 :   NS_ASSERTION(mediator, "Couldn't get window mediator. Doing xpcom shutdown?");
     943             : 
     944           0 :   if (mediator)
     945           0 :     mediator->UnregisterWindow(aWindow);
     946             : 
     947             :   // tell the window watcher
     948           0 :   nsCOMPtr<nsPIWindowWatcher> wwatcher ( do_GetService(NS_WINDOWWATCHER_CONTRACTID) );
     949           0 :   NS_ASSERTION(wwatcher, "Couldn't get windowwatcher, doing xpcom shutdown?");
     950           0 :   if (wwatcher) {
     951           0 :     nsCOMPtr<nsIDocShell> docShell;
     952           0 :     aWindow->GetDocShell(getter_AddRefs(docShell));
     953           0 :     if (docShell) {
     954           0 :       nsCOMPtr<nsPIDOMWindowOuter> domWindow(docShell->GetWindow());
     955           0 :       if (domWindow)
     956           0 :         wwatcher->RemoveWindow(domWindow);
     957             :     }
     958             :   }
     959             : 
     960           0 :   return NS_OK;
     961             : }
     962             : 
     963             : 
     964             : NS_IMETHODIMP
     965           0 : nsAppShellService::Observe(nsISupports* aSubject, const char *aTopic,
     966             :                            const char16_t *aData)
     967             : {
     968           0 :   if (!strcmp(aTopic, "xpcom-will-shutdown")) {
     969           0 :     mXPCOMWillShutDown = true;
     970           0 :   } else if (!strcmp(aTopic, "xpcom-shutdown")) {
     971           0 :     mXPCOMShuttingDown = true;
     972           0 :     if (mHiddenWindow) {
     973           0 :       mHiddenWindow->Destroy();
     974             :     }
     975           0 :     if (mHiddenPrivateWindow) {
     976           0 :       mHiddenPrivateWindow->Destroy();
     977             :     }
     978             :   } else {
     979           0 :     NS_ERROR("Unexpected observer topic!");
     980             :   }
     981             : 
     982           0 :   return NS_OK;
     983             : }
     984             : 
     985             : NS_IMETHODIMP
     986           0 : nsAppShellService::StartEventLoopLagTracking(bool* aResult)
     987             : {
     988             : #ifdef MOZ_INSTRUMENT_EVENT_LOOP
     989           0 :     *aResult = mozilla::InitEventTracing(true);
     990             : #endif
     991           0 :     return NS_OK;
     992             : }
     993             : 
     994             : NS_IMETHODIMP
     995           0 : nsAppShellService::StopEventLoopLagTracking()
     996             : {
     997             : #ifdef MOZ_INSTRUMENT_EVENT_LOOP
     998           0 :     mozilla::ShutdownEventTracing();
     999             : #endif
    1000           0 :     return NS_OK;
    1001             : }

Generated by: LCOV version 1.13