Thu, 15 Jan 2015 15:59:08 +0100
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 } } }