-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement UiaConnectionBoundObject in abstraction API #95
base: main
Are you sure you want to change the base?
Implement UiaConnectionBoundObject in abstraction API #95
Conversation
* Add a 'Set' method to AutomationRemoteExtensionTarget. All AutomationRemoteObject subclasses require this but seemed to have been left out of the original implementation. * Add 'IsExtensionTarget' and 'AsExtensionTarget' methods to AutomationRemoteAnyObject to enable check / casting to AutomationRemoteExtensionTarget. * Add a deprecation comment to AutomationRemoteExtensionTarget::IsExtensionTarget. I think this was a misunderstanding of where this needed to be.
* Add a UiaTypeBaseWithExtensionSupport template class which subclasses UiaTypeBase and adds IsExtensionSupported and CallExtension methods, moved from UiaElement. * UiaElement and UiaTextRange now inherit from UiaTypeBaseWithExtensionSupport rather than UiaTypeBase. This makes IsExtensionSupported and CallExtension methods again available on UiaElement, but also now UiaTextRange. * Add a new UiaConnectionBoundObject class, which inherits from UiaTypeBaseWithExtensionSupport. It contains no other real features of its own a part from being constructable from / convertable to AutomationRemoteExtensionTarget remotely and IUnknown locally. This can be used as a generic connection-bound object, such as sometimes returned from CallExtension, which represents a custom extension pattern. Previously the caller had to treat the object as a UiaElement, even though it was not really.
I ran the functional tests to ensure nothing breaks but please mention how these changes were tested. |
Hi @michaelDCurran , I also have a similar question as @rahulkhanna1605. |
Am on leave until 25 July. I'll fill in that detail when I get back.
|
The only testing I have done is:
|
@@ -144,9 +144,10 @@ namespace Microsoft.UI.UIAutomation | |||
|
|||
unsealed runtimeclass AutomationRemoteExtensionTarget : AutomationRemoteObject | |||
{ | |||
AutomationRemoteBool IsExtensionTarget(); | |||
/* Deprecated */ AutomationRemoteBool IsExtensionTarget(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be marked as deprecated? @mavangur could you also confirm if this would be required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know when this got deprecated Rahul, At the time I introduced this API, we are in a view that it would be useful. I don't know who marked it deprecated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Sorry for parachuting in, just hoping to provide some historic context :))
Is<Type>
and As<Type>
methods should be on AutomationRemoteAnyObject
, since that's what facilitates "casting" between the generic "any" type and a "concrete" type. Basically it helps "inspect" the actual type and convert between them safely. (Sort of like a QI...)
This method was originally added to AutomationRemoteExtensionTarget
where it doesn't do much good -- it's already representing a specific type. This PR is moving it to the right place and deprecating this one, presumably so that if anyone took a dependency on this so far for some reason they're not immediately broken.
Consider just introducing a (technically) breaking change and removing this, though.
Mick also did have a question in the PR:
Can someone please verify that the IsExtensionTarget op code in the remote ops VM really does ask if an anyObject is an extensionTarget (similar to all the other Is* op codes)?
I don't know for sure - I no longer have access to the Windows code base :( - but I would assume that it'd follow the same pattern as the others; I think someone would've had to go out of their way to implement it any differently given how things were originally structured.
cc @michaelDCurran and @beweedon |
Partially implements #93
Background
In pr #84 I added initial support for checking for and calling custom extensions to UiaElement through IsExtensionSupported and CallExtension methods.
However, this was somewhat incomplete, as UI Automation remote operations also allow for checking for and calling extensions on text ranges, and generic connection-bound objects (which currently have no representation in the abstraction library at all).
The general pattern for custom extensions is usually:
The work around would be to use a UiaElement in place of the connection-bound object, as that is the only class that implemented CallExtension. This is both semantically incorrect and dangerous (as calling any of the other UiaElement methods would fail or may crash the client.
PR #92 added support for connection-bound objects to the lower-level winrt library through the addition of the AutomationRemoteExtensionTarget class.
However, this also was slightly incomplete as AutomationRemoteExtensionTarget was missing a
Set
method, and AutomationRemoteAnyObject was missing IsExtensionTarget and AsExtensionTarget methods.Description of changes
This new PR enhances the abstraction library, adding a new UiaConnectionBoundObject class, which exposes IsExtensionSupported and CallExtension, and should be used where a connection-bound object is required, I.e. represents a custom pattern object.
This PR also exposes IsExtensionSupported and CallExtension on UiaTextRange, completing all the places where custom extensions are supported.
The specific changes to the abstraction library are as follows:
The above work also required addressing the limitations of the AutomationRemoteExtensionTarget implementation in the winrt library.
The specific changes to the winrt library are as follows:
Testing
I have not yet added tests for these changes. I should be able to add some general tests for UiaConnectionBoundObject in regards to construction / conversions. But as mentioned in previous PRs, there is currently no simple way to test IsExtesnionSupported / CallExtension as this requires a provider that has implemented these.
Questions / thoughts
*this
parameter on result.Set to AutomationRemoteElement, otherwise I would get an ambiguous overload error when compiling. This was caused due to me adding aSet
method to AutomationRemoteExtensionTarget, which is inherited by AutomationRemoteElement. I don't entirely understand why the static_cast is necessary or why the compiler is clearly converting to a base class when searching for the correct overload ofSet
. Did I address this issue in the right way?