ScreenSync MCP guide

Testing Android Foldables & Adaptive Layouts with Claude Code

Automate Android foldable postures, tabletop mode, dual-pane adaptive layouts, and Jetpack WindowManager state transitions on real devices with Claude Code and ScreenSync MCP.

Testing Android Foldables & Adaptive Layouts with Claude Code

The rapid rise of foldable smartphones, dual-screen devices, and large-screen tablets has transformed the landscape of modern Android engineering. Hardware form factors such as the Google Pixel Fold, Samsung Galaxy Z Fold, Galaxy Z Flip, and OnePlus Open require applications to move beyond rigid, fixed-dimension mobile canvases. When a user unfolds an Android device from a compact outer cover screen into an expansive inner display, or props the device on a flat surface into tabletop posture, the operating system triggers dynamic runtime configuration changes without terminating the underlying activity. An application must reflow its composables dynamically across adaptive window size classes, handle physical hinge occlusion boundaries without clipping actionable controls, preserve user input across screen transitions, and maintain sub-100ms rendering responsiveness. However, traditional mobile quality assurance pipelines struggle with foldable automation. Physical testing requires laborious manual folding and unfolding, while cloud device farms often lack physical foldable hardware or sever streaming connections during display reconfiguration events. By bridging terminal-based AI coding agents like Claude Code with the Model Context Protocol (MCP) via ScreenSync MCP, engineering teams can automate hardware posture simulation, dual-pane adaptive layout validation, and Jetpack WindowManager verification directly on connected Android hardware.

Key Takeaways

  • Programmatic Posture Simulation: ScreenSync MCP enables Claude Code to toggle foldable postures—including FLAT, HALF_OPENED, and CLOSED—deterministically via Android Debug Bridge (ADB) without manual hardware manipulation.
  • Continuous Non-Invasive Screen Capture: Display frames stream natively through Android's MediaProjection API (Android 7.0+, zero root, zero ADB overhead), maintaining sub-100ms visual mirror latency even during dynamic display resolution changes.
  • Jetpack WindowManager Validation: Claude Code inspects FoldingFeature properties, including state, isSeparating, and bounds, verifying that composables position themselves relative to the physical hinge without clipping.
  • Dual Semantic and Pixel Inspection: The testing agent combines structural view hierarchies from get_ui_hierarchy with visual validation from get_latest_screenshot to confirm that multi-pane layouts reflow seamlessly between Compact, Medium, and Expanded window sizes.
  • Cover vs Inner Display Triage: Claude Code automates state preservation testing across display switches, confirming that text inputs, scroll positions, and video playback resume without data loss or layout drift.
  • Unified 226-Tool Verification Surface: ScreenSync MCP bridges 29 phone and desktop tools (12 control, 3 OS, 14 capture and telemetry) with 197 browser automation tools to evaluate complex multi-surface mobile workflows.

The Testing Bottleneck: Why Foldables and Adaptive Layouts Break Traditional QA

Automating foldable and adaptive Android testing fails in traditional QA environments because physical hinge transitions trigger complex runtime configuration shifts that synthetic emulators and cloud device farms cannot reliably orchestrate. When an app transitions between cover and inner screens, unhandled window metric updates cause activity restarts, touch target displacement, and visual clipping beneath the physical hinge.

In standard slab-phone Android architectures, screen dimensions remain largely immutable during a session, with rotation representing the only common runtime layout shift. Foldables dismantle this assumption by introducing dynamic multi-state display geometry:

  1. Dynamic Aspect Ratio Volatility: Unfolding a device transitions the viewport from a tall, narrow cover screen (e.g., 23:9 or 20:9 aspect ratio) to a near-square inner display (e.g., 6:5 or 4:3 aspect ratio). Hardcoded layout dimensions, fixed canvas sizes, and non-adaptive column layouts immediately clip or overflow.
  2. Physical Hinge Occlusion: Unlike standard display cutouts or notches, the physical folding hinge occupies a distinct spatial region (FoldingFeature.bounds) across the display panel. If a user interface places interactive triggers, input text fields, or critical confirmation buttons directly over the hinge fold line, the user experiences visual distortion or physical touch unresponsiveness.
  3. Tabletop and Flex Posture Modes: Propping a foldable device halfway open (between 80 and 110 degrees) triggers the HALF_OPENED posture state. The app must split its user interface cleanly across the horizontal hinge: placing media playback or camera viewfinders in the top vertical pane, while rendering interactive controls, scrubbers, or comment feeds in the bottom horizontal pane.
  4. Configuration Change Cascades: Transitioning between displays triggers smallestScreenWidthDp, screenSize, and screenLayout configuration updates. If the activity is not configured properly or fails to retain state via Jetpack Compose rememberSaveable or Android ViewModels, the activity restarts, wiping out unsaved form entries and resetting video buffers.

Traditional continuous integration pipelines rely either on headless JVM mocks (like Robolectric) or cloud-hosted device grids. JVM unit tests execute in a synthetic software environment that lacks the real Android display subsystem, ignoring physical WindowInsets and folding sensor hardware. Cloud device farms, on the other hand, rarely provide physical foldable devices due to high mechanical wear-and-tear costs, and their video streaming protocols often freeze or disconnect when an emulator display geometry changes dynamically.

ScreenSync MCP resolves this bottleneck by pairing Claude Code with local developer hardware over a high-speed local Model Context Protocol (MCP) server. ScreenSync MCP streams display frames using Android's native MediaProjection API, which dynamically adapts to display dimension changes with approximately 94 milliseconds median latency over local Wi-Fi or USB reverse tethering. Claude Code can issue low-level ADB commands to manipulate device posture sensors, verify UI hierarchy trees, and refactor adaptive composables in the project repository.

Foldable Verification Dimension In-Memory JVM Mocks (Robolectric) Cloud Device Farms (SauceLabs / BrowserStack) ScreenSync MCP + Claude Code (Hardware/Emulator)
Physical Posture Manipulation Simulated via software mocks only Unavailable or restricted to manual web clicks Automated via ADB device state commands (cmd device_state)
Hinge Occlusion Detection In-memory rectangle calculations Manual visual inspection via browser video Autonomous pixel check + semantic bounding boxes via MCP
Screen Streaming Resilience N/A (runs headlessly without video) High latency; streams often stutter or drop during resize High-speed MediaProjection (~94 ms latency) persists across resizes
Tabletop Layout Split Audit Unit assertions only; no visual verification Prone to false positives from delayed frame updates Instantaneous validation via get_ui_hierarchy and get_latest_screenshot
Activity Recreation Survival Synthetic lifecycle dispatch in JVM Difficult to isolate from network latency drops Precise testing with am force-stop and posture state commands
Repository Source Remediation Static test failures without remediation Manual developer triage required Claude Code inspects logs and updates Kotlin layouts in repo
Multi-Surface Coordination Isolated to single JVM process Fragmented across web and mobile services Unified 226 tools linking mobile, desktop, and web consoles

Architecture of Modern Android Adaptive Layouts: WindowManager, Postures, and Scaffolds

Modern Android adaptive architecture combines Jetpack WindowManager, WindowSizeClass breakpoints, and Compose Material 3 Adaptive scaffolds. Rather than targeting specific screen resolutions, applications observe dynamic window metrics and folding features, automatically reflowing between single-pane compact views and multi-pane list-detail or supporting-pane layouts.

Building resilient foldable applications requires decoupling layout architecture from physical pixel dimensions. Google's modern Android engineering standards define three distinct Window Size Classes based on available viewport width:

  • Compact (Width < 600dp): Standard smartphone cover screens and portrait-oriented slab devices. Optimal for single-column linear navigation, bottom navigation bars, and modal sheets.
  • Medium (Width 600dp to 839dp): Small tablets, unfolded foldable devices in portrait orientation, and large foldable cover screens. Optimal for navigation rails, two-pane layouts with collapsed secondary panels, and adaptive grids.
  • Expanded (Width >= 840dp): Unfolded large foldables (such as Pixel Fold and Galaxy Z Fold in landscape), large tablets, and desktop/Chromebook windows. Optimal for persistent multi-pane scaffolds (ListDetailPaneScaffold, SupportingPaneScaffold) and persistent navigation drawers.

The Jetpack WindowManager FoldingFeature Model

To support foldables, Android applications integrate the androidx.window:window library. Jetpack WindowManager queries the hardware display manager and provides reactive streams of WindowLayoutInfo. When a foldable device changes its physical posture, WindowLayoutInfo emits a FoldingFeature containing vital hardware metadata:

  1. State: Either FoldingFeature.State.FLAT (completely opened at 180 degrees) or FoldingFeature.State.HALF_OPENED (angled between ~80 and ~140 degrees, forming tabletop or book posture).
  2. Orientation: FoldingFeature.Orientation.HORIZONTAL (hinge runs left-to-right, typical for clamshell flip phones in tabletop mode) or FoldingFeature.Orientation.VERTICAL (hinge runs top-to-bottom, typical for book-style foldables).
  3. Occlusion Type: FoldingFeature.OcclusionType.FULL (a physical hinge separates two distinct screen panels, like the Surface Duo) or FoldingFeature.OcclusionType.NONE (a continuous flexible OLED screen folds across the hinge, like the Galaxy Z Fold).
  4. IsSeparating: A boolean flag indicating whether the hinge physically or visually splits the display canvas into two distinct functional surfaces. When isSeparating is true, applications must never place content across the hinge bounds.
  5. Bounds: An Android Rect detailing the exact pixel coordinates [left, top, right, bottom] occupied by the hinge mechanism.

The following production-grade Kotlin implementation illustrates how an adaptive Jetpack Compose screen utilizes ListDetailPaneScaffold and handles FoldingFeature bounds to prevent hinge occlusion:

package com.example.screensync.adaptive.ui

import android.graphics.Rect
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.adaptive.layout.*
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowLayoutInfo

/**
 * Production-grade adaptive layout utilizing Material 3 Adaptive ListDetailPaneScaffold.
 * Automatically adapts between single-pane mobile and dual-pane foldable/tablet layouts.
 */
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun AdaptiveCatalogScreen(
    windowLayoutInfo: WindowLayoutInfo?,
    modifier: Modifier = Modifier
) {
    val adaptiveInfo = currentWindowAdaptiveInfo()
    val navigator = rememberListDetailPaneScaffoldNavigator<Long>()

    // Extract active folding feature to avoid hinge occlusion
    val foldingFeature = windowLayoutInfo?.displayFeatures
        ?.filterIsInstance<FoldingFeature>()
        ?.firstOrNull()

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            AnimatedPane(modifier = Modifier.preferredWidth(360.dp)) {
                CatalogListPane(
                    selectedItemId = navigator.currentDestination?.contentKey,
                    onItemClick = { itemId ->
                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, itemId)
                    }
                )
            }
        },
        detailPane = {
            AnimatedPane(modifier = Modifier.fillMaxSize()) {
                val selectedId = navigator.currentDestination?.contentKey
                if (selectedId != null) {
                    CatalogDetailPane(
                        itemId = selectedId,
                        foldingFeature = foldingFeature,
                        onBack = { navigator.navigateBack() }
                    )
                } else {
                    EmptyDetailPlaceholder()
                }
            }
        },
        modifier = modifier.fillMaxSize()
    )
}

@Composable
fun CatalogDetailPane(
    itemId: Long,
    foldingFeature: FoldingFeature?,
    onBack: () -> Unit,
    modifier: Modifier = Modifier
) {
    // If the device is in tabletop mode with a horizontal hinge, partition the pane
    if (foldingFeature != null && 
        foldingFeature.state == FoldingFeature.State.HALF_OPENED && 
        foldingFeature.orientation == FoldingFeature.Orientation.HORIZONTAL) {

        Column(modifier = modifier.fillMaxSize()) {
            // Upper screen: Media/Preview canvas
            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxWidth()
                    .background(MaterialTheme.colorScheme.surfaceVariant)
            ) {
                MediaViewerSection(itemId = itemId)
            }

            // Spacer matching the exact physical hinge bounds
            Spacer(modifier = Modifier.height(16.dp))

            // Lower screen: Interactive controls and input forms
            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxWidth()
                    .padding(16.dp)
            ) {
                InteractiveControlsSection(itemId = itemId, onBack = onBack)
            }
        }
    } else {
        // Standard full-height detail pane
        StandardDetailLayout(itemId = itemId, onBack = onBack, modifier = modifier)
    }
}

When building apps with modern reactive UI toolchains, developers can apply testing Jetpack Compose apps with Claude Code and MCP to verify that composable state holders respond instantaneously to posture changes without state reset or screen flicker.

How ScreenSync MCP Bridges Claude Code to Foldable Device Control

ScreenSync MCP connects Claude Code to foldable hardware through decoupled media and device control architectures. Display frames stream continuously over local Wi-Fi or LAN via Android's MediaProjection API at approximately 94ms median latency, while low-level posture commands, screen resolution toggles, and view inspection execute deterministically over ADB.

Automating foldable interactions requires an AI agent to execute two complementary roles: perceiving dynamic visual and structural changes on screen, and driving hardware posture shifts programmatically. ScreenSync MCP accomplishes this through a dual-channel architecture:

  1. Real-Time Display Perception Plane: The ScreenSync MCP Android client (com.screensync.mcp, compatible with Android 7.0 and higher) captures the physical display buffer directly from Android's hardware compositor using the native MediaProjection API. When a device unfolds or switches displays, the MediaProjection virtual display automatically receives the new surface configuration and resizes its stream buffer. Screen frames are encoded and transmitted locally to the desktop hub running on Node.js 18+. Because streaming operates across the local subnet without intermediate cloud relays, frame latency remains low (~94 ms median), and video feeds never drop when display dimensions change.
  2. Hardware State and ADB Control Plane: Low-level device interactions—such as tapping buttons, typing text, querying accessibility nodes, and injecting posture shifts—route through Android Debug Bridge (ADB). Whether connected via certified USB cable or authenticated wireless debugging, the desktop hub translates Claude Code's JSON-RPC tool calls into deterministic shell commands.

Simulating Foldable Postures via ADB

Developers testing foldables on physical hardware or the Android Studio Foldable Emulator can command device states through Android's system device_state service. Claude Code issues these commands directly from the terminal or through ADB wrappers:

Foldable State Hardware Posture ADB Command Sequence WindowManager Event Triggered
CLOSED Cover Screen Active adb shell cmd device_state state 0 Display switches to outer screen; WindowSizeClass becomes Compact
HALF_OPENED Tabletop / Book Posture adb shell cmd device_state state 1 FoldingFeature.state becomes HALF_OPENED; isSeparating set to true
OPEN (FLAT) Unfolded Main Screen adb shell cmd device_state state 2 Display switches to inner screen; WindowSizeClass becomes Expanded
FLIPPED / TENT Outer Screen in Tent Mode adb shell cmd device_state state 3 Orientation locks; outer display activates in reverse angle
Custom Hinge Angle Angle Simulation (Emulator) adb shell cmd display set-posture 90 Simulates exact 90-degree angle for tabletop UI verification
Split-Screen Launch Multi-Window App Dock adb shell am start -n <pkg>/<act> --windowingMode 3 Launches app in secondary split-screen window
Reset Device State Restore Auto Sensors adb shell cmd device_state state reset Returns posture control to physical device sensors

To evaluate how layout rules behave across diverse hardware manufacturers, engineering teams can pair foldable testing with cross-device Android testing: triaging OEM layout fragmentation across Samsung One UI, Google Pixel, and Xiaomi displays.

The Complete 226-Tool Verification Ecosystem

ScreenSync MCP equips Claude Code with 226 tools across mobile and web environments:

  • 29 Phone & Desktop Tools: 12 control_* tools (control_tap, control_swipe, control_type, control_key, control_open_url, control_launch_app), 3 os_* tools (os_mouse_click, os_type, os_hotkey), and 14 capture and telemetry tools (get_latest_screenshot, get_ui_hierarchy, get_logcat, record_screen, get_device_status).
  • 197 Web Tools: The web_* suite operates through an authenticated Chrome/Edge browser extension, allowing Claude Code to drive live desktop browser tabs, inspect cloud administrative dashboards, and verify that mobile mutations synchronize across web consoles.

Step-by-Step Setup: Configuring Hardware, Local Hub, and Claude Code

Configuring ScreenSync MCP for foldable testing requires launching the desktop hub on Node.js 18, registering the stdio MCP server in Claude Code, and establishing device pairing over USB or wireless debugging. Establishing an ADB reverse socket ensures display frames stream continuously during dynamic screen dimension shifts.

Engineering teams can establish this automated testing environment on Windows, macOS, or Linux through five sequential steps:

Step 1: Workstation and Hardware Verification

Verify that your development environment satisfies the necessary baseline specifications:

  1. Host Workstation: Windows 10/11, macOS, or Linux running Node.js 18 or newer with Android Platform Tools adb available in your system PATH.
  2. Target Device: A physical foldable Android smartphone running Android 7.0 (API level 24) or higher, or an Android Studio Foldable Virtual Device (e.g., Pixel Fold or 7.6" Fold-in with outer display).
  3. Target Application: Debug build of your application compiled with Jetpack Compose Material 3 Adaptive and Jetpack WindowManager libraries.
  4. Local Subnet: Host workstation and Android device connected to the same local Wi-Fi or LAN network for initial pairing.

Step 2: Launch the ScreenSync MCP Desktop Hub

Download the desktop hub archive from ScreenSync MCP and unpack it to a permanent directory on your workstation. Launch the platform-specific hub starter script:

# On Windows (Command Prompt or PowerShell)
cd C:   ools\screensync-hub
.\start-hub.bat

# On macOS or Linux (Terminal)
cd ~/tools/screensync-hub
chmod +x start-hub.sh
./start-hub.sh

The desktop hub initializes an HTTP server on port 3000 to ingest low-latency MediaProjection video streams and prepares a JSON-RPC Model Context Protocol server over stdio. The terminal output displays your unique authentication token (SCREEN_SYNC_TOKEN) and an ASCII pairing code. For comprehensive initial configuration, refer to the official ScreenSync MCP setup documentation.

Step 3: Register ScreenSync MCP in Claude Code

Register the desktop hub with the Claude Code CLI in your terminal:

claude mcp add screensync node "/path/to/screensync-hub/screensync-hub.js"

If you are using Claude Desktop, open your claude_desktop_config.json configuration file (Settings > Developer > Edit Config) and add the server:

{
  "mcpServers": {
    "screensync": {
      "command": "node",
      "args": ["/path/to/screensync-hub/screensync-hub.js"],
      "env": {
        "SCREEN_SYNC_TOKEN": "your_secure_token_here"
      }
    }
  }
}

(Note: Claude Code, Claude Desktop, Cursor, and VS Code agent mode communicate via local stdio processes and are fully supported. ChatGPT's web application requires remote HTTPS endpoints and does not support local stdio MCP servers).

Step 4: Install the Android App and Authorize Permissions

On your physical Android smartphone or emulator:

  1. Download and install the free ScreenSync MCP application (com.screensync.mcp) from Google Play.
  2. Open the application. Allow mDNS discovery to automatically detect your desktop hub on the local Wi-Fi network, or scan the pairing QR code from the hub console.
  3. Tap Start Projection and confirm Android's native MediaProjection screen capture consent prompt.
  4. Enable Developer Options (Settings > About Phone, tap Build Number 7 times), enter Developer Options, and toggle USB Debugging or Wireless Debugging. If using wireless connections, review our guide on pairing Android wireless debugging to an MCP server without USB.
  5. Verify ADB connectivity by running adb devices in your workstation terminal.

Step 5: Configure Reverse Port Forwarding

To guarantee high-throughput streaming and prevent network timeouts during rapid display changes, configure USB reverse port forwarding:

adb reverse tcp:3000 tcp:3000

With reverse port forwarding active, MediaProjection frames stream directly through the physical USB cable to the hub's HTTP server, eliminating Wi-Fi packet jitter.

Practical QA Workflows: Posture Shifts, Hinge Occlusion, and Split-Screen Testing

Practical foldable QA workflows validate three core capabilities: tabletop mode posture splitting, state preservation across fold/unfold transitions, and multi-window split-screen resizing. Claude Code coordinates ADB posture toggles with UI hierarchy dumps and screenshot analysis to detect layout clipping and state loss.

Workflow 1: Validating Tabletop Mode in Media Players and Camera Apps

When a foldable device is bent into tabletop posture (HALF_OPENED), a media application must isolate video playback to the top half of the display while anchoring playback controls, scrubber sliders, and comment sections to the bottom half.

Developer Directive:
"Claude, launch our video streaming app com.example.screensync.player on the connected foldable device. Set the device posture to HALF_OPENED (tabletop mode). Verify that the video playback surface remains unobstructed in the upper pane and that playback controls render strictly in the lower pane without overlapping the hinge."

Execution Steps:

  1. Launch App: Claude Code calls control_launch_app with package com.example.screensync.player.
  2. Inject Tabletop Posture: Claude Code executes the device state command:
    adb shell cmd device_state state 1
  3. Extract Structural Nodes: Claude Code calls get_ui_hierarchy to inspect the accessibility node tree. The agent calculates element bounds:
    <node resource-id="com.example.screensync.player:id/video_surface" bounds="[0,0][1812,1024]" />
    <node resource-id="com.example.screensync.player:id/hinge_separator" bounds="[0,1024][1812,1120]" />
    <node resource-id="com.example.screensync.player:id/playback_controls" bounds="[0,1120][1812,2176]" />
  4. Visual Verification: Claude Code calls get_latest_screenshot to confirm that the video frame did not distort its aspect ratio and that no play/pause buttons are clipped by the physical hinge crease. When evaluating camera viewfinders in tabletop mode, teams can also leverage testing Android camera and CameraX with Claude Code and MCP.

Workflow 2: Testing Fold/Unfold Transitions and State Preservation

A frequent defect in foldable apps is loss of user state when transitioning from the compact cover screen to the unfolded main display.

Developer Directive:
"Claude, start with the device CLOSED. Launch com.example.screensync.form and type 'Foldable Form Test' into the notes field. Then, simulate unfolding the device to OPEN (state 2). Verify that the text remains populated in the unfolded dual-pane layout without resetting cursor position or restarting the activity."

Execution Steps:

  1. Set Initial Closed State:
    adb shell cmd device_state state 0
  2. Enter Data on Cover Screen: Claude Code calls control_type to input text into the form.
  3. Unfold Device:
    adb shell cmd device_state state 2
  4. Assert State Continuity: Claude Code queries get_ui_hierarchy. It confirms that the input field contains "Foldable Form Test" and verifies that a secondary detail pane has appeared alongside the list without triggering an activity restart in get_logcat. To understand why combining accessibility node attributes with visual frames prevents touch target drift during screen resizing, review why your AI agent needs the Android UI hierarchy.

Workflow 3: Multi-Window Split-Screen Resizing and Density Scaling

Foldables frequently operate in multi-window split-screen mode, where an app shares the screen with another application.

Developer Directive:
"Claude, launch our app in split-screen mode side-by-side with Chrome. Resize the split divider from a 50/50 ratio to a 70/30 ratio. Assert that our app reflows from Medium to Compact window size class without truncating text or dropping frame rates."

Execution Steps:

  1. Launch Split-Screen Mode:
    adb shell am start -n com.example.screensync.shop/.ui.MainActivity --windowingMode 3
  2. Drag Split-Screen Divider: Claude Code calls control_swipe across the window divider handle coordinates.
  3. Verify Layout Reflow: Claude Code calls get_ui_hierarchy and asserts that the navigation rail automatically collapsed into a bottom navigation bar as width dropped below 600dp.
Foldable QA Scenario ScreenSync MCP Tools Used Primary Assertion Mechanism Common Defect Detected
Tabletop Posture Split cmd device_state 1, get_ui_hierarchy Viewport bounds relative to hinge Media canvas rendered underneath physical hinge
Cover to Inner Unfold cmd device_state 2, get_latest_screenshot Visual layout reflow + state check Form input cleared due to activity restart
Hinge Occlusion Check get_ui_hierarchy, get_latest_screenshot Coordinate comparison against hinge Rect Confirm button positioned directly on hinge crease
Split-Screen Resizing control_swipe, get_ui_hierarchy WindowSizeClass breakpoint trigger Layout fails to collapse navigation rail into bottom bar
Rapid Fold Cycling Shell loop, get_logcat Logcat memory leak and crash audit WindowLayoutInfo callback leaks causing OOM crash
Camera Viewfinder Switch control_tap, get_latest_screenshot Preview aspect ratio verification Viewfinder stretched or inverted on inner sensor

Common Pitfalls and Diagnostics in Foldable Android Testing

Common pitfalls in foldable Android testing include unhandled activity restarts during display metric changes, touch target drift between cover and main displays, and placing interactive controls over the physical hinge. Claude Code diagnoses these issues by parsing logcat lifecycle events and analyzing structural node bounds.

1. The Activity Recreation Trap

By default, Android restarts the current Activity when configuration parameters change. If an application fails to declare configuration change filters in its manifest or fails to retain state properly, unfolding the phone triggers an activity teardown and rebuild:

D LifecycleMonitor: Lifecycle status change: com.example.screensync.MainActivity in state DESTROYED
D LifecycleMonitor: Lifecycle status change: com.example.screensync.MainActivity in state CREATED
D LifecycleMonitor: Lifecycle status change: com.example.screensync.MainActivity in state RESUMED

When Claude Code detects this lifecycle churn via get_logcat, it inspects AndroidManifest.xml and recommends handling configuration changes manually:

<activity
    android:name=".MainActivity"
    android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
    android:exported="true" />

Concurrently, Claude Code audits the Compose tree to ensure transient values use rememberSaveable rather than standard remember.

2. The Hinge Occlusion Bug

When developers position buttons using hardcoded margins or percentage-based weights, interactive components often land directly inside the physical hinge crease:

W LayoutValidator: Warning: Button 'btn_submit' bounds [890, 1000, 1100, 1080] intersects FoldingFeature bounds [900, 0, 960, 2176]

Claude Code identifies this clipping by comparing element bounds extracted from get_ui_hierarchy with the FoldingFeature.bounds rectangle, refactoring the composable to use Modifier.displayCutoutPadding() or dynamic hinge spacers.

3. Coordinate Scaling Drift

Outer cover screens and inner foldable displays typically possess completely different pixel densities (DPI) and physical dimensions. For instance, an outer screen might run at 1080x2092 (422 DPI), while the inner screen runs at 2208x1768 (374 DPI). If an automated testing harness relies on absolute pixel coordinates recorded on the cover screen, tap commands sent to the unfolded screen land on empty space. ScreenSync MCP avoids this drift because Claude Code targets UI elements dynamically via resource IDs and text labels extracted from live get_ui_hierarchy dumps before calculating tap centers.

Implementation Checklist for Foldable and Adaptive Android Testing

  • [ ] Verify that workstation runs Node.js 18+ with Android Platform Tools adb accessible in system PATH.
  • [ ] Unpack the ScreenSync MCP desktop hub and execute start-hub.bat (Windows) or start-hub.sh (macOS/Linux).
  • [ ] Register ScreenSync MCP in Claude Code CLI via claude mcp add screensync node "/path/to/screensync-hub.js".
  • [ ] Install the free ScreenSync MCP client (version 2.5.7+) on physical Android 7.0+ hardware from Google Play.
  • [ ] Pair the device and workstation over the local Wi-Fi subnet; complete mDNS discovery or scan the console QR code.
  • [ ] Authorize native MediaProjection display recording on the Android phone for low-latency (~94 ms) local screen mirroring.
  • [ ] Configure adb reverse tcp:3000 tcp:3000 over USB to guarantee uninterrupted frame streaming during display resizing.
  • [ ] Add androidx.window:window and androidx.compose.material3.adaptive:adaptive dependencies to build.gradle.kts.
  • [ ] Configure android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" to prevent unhandled activity death.
  • [ ] Verify that interactive controls maintain at least 48dp separation from FoldingFeature.bounds to avoid hinge occlusion.
  • [ ] Assert that Tabletop posture (HALF_OPENED) splits media previews and interactive controls cleanly across the horizontal hinge.
  • [ ] Validate that transitioning between CLOSED and OPEN states preserves all user form inputs and cursor positions without data loss.
Component Under Test Target Standard Verification Tool / Command Success Criteria
Posture Simulation State 0 (Closed) to State 2 (Open) adb shell cmd device_state state <id> Hardware display changes without crash
Tabletop Layout Split Half-Opened Mode get_ui_hierarchy & get_latest_screenshot Controls strictly in lower pane; zero hinge overlap
State Continuity Unfold Transition control_type & get_ui_hierarchy Text entries retained after screen switch
WindowSizeClass Breakpoints Compact / Medium / Expanded control_swipe (Split-Screen Resize) Navigation rail collapses to bottom bar under 600dp
Display Mirror Fidelity Sub-100ms Video Streaming adb reverse tcp:3000 tcp:3000 Stream survives display dimension switch (~94 ms)
Activity Lifecycle Zero Unexpected Restarts get_logcat No DESTROYED -> CREATED cycle on unfold
Hinge Safe Areas Zero Element Clipping get_ui_hierarchy coordinate audit No interactive nodes intersect hinge Rect
Multi-Surface Coordination Mobile to Web Data Sync 29 Mobile Tools + 197 Browser Tools Mobile order updates reflect in web admin console

Conclusion

Automating Android foldable and adaptive layout testing with Claude Code and ScreenSync MCP eliminates the brittle manual verification routines that have historically held back large-screen mobile software engineering. By decoupling hardware-accelerated MediaProjection screen capture from deterministic ADB posture simulation over local physical links, engineering teams can validate tabletop mode partitioning, hinge occlusion avoidance, and state preservation in seconds. To expand your automated mobile test suite across diverse hardware components, discover what an Android screen MCP server is.

ScreenSync MCP provides developer automation tools including the ScreenSync MCP Android app, ScreenSync MCP desktop hub, and ScreenSync MCP browser extension for engineering teams worldwide. Explore our comprehensive technical documentation at screensyncmcp.tech, contact our engineering group directly at [email protected], and install the mobile app from ScreenSync MCP on Google Play to start automating real physical Android hardware today.

FAQ

Questions, answered

How does Claude Code simulate foldable device postures without physical manipulation?

Claude Code simulates foldable postures by executing Android Debug Bridge shell commands such as adb shell cmd device_state state through the developer workstation terminal. These commands instruct the Android operating system to simulate specific hardware postures—including CLOSED, HALF_OPENED, and OPEN—triggering Jetpack WindowManager posture callbacks programmatically.

How does ScreenSync MCP handle screen resolution changes when a device unfolds?

ScreenSync MCP captures display buffers natively through Android's MediaProjection API. When an Android device unfolds, the underlying virtual display surface dynamically resizes to match the new screen dimensions, allowing the local desktop hub to stream continuous video frames without dropping the connection or requiring session resets.

What is the difference between testing foldables on an emulator versus a physical foldable device?

Testing on physical foldable devices validates real-world hardware display cutouts, physical hinge sensor latencies, and manufacturer-specific OEM window managers like Samsung One UI. Emulators allow rapid posture angle configuration via ADB, but physical testing confirms exact touch response and thermal performance under sustained multi-window multitasking.

How does Claude Code verify that UI components avoid the physical hinge area?

Claude Code verifies hinge clearance by extracting the coordinate bounds of active UI elements from get_ui_hierarchy and comparing them with the hardware FoldingFeature bounds rectangle. If an interactive button or text input overlaps the hinge area, Claude Code flags the visual collision and refactors the layout.

Why do traditional Appium or Selenium scripts struggle with foldable fold/unfold testing?

Traditional Appium scripts struggle because fold/unfold transitions alter screen orientation, display density, and viewport aspect ratios simultaneously. These rapid configuration shifts often invalidate cached accessibility node references, freeze remote video streaming pipelines, and cause synthetic test sessions to terminate unexpectedly due to driver timeouts.

Does testing foldable posture changes with ScreenSync MCP require rooting the device?

Testing foldable posture changes with ScreenSync MCP requires zero device root access. Screen capture utilizes Android's standard MediaProjection API authorized once by the user, while posture simulation, touch interaction, and logcat telemetry execute deterministically through standard Android Debug Bridge (ADB) developer permissions.

How do Jetpack Compose adaptive scaffolds maintain UI state during fold transitions?

Jetpack Compose adaptive scaffolds maintain UI state by observing WindowSizeClass changes reactively while state holders preserve values using rememberSaveable or ViewModels. When an unfold event occurs, the scaffold reflows into dual-pane presentation without tearing down the underlying state or re-instantiating active coroutines.

Which AI agent platforms support automated foldable testing with ScreenSync MCP?

ScreenSync MCP supports any AI coding assistant capable of executing Model Context Protocol servers over local standard input/output (stdio), including Claude Code, Claude Desktop, Cursor, and VS Code in agent mode. Remote web assistants like ChatGPT are unsupported because they require external HTTPS endpoints rather than local stdio processes.

Written by

ScreenSync MCP team

The ScreenSync MCP team at EpsolDev builds the Android app, the desktop MCP hub and the browser extension that let AI agents see and control a real phone. These guides come out of that work.