Skip to content

feat: support Duo hinge control and secondary display capture - #1287

Merged
KazuCocoa merged 12 commits into
masterfrom
fix/duo-display-app-detection
Oct 4, 2026
Merged

KazuCocoa merged 12 commits into
masterfrom
fix/duo-display-app-detection

Conversation

@KazuCocoa

@KazuCocoa KazuCocoa commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

On an open iPhone Duo simulator, selecting the inner currentDisplayId still allowed the main-screen point lookup to choose the outer SpringBoard, while MJPEG and XCTest recordings remained fixed to the main display. This change makes secondary-display sessions usable for app discovery and capture, and adds hinge angle reading and simulated hinge events. Availability is checked at runtime on both simulators and physical devices; there is no fixed model or Simulator-build restriction. We have tested Duo-specific behavior only on the simulator, not on a real Duo device, and are awaiting feedback on whether these features work on real Duo devices as well.

  • Skip XCTest's main-display-only active-app point lookup when a secondary display is selected. Existing active-app fallback and explicit app preferences remain in place; this is not display-specific app filtering.
  • Follow currentDisplayId for MJPEG frames and newly started XCTest recordings. An existing stream follows setting changes; a recording keeps its initial target. Invalid selections fail capture/recording and pause MJPEG delivery.
  • Add GET and POST /session/:sessionId/wda/device/hingeAngle, also available without a session as /wda/device/hingeAngle. GET checks for an available hinge and the CoreMotion reading APIs. POST accepts finite angles in [0, 180], checks for an available hinge and the required IOKit functions, and sends an IOCF-serialized vendor HID payload. Those checks permit an injection attempt; they do not guarantee that the device accepts the event.
  • Document asynchronous hinge transitions, explicit display selection, and app-selection limitations.

Companion driver command: appium/appium-xcuitest-driver#3001 (draft until the WDA release is available).

Based on current master (9d1d17dd). Complements #1269 without incorporating or duplicating its W3C action changes. Unset currentDisplayId still means the main display; automatic selection after folding is not introduced.

Validation

Xcode 27.1 / iOS 27.1 Duo:

  • All 10 screen integration tests pass, including secondary-display point lookup, recording display IDs, and unavailable displays.
  • Safari is selected with defaultActiveApplication=auto on the inner display; source/window size become 951×669. Closed/main display is 466×678.
  • A single MJPEG connection switches between main and inner displays in both directions. Recording start/stop succeeds on both selections; native request tests independently assert recording screen IDs.
  • Companion XCUITest driver mobile: setSimulatedHingeAngle executes 0 → 90 → 180 → 0 → 90.5 degrees. Independent devicectl device motion hinge-angle readings confirm every target, with matching Safari layout changes and screenshots. No UI actions are used for this sequence.

iPhone 17 / iOS 26.5:

  • 171 native unit tests pass before hinge addition; the five custom-command tests pass afterward, including the two added hinge validation/unsupported-device tests.
  • Screen suite passes (9 pass, secondary-display test skipped).

WDA JavaScript: build, lint, and all 77 tests pass. iOS and tvOS simulator runner builds pass; the final iOS build has no newly introduced source warnings.

Limitations: Duo display behavior and hinge operations have been tested on the iPhone Duo simulator. We have not had access to a physical Duo, so hinge readings, event acceptance, and display/layout behavior on that hardware remain unverified. CoreMotion loading and the presence of CMAngleManager were verified on a physical iPad mini, which reported no available hinge; this does not validate physical hinge operations. Event dispatch does not wait for the angle/layout transition. W3C coordinate actions still require #1269. The existing one-pixel inner screenshot rounding was observed and is unchanged.

We are awaiting real-device feedback to confirm whether hinge readings, hinge event injection, and secondary-display capture work on physical Duo devices as well. If you have access to a real Duo device, we would appreciate help testing these endpoints and reporting the observed behavior. Please include the device model, iOS/Xcode and WDA versions, requests and responses, and any angle or display/layout changes. Unsupported operations and successful responses with no observable change are useful reports too.

Comment thread WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h Outdated
Comment thread WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m Outdated
Comment thread WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m Outdated
Comment thread WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m Outdated
Comment thread WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.m
Comment thread README.md
@KazuCocoa
KazuCocoa marked this pull request as draft October 3, 2026 07:36
@KazuCocoa

Copy link
Copy Markdown
Member Author

(Changed to draft as still working/testing the basic behavior)

Comment thread WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.m
Comment thread WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m Outdated
@KazuCocoa
KazuCocoa marked this pull request as ready for review October 3, 2026 08:38
Comment thread docs/multiple-displays.md
Comment on lines +23 to +24
W3C coordinate actions require the separate display-aware actions support tracked
in [#1269](https://github.com/appium/WebDriverAgent/pull/1269).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the 1269, or #1288

@Dan-Maor

Dan-Maor commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator

Interesting, very curious regarding whether the IOHIDEvent angle synthesis works on real Duos.

I don’t have a physical iPhone Duo as of right now, but will be happy to review it and to run some simulator tests on Monday once I have access to my testing environment.

Comment thread docs/multiple-displays.md Outdated
#import "XCUIScreen.h"
#import <objc/message.h>

static NSArray<XCUIScreen *> *FBScreensForDevice(id device, NSError **error)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably makes sense to split display-related stuff and the hinge one

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you meant screensOrError, it is not hinge related for Duo. It exists since around Xcode 14 or 15 technically, so can be used for multiple screens over USB as well

@KazuCocoa

Copy link
Copy Markdown
Member Author

@Dan-Maor when you test out stuff, #1288 should help as well. The PR will fix interactions issue I found out

KazuCocoa added a commit that referenced this pull request Oct 3, 2026
Extract display-related changes from PR #1287 at 78b3de2. Keep hinge APIs and their dependencies in a separate branch.
KazuCocoa added a commit that referenced this pull request Oct 3, 2026
Extract hinge-related changes from PR #1287 at 78b3de2. Include physical iPad IOKit probe results and keep display capture changes separate.
@KazuCocoa
KazuCocoa force-pushed the fix/duo-display-app-detection branch from ff009cc to b03e7d8 Compare October 3, 2026 19:32
Comment thread docs/hinge-angle.md
`GET /wda/device/hingeAngle` and `POST /wda/device/hingeAngle`. They operate on
the device and do not require creating an Appium session first.

## Validation and feedback

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed appium/appium-xcuitest-driver#3001 side as well about this feedback

}
if (!XCUIDevice.sharedDevice.fb_canAttemptSimulatedHingeAngleInjection) {
return FBResponseWithStatus([FBCommandStatus unsupportedOperationErrorWithMessage:
@"Hinge angle injection requires an available hinge and the IOKit HID APIs" traceback:nil]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this message is too technical. Can we instead change it to something like, requires a compatible/foldable device?

Comment thread README.md Outdated
* Easy development cycle as it can be launched & debugged directly via Xcode
* Use [Mac2Driver](https://github.com/appium/appium-mac2-driver) to automate macOS apps

## Hinge angle

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part could be merged to "multiple displays" topic as they are interconnected

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense

@KazuCocoa

Copy link
Copy Markdown
Member Author

@Dan-Maor I'm going to merge this to proceed Duo testable. It is appreciated to test out something for Duo to find out potential issues 🙏

@KazuCocoa
KazuCocoa merged commit 76d6aa0 into master Oct 4, 2026
54 of 60 checks passed
@KazuCocoa
KazuCocoa deleted the fix/duo-display-app-detection branch October 4, 2026 07:13
github-actions Bot pushed a commit that referenced this pull request Oct 4, 2026
## [16.14.0](v16.13.6...v16.14.0) (2026-10-04)

### Features

* support Duo hinge control and secondary display capture ([#1287](#1287)) ([76d6aa0](76d6aa0))
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 16.14.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants