rotate
Set device orientation to portrait or landscape for Android or iOS using a mobile automation tool. Simplify testing and UI validation with precise control.
Instructions
Rotate the device to a specific orientation
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| orientation | Yes | The orientation to set | |
| platform | Yes | Platform of the device |
Implementation Reference
- src/server/interactionTools.ts:796-802 (registration)Registers the "rotate" tool using ToolRegistry.registerDeviceAware with name, description, schema, handler function, and progress support flag.ToolRegistry.registerDeviceAware( "rotate", "Rotate the device to a specific orientation", rotateSchema, rotateHandler, true // Supports progress notifications );
- src/server/interactionTools.ts:650-663 (handler)The main tool handler for the "rotate" tool. Instantiates the Rotate class and calls its execute method with the requested orientation, then formats the response.const rotateHandler = async (device: BootedDevice, args: RotateArgs, progress?: ProgressCallback) => { try { const rotate = new Rotate(device); const result = await rotate.execute(args.orientation, progress); return createJSONToolResponse({ message: `Rotated device to ${args.orientation} orientation`, observation: result.observation, ...result }); } catch (error) { throw new ActionableError(`Failed to rotate device: ${error}`); } };
- Zod schema validating the input arguments for the rotate tool: orientation (portrait or landscape) and platform (android or ios).export const rotateSchema = z.object({ orientation: z.enum(["portrait", "landscape"]).describe("The orientation to set"), platform: z.enum(["android", "ios"]).describe("Platform of the device") });
- src/features/action/Rotate.ts:63-160 (helper)Core implementation of device rotation in the Rotate class's execute method. Detects current orientation and lock status, executes ADB commands to set user_rotation and accelerometer_rotation, verifies success, handles errors and lock restoration.async execute( orientation: "portrait" | "landscape", progress?: ProgressCallback ): Promise<RotateResult> { return this.observedInteraction( async () => { const value = orientation === "portrait" ? 0 : 1; // Get current orientation const currentOrientation = await this.getCurrentOrientation(); // Check if device is already in the desired orientation if (currentOrientation === orientation) { return { success: true, orientation, value, currentOrientation, previousOrientation: currentOrientation, rotationPerformed: false, orientationLockHandled: false, message: `Device is already in ${orientation} orientation` }; } // Check if orientation is locked const isLocked = await this.isOrientationLocked(); let orientationUnlocked = false; try { // If orientation is locked, unlock it temporarily if (isLocked) { logger.info("Orientation is locked, temporarily unlocking for rotation"); await this.adb.executeCommand("shell settings put system accelerometer_rotation 1"); orientationUnlocked = true; } // Disable accelerometer rotation and set user rotation await this.adb.executeCommand("shell settings put system accelerometer_rotation 0"); await this.adb.executeCommand(`shell settings put system user_rotation ${value}`); // Wait for rotation to complete await this.awaitIdle.waitForRotation(value); // If orientation was originally locked, restore the lock if (orientationUnlocked) { await this.adb.executeCommand("shell settings put system accelerometer_rotation 0"); logger.info("Restored orientation lock"); } // Verify the rotation was successful const newOrientation = await this.getCurrentOrientation(); const rotationSuccessful = newOrientation === orientation; return { success: rotationSuccessful, orientation, value, currentOrientation, previousOrientation: currentOrientation, rotationPerformed: true, orientationLockHandled: orientationUnlocked, message: rotationSuccessful ? `Successfully rotated from ${currentOrientation} to ${orientation}` : `Failed to rotate to ${orientation}, current orientation is ${newOrientation}` }; } catch (error) { // Restore orientation lock if we unlocked it if (orientationUnlocked) { try { await this.adb.executeCommand("shell settings put system accelerometer_rotation 0"); logger.info("Restored orientation lock after error"); } catch (restoreError) { logger.warn(`Failed to restore orientation lock: ${restoreError}`); } } return { success: false, orientation, value, currentOrientation, previousOrientation: currentOrientation, rotationPerformed: false, orientationLockHandled: orientationUnlocked, error: `Failed to change device orientation: ${error}` }; } }, { changeExpected: true, timeoutMs: 5000, progress } ); }
- src/models/RotateResult.ts:6-19 (schema)TypeScript interface defining the structure of the result object returned by the rotate operation, including success status, orientations, observation, and metadata.export interface RotateResult { success: boolean; orientation: string; value: number; observation?: ObserveResult; error?: string; // Enhanced fields for intelligent rotation currentOrientation?: string; previousOrientation?: string; rotationPerformed?: boolean; orientationLockHandled?: boolean; message?: string; }