widget/windows/winrt/FrameworkView.cpp

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

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

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

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "FrameworkView.h"
     7 #include "MetroAppShell.h"
     8 #include "MetroWidget.h"
     9 #include "mozilla/AutoRestore.h"
    10 #include "MetroUtils.h"
    11 #include "MetroApp.h"
    12 #include "UIABridgePublic.h"
    13 #include "KeyboardLayout.h"
    15 // generated
    16 #include "UIABridge.h"
    18 using namespace mozilla;
    19 using namespace mozilla::widget::winrt;
    20 #ifdef ACCESSIBILITY
    21 using namespace mozilla::a11y;
    22 #endif
    23 using namespace ABI::Windows::ApplicationModel;
    24 using namespace ABI::Windows::ApplicationModel::Core;
    25 using namespace ABI::Windows::ApplicationModel::Activation;
    26 using namespace ABI::Windows::UI::Core;
    27 using namespace ABI::Windows::UI::ViewManagement;
    28 using namespace ABI::Windows::UI::Input;
    29 using namespace ABI::Windows::Devices::Input;
    30 using namespace ABI::Windows::System;
    31 using namespace ABI::Windows::Foundation;
    32 using namespace Microsoft::WRL;
    33 using namespace Microsoft::WRL::Wrappers;
    35 namespace mozilla {
    36 namespace widget {
    37 namespace winrt {
    39 // statics
    40 bool FrameworkView::sKeyboardIsVisible = false;
    41 Rect FrameworkView::sKeyboardRect;
    42 HSTRING FrameworkView::sActivationURI = NULL;
    43 ApplicationExecutionState FrameworkView::sPreviousExecutionState;
    44 nsTArray<nsString>* sSettingsArray;
    46 FrameworkView::FrameworkView(MetroApp* aMetroApp) :
    47   mDPI(-1.0f),
    48   mWidget(nullptr),
    49   mShuttingDown(false),
    50   mMetroApp(aMetroApp),
    51   mWindow(nullptr),
    52   mMetroInput(nullptr),
    53   mWinVisible(false),
    54   mWinActiveState(false)
    55 {
    56   mActivated.value = 0;
    57   mWindowActivated.value = 0;
    58   mWindowVisibilityChanged.value = 0;
    59   mWindowSizeChanged.value = 0;
    60   mSoftKeyboardHidden.value = 0;
    61   mSoftKeyboardShown.value = 0;
    62   mDisplayPropertiesChanged.value = 0;
    63   mAutomationProviderRequested.value = 0;
    64   mDataTransferRequested.value = 0;
    65   mSearchQuerySubmitted.value = 0;
    66   mPlayToRequested.value = 0;
    67   mSettingsPane.value = 0;
    68   mPrintManager.value = 0;
    69   memset(&sKeyboardRect, 0, sizeof(Rect));
    70   sSettingsArray = new nsTArray<nsString>();
    71   LogFunction();
    72 }
    74 ////////////////////////////////////////////////////
    75 // IFrameworkView impl.
    77 HRESULT
    78 FrameworkView::Initialize(ICoreApplicationView* aAppView)
    79 {
    80   LogFunction();
    81   if (mShuttingDown)
    82     return E_FAIL;
    84   aAppView->add_Activated(Callback<__FITypedEventHandler_2_Windows__CApplicationModel__CCore__CCoreApplicationView_Windows__CApplicationModel__CActivation__CIActivatedEventArgs_t>(
    85     this, &FrameworkView::OnActivated).Get(), &mActivated);
    87   //CoCreateInstance(CLSID_WICImagingFactory, nullptr,
    88   //                 CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&mWicFactory));
    89   return S_OK;
    90 }
    92 HRESULT
    93 FrameworkView::Uninitialize()
    94 {
    95   return S_OK;
    96 }
    98 HRESULT
    99 FrameworkView::Load(HSTRING aEntryPoint)
   100 {
   101   return S_OK;
   102 }
   104 // called by winrt on startup
   105 HRESULT
   106 FrameworkView::Run()
   107 {
   108   LogFunction();
   110   // Initialize XPCOM, create mWidget and go! We get a
   111   // callback in MetroAppShell::Run, in which we kick
   112   // off normal browser execution / event dispatching.
   113   mMetroApp->Run();
   115   // Gecko is completely shut down at this point.
   116   WinUtils::Log("Exiting FrameworkView::Run()");
   118   WindowsDeleteString(sActivationURI);
   119   return S_OK;
   120 }
   122 HRESULT
   123 FrameworkView::ActivateView()
   124 {
   125   LogFunction();
   127   UpdateWidgetSizeAndPosition();
   129   nsIntRegion region(nsIntRect(0, 0, mWindowBounds.width, mWindowBounds.height));
   130   mWidget->Paint(region);
   132   // Activate the window, this kills the splash screen
   133   mWindow->Activate();
   135   ProcessLaunchArguments();
   136   AddEventHandlers();
   137   SetupContracts();
   139   return S_OK;
   140 }
   142 HRESULT
   143 FrameworkView::SetWindow(ICoreWindow* aWindow)
   144 {
   145   LogFunction();
   147   NS_ASSERTION(!mWindow, "Attempting to set a window on a view that already has a window!");
   148   NS_ASSERTION(aWindow, "Attempting to set a null window on a view!");
   150   mWindow = aWindow;
   151   UpdateLogicalDPI();
   152   return S_OK;
   153 }
   155 ////////////////////////////////////////////////////
   156 // FrameworkView impl.
   158 void
   159 FrameworkView::AddEventHandlers() {
   160   NS_ASSERTION(mWindow, "SetWindow must be called before AddEventHandlers!");
   161   NS_ASSERTION(mWidget, "SetWidget must be called before AddEventHAndlers!");
   163   mMetroInput = Make<MetroInput>(mWidget.Get(),
   164                                  mWindow.Get());
   166   mWindow->add_VisibilityChanged(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CVisibilityChangedEventArgs>(
   167     this, &FrameworkView::OnWindowVisibilityChanged).Get(), &mWindowVisibilityChanged);
   168   mWindow->add_Activated(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowActivatedEventArgs_t>(
   169     this, &FrameworkView::OnWindowActivated).Get(), &mWindowActivated);
   170   mWindow->add_SizeChanged(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t>(
   171     this, &FrameworkView::OnWindowSizeChanged).Get(), &mWindowSizeChanged);
   173   mWindow->add_AutomationProviderRequested(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CAutomationProviderRequestedEventArgs_t>(
   174     this, &FrameworkView::OnAutomationProviderRequested).Get(), &mAutomationProviderRequested);
   176   HRESULT hr;
   177   ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> dispProps;
   178   if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), dispProps.GetAddressOf()))) {
   179     hr = dispProps->add_LogicalDpiChanged(Callback<ABI::Windows::Graphics::Display::IDisplayPropertiesEventHandler, FrameworkView>(
   180       this, &FrameworkView::OnLogicalDpiChanged).Get(), &mDisplayPropertiesChanged);
   181     LogHRESULT(hr);
   182   }
   184   ComPtr<ABI::Windows::UI::ViewManagement::IInputPaneStatics> inputStatic;
   185   if (SUCCEEDED(hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), inputStatic.GetAddressOf()))) {
   186     ComPtr<ABI::Windows::UI::ViewManagement::IInputPane> inputPane;
   187     if (SUCCEEDED(inputStatic->GetForCurrentView(inputPane.GetAddressOf()))) {
   188       inputPane->add_Hiding(Callback<__FITypedEventHandler_2_Windows__CUI__CViewManagement__CInputPane_Windows__CUI__CViewManagement__CInputPaneVisibilityEventArgs_t>(
   189         this, &FrameworkView::OnSoftkeyboardHidden).Get(), &mSoftKeyboardHidden);
   190       inputPane->add_Showing(Callback<__FITypedEventHandler_2_Windows__CUI__CViewManagement__CInputPane_Windows__CUI__CViewManagement__CInputPaneVisibilityEventArgs_t>(
   191         this, &FrameworkView::OnSoftkeyboardShown).Get(), &mSoftKeyboardShown);
   192     }
   193   }
   194 }
   196 // Called by MetroApp
   197 void
   198 FrameworkView::Shutdown()
   199 {
   200   LogFunction();
   201   mShuttingDown = true;
   203   if (mWindow && mWindowVisibilityChanged.value) {
   204     mWindow->remove_VisibilityChanged(mWindowVisibilityChanged);
   205     mWindow->remove_Activated(mWindowActivated);
   206     mWindow->remove_Closed(mWindowClosed);
   207     mWindow->remove_SizeChanged(mWindowSizeChanged);
   208     mWindow->remove_AutomationProviderRequested(mAutomationProviderRequested);
   209   }
   211   ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> dispProps;
   212   if (mDisplayPropertiesChanged.value &&
   213       SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), dispProps.GetAddressOf()))) {
   214     dispProps->remove_LogicalDpiChanged(mDisplayPropertiesChanged);
   215   }
   217   ComPtr<ABI::Windows::UI::ViewManagement::IInputPaneStatics> inputStatic;
   218   if (mSoftKeyboardHidden.value &&
   219       SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), inputStatic.GetAddressOf()))) {
   220     ComPtr<ABI::Windows::UI::ViewManagement::IInputPane> inputPane;
   221     if (SUCCEEDED(inputStatic->GetForCurrentView(inputPane.GetAddressOf()))) {
   222       inputPane->remove_Hiding(mSoftKeyboardHidden);
   223       inputPane->remove_Showing(mSoftKeyboardShown);
   224     }
   225   }
   227   if (mAutomationProvider) {
   228     ComPtr<IUIABridge> provider;
   229     mAutomationProvider.As(&provider);
   230     if (provider) {
   231       provider->Disconnect();
   232     }
   233   }
   234   mAutomationProvider = nullptr;
   236   mMetroInput = nullptr;
   237   delete sSettingsArray;
   238   sSettingsArray = nullptr;
   239   mWidget = nullptr;
   240   mMetroApp = nullptr;
   241   mWindow = nullptr;
   242 }
   244 void
   245 FrameworkView::SetCursor(CoreCursorType aCursorType, DWORD aCustomId)
   246 {
   247   if (mShuttingDown) {
   248     return;
   249   }
   250   NS_ASSERTION(mWindow, "SetWindow must be called before SetCursor!");
   251   ComPtr<ABI::Windows::UI::Core::ICoreCursorFactory> factory;
   252   AssertHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), factory.GetAddressOf()));
   253   ComPtr<ABI::Windows::UI::Core::ICoreCursor> cursor;
   254   AssertHRESULT(factory->CreateCursor(aCursorType, aCustomId, cursor.GetAddressOf()));
   255   mWindow->put_PointerCursor(cursor.Get());
   256 }
   258 void
   259 FrameworkView::ClearCursor()
   260 {
   261   if (mShuttingDown) {
   262     return;
   263   }
   264   NS_ASSERTION(mWindow, "SetWindow must be called before ClearCursor!");
   265   mWindow->put_PointerCursor(nullptr);
   266 }
   268 void
   269 FrameworkView::UpdateLogicalDPI()
   270 {
   271   ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> dispProps;
   272   HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(),
   273                                     dispProps.GetAddressOf());
   274   AssertHRESULT(hr);
   275   FLOAT value;
   276   AssertHRESULT(dispProps->get_LogicalDpi(&value));
   277   SetDpi(value);
   278 }
   280 void
   281 FrameworkView::GetBounds(nsIntRect &aRect)
   282 {
   283   // May be called by compositor thread
   284   if (mShuttingDown) {
   285     return;
   286   }
   287   aRect = mWindowBounds;
   288 }
   290 void
   291 FrameworkView::UpdateWidgetSizeAndPosition()
   292 {
   293   if (mShuttingDown)
   294     return;
   296   NS_ASSERTION(mWindow, "SetWindow must be called before UpdateWidgetSizeAndPosition!");
   297   NS_ASSERTION(mWidget, "SetWidget must be called before UpdateWidgetSizeAndPosition!");
   299   UpdateBounds();
   300   mWidget->Move(0, 0);
   301   mWidget->Resize(0, 0, mWindowBounds.width, mWindowBounds.height, true);
   302   mWidget->SizeModeChanged();
   303 }
   305 bool
   306 FrameworkView::IsEnabled() const
   307 {
   308   return mWinActiveState;
   309 }
   311 bool
   312 FrameworkView::IsVisible() const
   313 {
   314   // we could check the wnd in MetroWidget for this, but
   315   // generally we don't let nsIWidget control visibility
   316   // or activation.
   317   return mWinVisible;
   318 }
   320 void FrameworkView::SetDpi(float aDpi)
   321 {
   322   if (aDpi != mDPI) {
   323     LogFunction();
   325     mDPI = aDpi;
   327     // notify the widget that dpi has changed
   328     if (mWidget) {
   329       mWidget->ChangedDPI();
   330       UpdateBounds();
   331     }
   332   }
   333 }
   335 void
   336 FrameworkView::UpdateBounds()
   337 {
   338   if (!mWidget)
   339     return;
   341   RECT winRect;
   342   GetClientRect(mWidget->GetICoreWindowHWND(), &winRect);
   344   mWindowBounds = nsIntRect(winRect.left,
   345                             winRect.top,
   346                             winRect.right - winRect.left,
   347                             winRect.bottom - winRect.top);
   348 }
   350 void
   351 FrameworkView::SetWidget(MetroWidget* aWidget)
   352 {
   353   NS_ASSERTION(!mWidget, "Attempting to set a widget for a view that already has a widget!");
   354   NS_ASSERTION(aWidget, "Attempting to set a null widget for a view!");
   355   LogFunction();
   356   mWidget = aWidget;
   357   mWidget->FindMetroWindow();
   358   UpdateBounds();
   359 }
   361 ////////////////////////////////////////////////////
   362 // Event handlers
   364 void
   365 FrameworkView::SendActivationEvent() 
   366 {
   367   if (mShuttingDown) {
   368     return;
   369   }
   370   NS_ASSERTION(mWindow, "SetWindow must be called before SendActivationEvent!");
   371   mWidget->Activated(mWinActiveState);
   372   if (mWinActiveState) {
   373     UpdateWidgetSizeAndPosition();
   374   }
   375   EnsureAutomationProviderCreated();
   376 }
   378 HRESULT
   379 FrameworkView::OnWindowVisibilityChanged(ICoreWindow* aWindow,
   380                                          IVisibilityChangedEventArgs* aArgs)
   381 {
   382   // If we're visible, or we can't determine if we're visible, just store
   383   // that we are visible.
   384   boolean visible;
   385   mWinVisible = FAILED(aArgs->get_Visible(&visible)) || visible;
   386   return S_OK;
   387 }
   389 HRESULT
   390 FrameworkView::OnActivated(ICoreApplicationView* aApplicationView,
   391                            IActivatedEventArgs* aArgs)
   392 {
   393   LogFunction();
   395   if (mShuttingDown) {
   396     return S_OK;
   397   }
   399   aArgs->get_PreviousExecutionState(&sPreviousExecutionState);
   400   bool startup = sPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_Terminated ||
   401                  sPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_ClosedByUser ||
   402                  sPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_NotRunning;
   403   ProcessActivationArgs(aArgs, startup);
   404   return S_OK;
   405 }
   407 HRESULT
   408 FrameworkView::OnSoftkeyboardHidden(IInputPane* aSender,
   409                                     IInputPaneVisibilityEventArgs* aArgs)
   410 {
   411   LogFunction();
   412   sKeyboardIsVisible = false;
   413   memset(&sKeyboardRect, 0, sizeof(Rect));
   414   MetroUtils::FireObserver("metro_softkeyboard_hidden");
   415   aArgs->put_EnsuredFocusedElementInView(true);
   416   return S_OK;
   417 }
   419 HRESULT
   420 FrameworkView::OnSoftkeyboardShown(IInputPane* aSender,
   421                                    IInputPaneVisibilityEventArgs* aArgs)
   422 {
   423   LogFunction();
   424   sKeyboardIsVisible = true;
   425   aSender->get_OccludedRect(&sKeyboardRect);
   426   MetroUtils::FireObserver("metro_softkeyboard_shown");
   427   aArgs->put_EnsuredFocusedElementInView(true);
   428   return S_OK;
   429 }
   431 HRESULT
   432 FrameworkView::OnWindowSizeChanged(ICoreWindow* aSender, IWindowSizeChangedEventArgs* aArgs)
   433 {
   434   LogFunction();
   435   UpdateWidgetSizeAndPosition();
   436   return S_OK;
   437 }
   439 HRESULT
   440 FrameworkView::OnWindowActivated(ICoreWindow* aSender, IWindowActivatedEventArgs* aArgs)
   441 {
   442   LogFunction();
   443   if (!mWidget) {
   444     return S_OK;
   445   }
   446   CoreWindowActivationState state;
   447   aArgs->get_WindowActivationState(&state);
   448   mWinActiveState = !(state == CoreWindowActivationState::CoreWindowActivationState_Deactivated);
   449   SendActivationEvent();
   450   return S_OK;
   451 }
   453 HRESULT
   454 FrameworkView::OnLogicalDpiChanged(IInspectable* aSender)
   455 {
   456   LogFunction();
   457   UpdateLogicalDPI();
   458   if (mWidget) {
   459     mWidget->Invalidate();
   460   }
   461   return S_OK;
   462 }
   464 bool
   465 FrameworkView::EnsureAutomationProviderCreated()
   466 {
   467 #ifdef ACCESSIBILITY
   468   if (!mWidget || mShuttingDown)
   469     return false;
   471   if (mAutomationProvider) {
   472     return true;
   473   }
   475   Accessible *rootAccessible = mWidget->GetRootAccessible();
   476   if (rootAccessible) {
   477     IInspectable* inspectable;
   478     HRESULT hr;
   479     AssertRetHRESULT(hr = UIABridge_CreateInstance(&inspectable), hr); // Addref
   480     IUIABridge* bridge = nullptr;
   481     inspectable->QueryInterface(IID_IUIABridge, (void**)&bridge); // Addref
   482     if (bridge) {
   483       bridge->Init(this, mWindow.Get(), (ULONG)rootAccessible);
   484       mAutomationProvider = inspectable;
   485       inspectable->Release();
   486       return true;
   487     }
   488   }
   489 #endif
   490   return false;
   491 }
   493 HRESULT
   494 FrameworkView::OnAutomationProviderRequested(ICoreWindow* aSender,
   495                                              IAutomationProviderRequestedEventArgs* aArgs)
   496 {
   497   LogFunction();
   498   if (!EnsureAutomationProviderCreated())
   499     return E_FAIL;
   500   HRESULT hr = aArgs->put_AutomationProvider(mAutomationProvider.Get());
   501   if (FAILED(hr)) {
   502     WinUtils::Log("put failed? %X", hr);
   503   }
   504   return S_OK;
   505 }
   507 } } }

mercurial