widget/windows/winrt/UIABridge.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 "UIABridge.h"
     7 #include "MetroUtils.h"
     8 #include "UIABridgePrivate.h"
     9 #include "MetroWidget.h"
    10 #include "WinUtils.h"
    12 #include <wrl.h>
    13 #include <OAIdl.h>
    14 #include <windows.graphics.display.h>
    16 #ifdef ACCESSIBILITY
    17 using namespace mozilla::a11y;
    18 #endif
    19 using namespace mozilla::widget;
    20 using namespace Microsoft::WRL;
    21 using namespace Microsoft::WRL::Wrappers;
    22 using namespace ABI::Windows::UI;
    23 using namespace ABI::Windows::UI::Core;
    24 using namespace ABI::Windows::Foundation;
    25 using namespace ABI::Windows::System;
    27 //#define DEBUG_BRIDGE
    28 #if !defined(DEBUG_BRIDGE)
    29 #undef LogThread
    30 #undef LogFunction
    31 #define LogThread() 
    32 #define LogFunction()
    33 #define BridgeLog(...)
    34 #else
    35 #define BridgeLog(...) WinUtils::Log(__VA_ARGS__)
    36 #endif
    38 #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
    39  const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
    40 MIDL_DEFINE_GUID(IID, IID_IUIABridge, 0xc78b35b5, 0x5db, 0x43aa, 0xae, 0x73, 0x94, 0xc2, 0x33, 0xa9, 0x3c, 0x98);
    42 namespace mozilla {
    43 namespace widget {
    44 namespace winrt {
    46 #define ProviderOptions_UseClientCoordinates (ProviderOptions)0x100
    48 static int gIDIndex = 2;
    49 ComPtr<IUIABridge> gProviderRoot = nullptr;
    50 static ComPtr<IUIAElement> gElement = nullptr;
    52 HRESULT
    53 UIABridge_CreateInstance(IInspectable **retVal)
    54 {
    55   HRESULT hr = E_OUTOFMEMORY;
    56   *retVal = nullptr;
    57   ComPtr<UIABridge> spProvider = Make<UIABridge>();
    58   if (spProvider != nullptr &&
    59       SUCCEEDED(hr = spProvider.Get()->QueryInterface(IID_PPV_ARGS(retVal))) &&
    60       SUCCEEDED(hr = spProvider.Get()->QueryInterface(IID_PPV_ARGS(&gProviderRoot)))) {
    61     return S_OK;
    62   }
    63   return hr;
    64 }
    66 HRESULT
    67 UIATextElement_CreateInstance(IRawElementProviderFragmentRoot* aRoot)
    68 {
    69   LogFunction();
    70   HRESULT hr = E_OUTOFMEMORY;
    71   ComPtr<UIATextElement> spProvider = Make<UIATextElement>();
    72   if (spProvider != nullptr &&
    73       SUCCEEDED(hr = spProvider.Get()->QueryInterface(IID_PPV_ARGS(&gElement)))) {
    74     spProvider->SetIndexID(gIDIndex++);
    75     return S_OK;
    76   }
    77   return hr;
    78 }
    80 // IUIABridge
    82 HRESULT
    83 UIABridge::Init(IInspectable* aView, IInspectable* aWindow, LONG_PTR aInnerPtr)
    84 {
    85   LogFunction();
    86   NS_ASSERTION(aView, "invalid framework view pointer");
    87   NS_ASSERTION(aWindow, "invalid window pointer");
    88   NS_ASSERTION(aInnerPtr, "invalid Accessible pointer");
    90 #if defined(ACCESSIBILITY)
    91   // init AccessibilityBridge and connect to accessibility
    92   mAccBridge = new AccessibilityBridge();
    93   if (!mAccBridge->Init(CastToUnknown(), (Accessible*)aInnerPtr)) {
    94     return E_FAIL;
    95   }
    97   aWindow->QueryInterface(IID_PPV_ARGS(&mWindow));
    99   if (FAILED(UIATextElement_CreateInstance(this)))
   100     return E_FAIL;
   102   mAccessible = (Accessible*)aInnerPtr;
   104   return S_OK;
   105 #endif
   106   return E_FAIL;
   107 }
   109 HRESULT
   110 UIABridge::Disconnect()
   111 {
   112   LogFunction();
   113 #if defined(ACCESSIBILITY)
   114   mAccBridge->Disconnect();
   115   mAccessible = nullptr;
   116 #endif
   117   mWindow = nullptr;
   118   gElement = nullptr;
   119   gProviderRoot = nullptr;
   120   return S_OK;
   121 }
   123 bool
   124 UIABridge::Connected()
   125 {
   126   return !!mAccessible;
   127 }
   129 // IUIAElement
   131 HRESULT
   132 UIABridge::SetFocusInternal(LONG_PTR aAccessible)
   133 {
   134   LogFunction();
   135   return S_OK;
   136 }
   138 HRESULT
   139 UIABridge::ClearFocus()
   140 {
   141   LogFunction();
   142   return S_OK;
   143 }
   145 static void
   146 DumpChildInfo(nsCOMPtr<nsIAccessible>& aChild)
   147 {
   148 #ifdef DEBUG
   149   if (!aChild) {
   150     return;
   151   }
   152   nsString str;
   153   aChild->GetName(str);
   154   BridgeLog("name: %ls", str.BeginReading());
   155   aChild->GetDescription(str);
   156   BridgeLog("description: %ls", str.BeginReading());
   157 #endif
   158 }
   160 static bool
   161 ChildHasFocus(nsCOMPtr<nsIAccessible>& aChild)
   162 {
   163   Accessible* access = (Accessible*)aChild.get();
   164   BridgeLog("Focus element flags: editable:%d focusable:%d readonly:%d",
   165     ((access->NativeState() & mozilla::a11y::states::EDITABLE) > 0),
   166     ((access->NativeState() & mozilla::a11y::states::FOCUSABLE) > 0),
   167     ((access->NativeState() & mozilla::a11y::states::READONLY) > 0));
   168   return (((access->NativeState() & mozilla::a11y::states::EDITABLE) > 0) &&
   169            ((access->NativeState() & mozilla::a11y::states::READONLY) == 0));
   170 }
   172 HRESULT
   173 UIABridge::FocusChangeEvent()
   174 {
   175   LogFunction();
   176   if (!Connected()) {
   177     return UIA_E_ELEMENTNOTAVAILABLE;
   178   }
   180   nsCOMPtr<nsIAccessible> child;
   181   mAccessible->GetFocusedChild(getter_AddRefs(child));
   182   if (!child) {
   183     return S_OK;
   184   }
   186   if (!ChildHasFocus(child)) {
   187     ComPtr<IUIAElement> element;
   188     gElement.As(&element);
   189     if (!element) {
   190       return S_OK;
   191     }
   192     element->ClearFocus();
   193     UiaRaiseAutomationEvent(this, UIA_AutomationFocusChangedEventId);
   194   }
   196   return S_OK;
   197 }
   199 // IRawElementProviderFragmentRoot
   201 HRESULT
   202 UIABridge::ElementProviderFromPoint(double x, double y, IRawElementProviderFragment ** retVal)
   203 {
   204   LogFunction();
   205   *retVal = nullptr;
   206   if (!Connected()) {
   207     return UIA_E_ELEMENTNOTAVAILABLE;
   208   }
   209   gElement.Get()->QueryInterface(IID_PPV_ARGS(retVal));
   210   return S_OK;
   211 }
   213 // Windows calls this looking for the current focus element. Windows
   214 // will call here before accessible sends us any observer events through
   215 // the accessibility bridge, so update child focus information.
   216 HRESULT
   217 UIABridge::GetFocus(IRawElementProviderFragment ** retVal)
   218 {
   219   LogFunction();
   220   if (!Connected()) {
   221     return UIA_E_ELEMENTNOTAVAILABLE;
   222   }
   224   nsCOMPtr<nsIAccessible> child;
   225   nsresult rv = mAccessible->GetFocusedChild(getter_AddRefs(child));
   226   if (!child) {
   227     BridgeLog("mAccessible->GetFocusedChild failed.");
   228     return S_OK;
   229   }
   231   DumpChildInfo(child);
   233   ComPtr<IUIAElement> element;
   234   gElement.As(&element);
   235   if (!element) {
   236     BridgeLog("gElement as IUIAElement failed.");
   237     return S_OK;
   238   }
   240   if (!ChildHasFocus(child)) {
   241     element->ClearFocus();
   242   } else {
   243     element->SetFocusInternal((LONG_PTR)child.get());
   244     element.Get()->QueryInterface(IID_PPV_ARGS(retVal));
   245   }
   247   return S_OK;
   248 }
   250 // IRawElementProviderFragment
   252 HRESULT
   253 UIABridge::Navigate(NavigateDirection direction, IRawElementProviderFragment ** retVal)
   254 {
   255   LogFunction();
   256   if (!Connected()) {
   257     return UIA_E_ELEMENTNOTAVAILABLE;
   258   }
   259   *retVal = nullptr;
   261   switch(direction) {
   262     case NavigateDirection_Parent:
   263     BridgeLog("UIABridge::Navigate NavigateDirection_Parent");
   264     break;
   265     case NavigateDirection_NextSibling:
   266     BridgeLog("UIABridge::Navigate NavigateDirection_NextSibling");
   267     break;
   268     case NavigateDirection_PreviousSibling:
   269     BridgeLog("UIABridge::Navigate NavigateDirection_PreviousSibling");
   270     break;
   271     case NavigateDirection_FirstChild:
   272     BridgeLog("UIABridge::Navigate NavigateDirection_FirstChild");
   273     gElement.Get()->QueryInterface(IID_PPV_ARGS(retVal));
   274     break;
   275     case NavigateDirection_LastChild:
   276     BridgeLog("UIABridge::Navigate NavigateDirection_LastChild");
   277     gElement.Get()->QueryInterface(IID_PPV_ARGS(retVal));
   278     break;
   279   }
   281   // For the other directions (parent, next, previous) the default of nullptr is correct
   282   return S_OK;
   283 }
   285 HRESULT
   286 UIABridge::GetRuntimeId(SAFEARRAY ** retVal)
   287 {
   288   LogFunction();
   289   if (!Connected()) {
   290     return UIA_E_ELEMENTNOTAVAILABLE;
   291   }
   293   int runtimeId[2] = { UiaAppendRuntimeId, 1 }; // always 1
   294   *retVal = SafeArrayCreateVector(VT_I4, 0, ARRAYSIZE(runtimeId));
   295   if (*retVal != nullptr) {
   296     for (long index = 0; index < ARRAYSIZE(runtimeId); ++index) {
   297       SafeArrayPutElement(*retVal, &index, &runtimeId[index]);
   298     }
   299   } else {
   300     return E_OUTOFMEMORY;
   301   }
   302   return S_OK;
   303 }
   305 HRESULT
   306 UIABridge::get_BoundingRectangle(UiaRect * retVal)
   307 {
   308   LogFunction();
   309   if (!Connected() || !mWindow) {
   310     return UIA_E_ELEMENTNOTAVAILABLE;
   311   }
   313   // returns logical pixels
   314   Rect bounds;
   315   mWindow->get_Bounds(&bounds);
   317   // we need to return physical pixels
   318   retVal->left = WinUtils::LogToPhys(bounds.X);
   319   retVal->top = WinUtils::LogToPhys(bounds.Y);
   320   retVal->width = WinUtils::LogToPhys(bounds.Width);
   321   retVal->height = WinUtils::LogToPhys(bounds.Height);
   323   return S_OK;
   324 }
   326 HRESULT
   327 UIABridge::GetEmbeddedFragmentRoots(SAFEARRAY ** retVal)
   328 {
   329   if (!Connected()) {
   330     return UIA_E_ELEMENTNOTAVAILABLE;
   331   }
   332   // doesn't apply according to msdn.
   333   *retVal = nullptr;
   334   return S_OK;
   335 }
   337 HRESULT
   338 UIABridge::SetFocus()
   339 {
   340   LogFunction();
   341   if (!Connected()) {
   342     return UIA_E_ELEMENTNOTAVAILABLE;
   343   }
   344   return S_OK;
   345 }
   347 HRESULT
   348 UIABridge::get_FragmentRoot(IRawElementProviderFragmentRoot ** retVal)
   349 {
   350   // we are the fragment root. Our children return us for this call.
   351   return QueryInterface(IID_PPV_ARGS(retVal));
   352 }
   354 // IRawElementProviderSimple
   356 HRESULT
   357 UIABridge::get_ProviderOptions(ProviderOptions * pRetVal)
   358 {
   359   LogFunction();
   360   if (!Connected()) {
   361     return E_FAIL;
   362   }
   363   *pRetVal = ProviderOptions_ServerSideProvider | 
   364              ProviderOptions_UseComThreading | 
   365              ProviderOptions_UseClientCoordinates;
   366   return S_OK;
   367 }
   369 HRESULT
   370 UIABridge::GetPatternProvider(PATTERNID patternId, IUnknown **ppRetVal)
   371 {
   372   LogFunction();
   373   BridgeLog("UIABridge::GetPatternProvider=%d", patternId);
   375   // The root window doesn't support any specific pattern
   376   *ppRetVal = nullptr;
   378   return S_OK;
   379 }
   381 HRESULT
   382 UIABridge::GetPropertyValue(PROPERTYID idProp, VARIANT * pRetVal)
   383 {
   384   pRetVal->vt = VT_EMPTY;
   386   switch (idProp) {
   387     case UIA_AutomationIdPropertyId:
   388     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_AutomationIdPropertyId");
   389     break;
   390     case UIA_ControlTypePropertyId:
   391     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_ControlTypePropertyId");
   392     break;
   393     case UIA_IsKeyboardFocusablePropertyId:
   394     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsKeyboardFocusablePropertyId");
   395     break;
   396     case UIA_IsContentElementPropertyId:
   397     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsContentElementPropertyId");
   398     break;
   399     case UIA_IsControlElementPropertyId:
   400     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsControlElementPropertyId");
   401     break;
   402     case UIA_IsEnabledPropertyId:
   403     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsEnabledPropertyId");
   404     break;
   405     case UIA_HasKeyboardFocusPropertyId:
   406     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_HasKeyboardFocusPropertyId");
   407     break;
   408     case UIA_NamePropertyId:
   409     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_NamePropertyId");
   410     break;
   411     case UIA_IsPasswordPropertyId:
   412     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsPasswordPropertyId");
   413     break;
   414     case UIA_NativeWindowHandlePropertyId:
   415     BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_NativeWindowHandlePropertyId");
   416     break;
   417     default:
   418     BridgeLog("UIABridge::GetPropertyValue: idProp=%d", idProp);
   419     break;
   420   }
   422   if (!Connected()) {
   423     return E_FAIL;
   424   }
   426   switch (idProp) {
   427     case UIA_AutomationIdPropertyId:
   428       pRetVal->bstrVal = SysAllocString(L"MozillaAccessibilityBridge0001");
   429       pRetVal->vt = VT_BSTR;
   430       break;
   432     case UIA_ControlTypePropertyId:
   433       pRetVal->vt = VT_I4;
   434       pRetVal->lVal = UIA_WindowControlTypeId;
   435       break;
   437     case UIA_IsKeyboardFocusablePropertyId:
   438     case UIA_IsContentElementPropertyId:
   439     case UIA_IsControlElementPropertyId:
   440     case UIA_IsEnabledPropertyId:
   441       pRetVal->boolVal = VARIANT_TRUE;
   442       pRetVal->vt = VT_BOOL;
   443       break;
   445     case UIA_HasKeyboardFocusPropertyId:
   446       pRetVal->vt = VT_BOOL;
   447       pRetVal->boolVal = VARIANT_FALSE;
   448       break;
   450     case UIA_NamePropertyId:
   451       pRetVal->bstrVal = SysAllocString(L"MozillaAccessibilityBridge");
   452       pRetVal->vt = VT_BSTR;
   453       break;
   455     case UIA_IsPasswordPropertyId:
   456       pRetVal->vt = VT_BOOL;
   457       pRetVal->boolVal = VARIANT_FALSE;
   458       break;
   460     case UIA_NativeWindowHandlePropertyId:
   461     pRetVal->vt = VT_I4;
   462     pRetVal->lVal = (LONG)MetroWidget::GetICoreWindowHWND();
   463     break;
   465     default:
   466       BridgeLog("UIABridge: Unhandled property");
   467       break;
   468   }
   469   return S_OK;
   470 }
   472 HRESULT
   473 UIABridge::get_HostRawElementProvider(IRawElementProviderSimple **ppRetVal)
   474 {
   475   // We only have this in the root bridge - this is our parent ICoreWindow.
   476   *ppRetVal = nullptr;
   477   if (mWindow != nullptr) {
   478     IInspectable *pHostAsInspectable = nullptr;
   479     if (SUCCEEDED(mWindow->get_AutomationHostProvider(&pHostAsInspectable))) {
   480       pHostAsInspectable->QueryInterface(ppRetVal);
   481       pHostAsInspectable->Release();
   482     }
   483   }
   484   return S_OK;
   485 }
   487 ///////////////////////////////////////////////////////////////////////////////
   488 // Element
   490 HRESULT
   491 UIATextElement::SetFocusInternal(LONG_PTR aAccessible)
   492 {
   493   LogFunction();
   494 #if defined(ACCESSIBILITY)
   495   NS_ASSERTION(mAccessItem, "Bad accessible pointer");
   496   if (mAccessItem == (nsIAccessible*)aAccessible) {
   497     return E_UNEXPECTED;
   498   }
   499   mAccessItem = (nsIAccessible*)aAccessible;
   500   return S_OK;
   501 #endif
   502   return E_FAIL;
   503 }
   505 HRESULT
   506 UIATextElement::ClearFocus()
   507 {
   508   LogFunction();
   509   mAccessItem = nullptr;
   510   return S_OK;
   511 }
   513 // IRawElementProviderFragment
   515 HRESULT
   516 UIATextElement::Navigate(NavigateDirection direction, IRawElementProviderFragment ** retVal)
   517 {
   518   LogFunction();
   520   *retVal = nullptr;
   521   switch(direction) {
   522     case NavigateDirection_Parent:
   523     gProviderRoot.Get()->QueryInterface(IID_PPV_ARGS(retVal));
   524     break;
   525     case NavigateDirection_NextSibling:
   526     break;
   527     case NavigateDirection_PreviousSibling:
   528     break;
   529     case NavigateDirection_FirstChild:
   530     break;
   531     case NavigateDirection_LastChild:
   532     break;
   533   }
   534   return S_OK;
   535 }
   537 HRESULT
   538 UIATextElement::GetRuntimeId(SAFEARRAY ** retVal)
   539 {
   540   LogFunction();
   541   int runtimeId[2] = { UiaAppendRuntimeId, mIndexID };
   542   *retVal = SafeArrayCreateVector(VT_I4, 0, ARRAYSIZE(runtimeId));
   543   if (*retVal != nullptr) {
   544     for (long index = 0; index < ARRAYSIZE(runtimeId); ++index) {
   545       SafeArrayPutElement(*retVal, &index, &runtimeId[index]);
   546     }
   547   } else {
   548     return E_OUTOFMEMORY;
   549   }
   550   return S_OK;
   551 }
   553 HRESULT
   554 UIATextElement::get_BoundingRectangle(UiaRect * retVal)
   555 {
   556   LogFunction();
   558   if (!mAccessItem) {
   559     return UIA_E_ELEMENTNOTAVAILABLE;
   560   }
   562   // bounds are in physical pixels
   563   int32_t docX = 0, docY = 0, docWidth = 0, docHeight = 0;
   564   mAccessItem->GetBounds(&docX, &docY, &docWidth, &docHeight);
   566   retVal->left = (float)docX;
   567   retVal->top = (float)docY;
   568   retVal->width = (float)docWidth;
   569   retVal->height = (float)docHeight;
   571   BridgeLog("get_BoundingRectangle: left=%d top=%d right=%d bottom=%d", docX, docY, docX + docWidth, docY + docHeight);
   572   return S_OK;
   573 }
   575 HRESULT
   576 UIATextElement::GetEmbeddedFragmentRoots(SAFEARRAY ** retVal)
   577 {
   578   *retVal = nullptr;
   579   return S_OK;
   580 }
   582 HRESULT
   583 UIATextElement::SetFocus()
   584 {
   585   LogFunction();
   586   return S_OK;
   587 }
   589 HRESULT
   590 UIATextElement::get_FragmentRoot(IRawElementProviderFragmentRoot ** retVal)
   591 {
   592   return gProviderRoot.Get()->QueryInterface(IID_PPV_ARGS(retVal));
   593 }
   595 // IRawElementProviderSimple
   597 HRESULT
   598 UIATextElement::get_ProviderOptions(ProviderOptions * pRetVal)
   599 {
   600   *pRetVal = ProviderOptions_ServerSideProvider | 
   601              ProviderOptions_UseComThreading | 
   602              ProviderOptions_UseClientCoordinates;
   603   return S_OK;
   604 }
   606 HRESULT
   607 UIATextElement::GetPatternProvider(PATTERNID patternId, IUnknown **ppRetVal)
   608 {
   609   LogFunction();
   610   BridgeLog("UIATextElement::GetPatternProvider=%d", patternId);
   612   // UIA_ValuePatternId - 10002
   613   // UIA_TextPatternId  - 10014
   614   // UIA_TextChildPatternId - 10029
   616   *ppRetVal = nullptr;
   617   if (patternId == UIA_TextPatternId) {
   618     BridgeLog("** TextPattern requested from element.");
   619     *ppRetVal = static_cast<ITextProvider*>(this);
   620     AddRef();
   621     return S_OK;
   622   } else if (patternId == UIA_ValuePatternId) {
   623     BridgeLog("** ValuePattern requested from element.");
   624     *ppRetVal = static_cast<IValueProvider*>(this);
   625     AddRef();
   626     return S_OK;
   627   }
   629   return S_OK;
   630 }
   632 HRESULT
   633 UIATextElement::GetPropertyValue(PROPERTYID idProp, VARIANT * pRetVal)
   634 {
   635   pRetVal->vt = VT_EMPTY;
   637   // native hwnd, we don't have one for elements
   638   if (idProp == 30020) {
   639     return S_OK;
   640   }
   642   switch (idProp) {
   643     case UIA_AutomationIdPropertyId:
   644     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_AutomationIdPropertyId");
   645     break;
   646     case UIA_ControlTypePropertyId:
   647     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_ControlTypePropertyId");
   648     break;
   649     case UIA_IsKeyboardFocusablePropertyId:
   650     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsKeyboardFocusablePropertyId");
   651     break;
   652     case UIA_IsContentElementPropertyId:
   653     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsContentElementPropertyId");
   654     break;
   655     case UIA_IsControlElementPropertyId:
   656     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsControlElementPropertyId");
   657     break;
   658     case UIA_IsEnabledPropertyId:
   659     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsEnabledPropertyId");
   660     break;
   661     case UIA_HasKeyboardFocusPropertyId:
   662     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_HasKeyboardFocusPropertyId");
   663     break;
   664     case UIA_NamePropertyId:
   665     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_NamePropertyId");
   666     break;
   667     case UIA_IsPasswordPropertyId:
   668     BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsPasswordPropertyId");
   669     break;
   670     default:
   671     BridgeLog("UIATextElement::GetPropertyValue: idProp=%d", idProp);
   672     break;
   673   }
   675   switch (idProp) {
   676     case UIA_AutomationIdPropertyId:
   677       pRetVal->bstrVal = SysAllocString(L"MozillaDocument0001");
   678       pRetVal->vt = VT_BSTR;
   679       break;
   681     case UIA_ControlTypePropertyId:
   682       pRetVal->vt = VT_I4;
   683       pRetVal->lVal = UIA_EditControlTypeId;
   684       break;
   686     case UIA_IsTextPatternAvailablePropertyId:
   687     case UIA_IsKeyboardFocusablePropertyId:
   688     case UIA_IsContentElementPropertyId:
   689     case UIA_IsControlElementPropertyId:
   690     case UIA_IsEnabledPropertyId:
   691       pRetVal->boolVal = VARIANT_TRUE;
   692       pRetVal->vt = VT_BOOL;
   693       break;
   695     case UIA_LocalizedControlTypePropertyId:
   696     case UIA_LabeledByPropertyId:
   697       break;
   699     case UIA_HasKeyboardFocusPropertyId: 
   700     {
   701       if (mAccessItem) {
   702         uint32_t state, extraState;
   703         if (NS_SUCCEEDED(mAccessItem->GetState(&state, &extraState)) &&
   704             (state & nsIAccessibleStates::STATE_FOCUSED)) {
   705           pRetVal->vt = VT_BOOL;
   706           pRetVal->boolVal = VARIANT_TRUE;
   707           return S_OK;
   708         }
   709       }
   710       pRetVal->vt = VT_BOOL;
   711       pRetVal->boolVal = VARIANT_FALSE;
   712       break;
   713     }
   715     case UIA_NamePropertyId:
   716       pRetVal->bstrVal = SysAllocString(L"MozillaDocument");
   717       pRetVal->vt = VT_BSTR;
   718       break;
   720     case UIA_IsPasswordPropertyId:
   721       pRetVal->vt = VT_BOOL;
   722       pRetVal->boolVal = VARIANT_FALSE;
   723       break;
   725     default:
   726       BridgeLog("UIATextElement: Unhandled property");
   727       break;
   728   }
   729   return S_OK;
   730 }
   732 HRESULT
   733 UIATextElement::get_HostRawElementProvider(IRawElementProviderSimple **ppRetVal)
   734 {
   735   *ppRetVal = nullptr;
   736   return S_OK;
   737 }
   739 // ITextProvider
   741 HRESULT
   742 UIATextElement::GetSelection(SAFEARRAY * *pRetVal)
   743 {
   744   LogFunction();
   745   return E_NOTIMPL;
   746 }
   748 HRESULT
   749 UIATextElement::GetVisibleRanges(SAFEARRAY * *pRetVal)
   750 {
   751   LogFunction();
   752   return E_NOTIMPL;
   753 }
   755 HRESULT
   756 UIATextElement::RangeFromChild(IRawElementProviderSimple *childElement, ITextRangeProvider **pRetVal)
   757 {
   758   LogFunction();
   759   return E_NOTIMPL;
   760 }
   762 HRESULT
   763 UIATextElement::RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal)
   764 {
   765   LogFunction();
   766   return E_NOTIMPL;
   767 }
   769 HRESULT
   770 UIATextElement::get_DocumentRange(ITextRangeProvider **pRetVal)
   771 {
   772   LogFunction();
   773   return E_NOTIMPL;
   774 }
   776 HRESULT
   777 UIATextElement::get_SupportedTextSelection(SupportedTextSelection *pRetVal)
   778 {
   779   LogFunction();
   780   return E_NOTIMPL;
   781 }
   783 // IValueProvider
   785 IFACEMETHODIMP
   786 UIATextElement::SetValue(LPCWSTR val)
   787 {
   788   LogFunction();
   789   return E_NOTIMPL;
   790 }
   792 IFACEMETHODIMP
   793 UIATextElement::get_Value(BSTR *pRetVal)
   794 {
   795   LogFunction();
   796   return E_NOTIMPL;
   797 }
   799 IFACEMETHODIMP
   800 UIATextElement::get_IsReadOnly(BOOL *pRetVal)
   801 {
   802   LogFunction();
   803   *pRetVal = FALSE;
   804   return S_OK;
   805 }
   807 } } }

mercurial