deepadb 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { z } from "zod";
9
9
  import { OutputProcessor } from "../middleware/output-processor.js";
10
- import { validateShellArg, validateShellArgs } from "../middleware/sanitize.js";
10
+ import { shellEscape, validateShellArg, validateShellArgs } from "../middleware/sanitize.js";
11
11
  export function registerControlTools(ctx) {
12
12
  ctx.server.tool("adb_airplane_mode", "Toggle airplane mode on/off. Useful for resetting cellular registration during radio testing.", {
13
13
  enabled: z.boolean().describe("true = enable airplane mode, false = disable"),
@@ -76,13 +76,19 @@ export function registerControlTools(ctx) {
76
76
  return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
77
77
  }
78
78
  });
79
- ctx.server.tool("adb_screen", "Control screen state: wake, sleep, toggle, or unlock (swipe up)", {
80
- action: z.enum(["wake", "sleep", "toggle", "unlock"]).describe("Screen action"),
79
+ ctx.server.tool("adb_screen", "Control screen state: wake, sleep, toggle, lock, or unlock. Lock and unlock verify actual keyguard state via dumpsys window. Unlock uses wm dismiss-keyguard (works for swipe keyguards); supply 'pin' to perform the full PIN entry sequence for PIN-protected devices: wakes screen, dismisses keyguard, swipes up to reveal keypad, types PIN, confirms with ENTER, and verifies the keyguard sleep token was released.", {
80
+ action: z.enum(["wake", "sleep", "toggle", "lock", "unlock"]).describe("Screen action"),
81
+ pin: z.string().trim().regex(/^[a-zA-Z0-9]+$/, "PIN must be alphanumeric only").optional().describe("PIN/password to enter when unlock encounters an active keyguard (digits only for PIN, alphanumeric for password). Only used with action='unlock'."),
81
82
  device: z.string().optional().describe("Device serial"),
82
- }, async ({ action, device }) => {
83
+ }, async ({ action, pin, device }) => {
83
84
  try {
84
85
  const resolved = await ctx.deviceManager.resolveDevice(device);
85
86
  const serial = resolved.serial;
87
+ /** True if the keyguard security challenge is currently active (window sleep token present). */
88
+ const isKeyguardActive = async () => {
89
+ const r = await ctx.bridge.shell("dumpsys window | grep -m1 keyguard", { device: serial, timeout: 5000, ignoreExitCode: true });
90
+ return r.stdout.includes("keyguard");
91
+ };
86
92
  switch (action) {
87
93
  case "wake":
88
94
  await ctx.bridge.shell("input keyevent KEYCODE_WAKEUP", { device: serial });
@@ -93,11 +99,58 @@ export function registerControlTools(ctx) {
93
99
  case "toggle":
94
100
  await ctx.bridge.shell("input keyevent KEYCODE_POWER", { device: serial });
95
101
  break;
96
- case "unlock":
102
+ case "lock": {
103
+ const pwState = await ctx.bridge.shell("dumpsys power | grep -m1 mWakefulness", { device: serial, timeout: 5000, ignoreExitCode: true });
104
+ if (!pwState.stdout.includes("Awake")) {
105
+ // Screen already off — check keyguard so response is always informative
106
+ const alreadyLocked = await isKeyguardActive();
107
+ return { content: [{ type: "text", text: alreadyLocked ? "Screen: already locked (keyguard active)" : "Screen: already off" }] };
108
+ }
109
+ await ctx.bridge.shell("input keyevent KEYCODE_SLEEP", { device: serial });
110
+ await new Promise((r) => setTimeout(r, 1500)); // keyguard sleep token takes ~1s to appear in dumpsys window
111
+ const locked = await isKeyguardActive();
112
+ return { content: [{ type: "text", text: locked ? "Screen: locked (keyguard active)" : "Screen: sleep sent" }] };
113
+ }
114
+ case "unlock": {
97
115
  await ctx.bridge.shell("input keyevent KEYCODE_WAKEUP", { device: serial });
98
116
  await new Promise((r) => setTimeout(r, 300));
99
- await ctx.bridge.shell("input swipe 540 1800 540 400 300", { device: serial, ignoreExitCode: true });
100
- break;
117
+ await ctx.bridge.shell("wm dismiss-keyguard", { device: serial, ignoreExitCode: true });
118
+ await new Promise((r) => setTimeout(r, 400));
119
+ const stillLocked = await isKeyguardActive();
120
+ if (!stillLocked) {
121
+ return { content: [{ type: "text", text: "Screen: unlocked (keyguard dismissed)" }] };
122
+ }
123
+ // Keyguard is still active (PIN/pattern). Attempt PIN entry if supplied.
124
+ if (!pin) {
125
+ return { content: [{ type: "text", text: "Screen: awake — keyguard still active (PIN/pattern/biometric required)" }] };
126
+ }
127
+ // Derive proportional swipe coordinates from actual screen size
128
+ const sizeResult = await ctx.bridge.shell("wm size", { device: serial, timeout: 5000, ignoreExitCode: true });
129
+ const sizeMatch = sizeResult.stdout.match(/(\d+)x(\d+)/);
130
+ const screenW = sizeMatch ? parseInt(sizeMatch[1]) : 1080;
131
+ const screenH = sizeMatch ? parseInt(sizeMatch[2]) : 2400;
132
+ const cx = Math.round(screenW / 2);
133
+ const yBot = Math.round(screenH * 0.80);
134
+ const yTop = Math.round(screenH * 0.20);
135
+ // Swipe up to reveal PIN keypad
136
+ await ctx.bridge.shell(`input swipe ${cx} ${yBot} ${cx} ${yTop} 300`, { device: serial });
137
+ await new Promise((r) => setTimeout(r, 1000));
138
+ // Type PIN and confirm
139
+ await ctx.bridge.shell(`input text '${shellEscape(pin)}'`, { device: serial });
140
+ await new Promise((r) => setTimeout(r, 300));
141
+ await ctx.bridge.shell("input keyevent KEYCODE_ENTER", { device: serial });
142
+ await new Promise((r) => setTimeout(r, 800));
143
+ // Verify keyguard was actually dismissed
144
+ const unlockedAfterPin = !(await isKeyguardActive());
145
+ return {
146
+ content: [{
147
+ type: "text",
148
+ text: unlockedAfterPin
149
+ ? "Screen: unlocked (PIN accepted, keyguard dismissed)"
150
+ : "Screen: PIN entered — keyguard still active (wrong PIN or biometric required)",
151
+ }],
152
+ };
153
+ }
101
154
  }
102
155
  return { content: [{ type: "text", text: `Screen: ${action} sent` }] };
103
156
  }
@@ -1 +1 @@
1
- {"version":3,"file":"control.js","sourceRoot":"","sources":["../../src/tools/control.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"control.js","sourceRoot":"","sources":["../../src/tools/control.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE7F,MAAM,UAAU,oBAAoB,CAAC,GAAgB;IAEnD,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,mBAAmB,EACnB,+FAA+F,EAC/F;QACE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QAC7E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAChC,kBAAkB;YAClB,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1F,qDAAqD;YACrD,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CACpB,kEAAkE,OAAO,EAAE,EAC3E,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CACzC,CAAC;YACF,yCAAyC;YACzC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9C,SAAS;YACT,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACjG,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;YAC1D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,UAAU,EACV,wBAAwB,EACxB;QACE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QACpE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB,CAAC;YAC7D,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACzD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC;QAC5F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,iBAAiB,EACjB,+BAA+B,EAC/B;QACE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;QAC3E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB,CAAC;YAC7D,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACzD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC;QACnG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,cAAc,EACd,qCAAqC,EACrC;QACE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAC1D,sFAAsF,CACvF;QACD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,qDAAqD;YACrD,MAAM,OAAO,GAA2B,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YAC5F,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CACpB,qCAAqC,OAAO,CAAC,IAAI,CAAC,EAAE,EACpD,EAAE,MAAM,EAAE,MAAM,EAAE,CACnB,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QACzE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,YAAY,EACZ,4ZAA4Z,EAC5Z;QACE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC;QACvF,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,+BAA+B,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mJAAmJ,CAAC;QACxP,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAE/B,gGAAgG;YAChG,MAAM,gBAAgB,GAAG,KAAK,IAAsB,EAAE;gBACpD,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAC9B,oCAAoC,EACpC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CACxD,CAAC;gBACF,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACvC,CAAC,CAAC;YAEF,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,MAAM;oBACT,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC5E,MAAM;gBACR,KAAK,OAAO;oBACV,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC3E,MAAM;gBACR,KAAK,QAAQ;oBACX,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC3E,MAAM;gBACR,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CACpC,uCAAuC,EACvC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CACxD,CAAC;oBACF,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;wBACtC,wEAAwE;wBACxE,MAAM,aAAa,GAAG,MAAM,gBAAgB,EAAE,CAAC;wBAC/C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC;oBACnI,CAAC;oBACD,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC3E,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,6DAA6D;oBAC5G,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;oBACxC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC,EAAE,CAAC;gBACnH,CAAC;gBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC5E,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;oBAC7C,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;oBACxF,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;oBAE7C,MAAM,WAAW,GAAG,MAAM,gBAAgB,EAAE,CAAC;oBAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;wBACjB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uCAAuC,EAAE,CAAC,EAAE,CAAC;oBACxF,CAAC;oBAED,yEAAyE;oBACzE,IAAI,CAAC,GAAG,EAAE,CAAC;wBACT,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,wEAAwE,EAAE,CAAC,EAAE,CAAC;oBACzH,CAAC;oBAED,gEAAgE;oBAChE,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC9G,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;oBACzD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC1D,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC1D,MAAM,EAAE,GAAK,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;oBACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;oBACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;oBAExC,gCAAgC;oBAChC,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC1F,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;oBAC9C,uBAAuB;oBACvB,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC/E,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;oBAC7C,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC3E,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;oBAE7C,yCAAyC;oBACzC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC;oBACrD,OAAO;wBACL,OAAO,EAAE,CAAC;gCACR,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,gBAAgB;oCACpB,CAAC,CAAC,qDAAqD;oCACvD,CAAC,CAAC,+EAA+E;6BACpF,CAAC;qBACH,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,MAAM,OAAO,EAAE,CAAC,EAAE,CAAC;QACzE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,oBAAoB,EACpB,oIAAoI,EACpI;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAC5H,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE;QACjC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAE/B,uBAAuB;YACvB,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACrF,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CACpB,qEAAqE,EACrE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CACzC,CAAC;YAEF,MAAM,MAAM,GAAG,CAAC,uBAAuB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACnE,MAAM,CAAC,IAAI,CAAC,WAAW,YAAY,yBAAyB,CAAC,CAAC;YAE9D,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;YAE7D,wBAAwB;YACxB,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACrF,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CACpB,sEAAsE,EACtE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CACzC,CAAC;YAEF,MAAM,CAAC,IAAI,CAAC,wBAAwB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAC;YAEtF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QAClE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,kBAAkB,EAClB,4EAA4E,EAC5E;QACE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAChF,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8EAA8E,CAAC;QACxG,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC5C,IAAI,MAAM;gBAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAChF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,SAAS,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACvG,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,SAAS,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,GAAG,MAAM,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;QACtI,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,kBAAkB,EAClB,2EAA2E,EAC3E;QACE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAChF,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;QACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YACnE,IAAI,MAAM;gBAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAChF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,SAAS,IAAI,GAAG,IAAI,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACjG,uBAAuB;YACvB,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,SAAS,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACtG,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QAC/F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,YAAY,EACZ,qEAAqE,EACrE;QACE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;aAC5E,QAAQ,CAAC,wDAAwD,CAAC;QACrE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,MAAM,IAAI,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;gBACzC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,KAAK;gBACd,cAAc,EAAE,IAAI;aACrB,CAAC,CAAC;YACH,GAAG,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,aAAa,MAAM,SAAS,IAAI,oDAAoD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;qBACpJ,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClG,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"input-gestures.d.ts","sourceRoot":"","sources":["../../src/tools/input-gestures.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOjD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAo3BhE"}
1
+ {"version":3,"file":"input-gestures.d.ts","sourceRoot":"","sources":["../../src/tools/input-gestures.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOjD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA4pChE"}
@@ -38,6 +38,24 @@ export function registerInputGestureTools(ctx) {
38
38
  return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
39
39
  }
40
40
  });
41
+ ctx.server.tool("adb_input_fling", "Perform a high-velocity fling gesture. Like swipe but with a short duration to create scroll momentum on lists, launchers, and paged views. Useful for fast-scrolling through long lists, dismissing notifications, or triggering velocity-sensitive behaviors.", {
42
+ x1: z.number().int().min(0).max(9999).describe("Start X coordinate"),
43
+ y1: z.number().int().min(0).max(9999).describe("Start Y coordinate"),
44
+ x2: z.number().int().min(0).max(9999).describe("End X coordinate"),
45
+ y2: z.number().int().min(0).max(9999).describe("End Y coordinate"),
46
+ durationMs: z.number().int().min(20).max(200).optional().default(50)
47
+ .describe("Fling duration in ms (20-200, default 50). Shorter = more velocity"),
48
+ device: z.string().optional().describe("Device serial"),
49
+ }, async ({ x1, y1, x2, y2, durationMs, device }) => {
50
+ try {
51
+ const resolved = await ctx.deviceManager.resolveDevice(device);
52
+ await ctx.bridge.shell(`input swipe ${x1} ${y1} ${x2} ${y2} ${durationMs}`, { device: resolved.serial, timeout: durationMs + 3000, ignoreExitCode: true });
53
+ return { content: [{ type: "text", text: `Fling: (${x1},${y1}) → (${x2},${y2}) over ${durationMs}ms` }] };
54
+ }
55
+ catch (error) {
56
+ return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
57
+ }
58
+ });
41
59
  ctx.server.tool("adb_input_long_press", "Long press at a point on screen. Triggers context menus, selection mode, drag handles, and other long-press behaviors. Implemented as a zero-distance swipe with configurable hold duration.", {
42
60
  x: z.number().int().min(0).max(9999).describe("X coordinate"),
43
61
  y: z.number().int().min(0).max(9999).describe("Y coordinate"),
@@ -490,12 +508,12 @@ export function registerInputGestureTools(ctx) {
490
508
  return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
491
509
  }
492
510
  });
493
- ctx.server.tool("adb_batch_actions", "Execute multiple input actions in a single tool call. Reduces ADB round-trips for multi-step UI interactions. Each action runs sequentially with an optional delay between them. Supported action types: tap, swipe, long_press, double_tap, keyevent, text, drag, back, home, sleep.", {
511
+ ctx.server.tool("adb_batch_actions", "Execute multiple input actions in a single tool call. Reduces ADB round-trips for multi-step UI interactions. Each action runs sequentially with an optional delay between them. Supported action types: tap, swipe, fling, long_press, double_tap, keyevent, text, drag, pinch, back, home, sleep.", {
494
512
  actions: z.array(z.object({
495
- type: z.enum(["tap", "swipe", "long_press", "double_tap", "keyevent", "text", "drag", "back", "home", "sleep"])
513
+ type: z.enum(["tap", "swipe", "fling", "long_press", "double_tap", "keyevent", "text", "drag", "pinch", "back", "home", "sleep"])
496
514
  .describe("Action type"),
497
515
  args: z.string().optional()
498
- .describe("Action arguments: tap='x y', swipe='x1 y1 x2 y2 [ms]', long_press='x y [ms]', double_tap='x y', keyevent='KEYCODE_*', text='string', drag='x1 y1 x2 y2 [ms]', sleep='ms', back/home=none"),
516
+ .describe("Action arguments: tap='x y', swipe='x1 y1 x2 y2 [ms]', fling='x1 y1 x2 y2 [ms]', long_press='x y [ms]', double_tap='x y', keyevent='KEYCODE_*', text='string', drag='x1 y1 x2 y2 [ms]', pinch='cx cy startRadius endRadius [durationMs]', sleep='ms', back/home=none"),
499
517
  })).min(1).max(50).describe("Array of actions to execute (1-50)"),
500
518
  delayMs: z.number().int().min(0).max(5000).optional().default(100)
501
519
  .describe("Delay between actions in ms (0-5000, default 100)"),
@@ -525,6 +543,17 @@ export function registerInputGestureTools(ctx) {
525
543
  throw new Error(`Invalid swipe args: "${args}"`);
526
544
  cmd = `input swipe ${args}`;
527
545
  break;
546
+ case "fling": {
547
+ if (!/^[\d\s]+$/.test(args))
548
+ throw new Error(`Invalid fling args: "${args}"`);
549
+ const fl = args.trim().split(/\s+/);
550
+ if (fl.length < 4)
551
+ throw new Error("fling needs: x1 y1 x2 y2 [durationMs]");
552
+ // Default to 50ms for fling velocity; user-supplied 5th arg overrides
553
+ const flDur = fl[4] ?? "50";
554
+ cmd = `input swipe ${fl[0]} ${fl[1]} ${fl[2]} ${fl[3]} ${flDur}`;
555
+ break;
556
+ }
528
557
  case "long_press": {
529
558
  if (!/^[\d\s]+$/.test(args))
530
559
  throw new Error(`Invalid long_press args: "${args}"`);
@@ -559,6 +588,26 @@ export function registerInputGestureTools(ctx) {
559
588
  throw new Error(`Invalid drag args: "${args}"`);
560
589
  cmd = `input draganddrop ${args}`;
561
590
  break;
591
+ case "pinch": {
592
+ if (!/^[\d\s]+$/.test(args))
593
+ throw new Error(`Invalid pinch args: "${args}"`);
594
+ const pp = args.trim().split(/\s+/).map(Number);
595
+ if (pp.length < 4)
596
+ throw new Error("pinch needs: cx cy startRadius endRadius [durationMs]");
597
+ const [pcx, pcy, psr, per] = pp;
598
+ const pdur = pp[4] ?? 500;
599
+ const prad = (90 * Math.PI) / 180; // vertical axis
600
+ const pf1sx = Math.round(pcx + psr * Math.cos(prad));
601
+ const pf1sy = Math.round(pcy + psr * Math.sin(prad));
602
+ const pf1ex = Math.round(pcx + per * Math.cos(prad));
603
+ const pf1ey = Math.round(pcy + per * Math.sin(prad));
604
+ const pf2sx = Math.round(pcx - psr * Math.cos(prad));
605
+ const pf2sy = Math.round(pcy - psr * Math.sin(prad));
606
+ const pf2ex = Math.round(pcx - per * Math.cos(prad));
607
+ const pf2ey = Math.round(pcy - per * Math.sin(prad));
608
+ cmd = `input swipe ${pf1sx} ${pf1sy} ${pf1ex} ${pf1ey} ${pdur} & input swipe ${pf2sx} ${pf2sy} ${pf2ex} ${pf2ey} ${pdur}`;
609
+ break;
610
+ }
562
611
  case "back":
563
612
  cmd = "input keyevent KEYCODE_BACK";
564
613
  break;
@@ -762,5 +811,210 @@ export function registerInputGestureTools(ctx) {
762
811
  return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
763
812
  }
764
813
  });
814
+ // ── Multi-Touch: Pinch/Spread Gesture ─────────────────────────────────
815
+ /**
816
+ * Discover the primary touchscreen input device and its MT axis ranges.
817
+ * Parses `getevent -p` output to find a device with ABS_MT_POSITION_X/Y
818
+ * and INPUT_PROP_DIRECT. Caches the result for the session.
819
+ */
820
+ let cachedTouchDevice = undefined;
821
+ async function detectTouchDevice(bridge, serial) {
822
+ if (cachedTouchDevice !== undefined)
823
+ return cachedTouchDevice;
824
+ try {
825
+ const result = await bridge.rootShell("getevent -p", {
826
+ device: serial, timeout: 5000, ignoreExitCode: true,
827
+ });
828
+ const output = result.stdout;
829
+ // Split into device blocks
830
+ const blocks = output.split(/(?=add device \d+:)/);
831
+ for (const block of blocks) {
832
+ // Must be INPUT_PROP_DIRECT (touch screen, not touchpad)
833
+ if (!block.includes("INPUT_PROP_DIRECT"))
834
+ continue;
835
+ const nodeMatch = block.match(/add device \d+:\s+(\S+)/);
836
+ if (!nodeMatch)
837
+ continue;
838
+ // Must have ABS_MT_POSITION_X (0035) and ABS_MT_POSITION_Y (0036)
839
+ const xMatch = block.match(/0035\s+:\s+value \d+, min (\d+), max (\d+)/);
840
+ const yMatch = block.match(/0036\s+:\s+value \d+, min (\d+), max (\d+)/);
841
+ if (!xMatch || !yMatch)
842
+ continue;
843
+ // Optional: ABS_MT_SLOT (002f), ABS_MT_PRESSURE (003a)
844
+ const slotMatch = block.match(/002f\s+:\s+value \d+, min \d+, max (\d+)/);
845
+ const pressMatch = block.match(/003a\s+:\s+value \d+, min \d+, max (\d+)/);
846
+ cachedTouchDevice = {
847
+ eventNode: nodeMatch[1],
848
+ maxX: parseInt(xMatch[2], 10),
849
+ maxY: parseInt(yMatch[2], 10),
850
+ maxSlot: slotMatch ? parseInt(slotMatch[1], 10) : 1,
851
+ maxPressure: pressMatch ? parseInt(pressMatch[1], 10) : 50,
852
+ };
853
+ return cachedTouchDevice;
854
+ }
855
+ }
856
+ catch { /* getevent requires root — expected to fail without it */ }
857
+ cachedTouchDevice = null;
858
+ return null;
859
+ }
860
+ ctx.server.tool("adb_input_pinch", "Perform a multi-touch pinch (zoom out) or spread (zoom in) gesture. Two fingers move symmetrically toward or away from a center point. Uses parallel swipe injection by default (universal, no root); when root is available, can use raw sendevent for true multi-touch MT protocol injection. The 'auto' method selects the best available approach.", {
861
+ cx: z.number().int().min(0).max(9999).describe("Center X coordinate of the pinch gesture"),
862
+ cy: z.number().int().min(0).max(9999).describe("Center Y coordinate of the pinch gesture"),
863
+ startRadius: z.number().int().min(10).max(2000).describe("Starting distance (px) from center to each finger"),
864
+ endRadius: z.number().int().min(10).max(2000).describe("Ending distance (px) from center to each finger. Smaller than startRadius = pinch/zoom-out, larger = spread/zoom-in"),
865
+ durationMs: z.number().int().min(100).max(5000).optional().default(500)
866
+ .describe("Gesture duration in ms (100-5000, default 500)"),
867
+ angle: z.number().min(0).max(360).optional().default(90)
868
+ .describe("Angle in degrees for the pinch axis (0=horizontal, 90=vertical, default 90)"),
869
+ steps: z.number().int().min(5).max(60).optional().default(20)
870
+ .describe("Interpolation steps for sendevent method (5-60, default 20). More steps = smoother gesture"),
871
+ method: z.enum(["auto", "swipe", "sendevent"]).optional().default("auto")
872
+ .describe("Injection method: 'auto' (sendevent if root, else swipe), 'swipe' (parallel swipes, universal), 'sendevent' (raw MT protocol, requires root)"),
873
+ device: z.string().optional().describe("Device serial"),
874
+ }, async ({ cx, cy, startRadius, endRadius, durationMs, angle, steps, method, device }) => {
875
+ try {
876
+ const resolved = await ctx.deviceManager.resolveDevice(device);
877
+ const serial = resolved.serial;
878
+ // Convert angle to radians for finger position calculation
879
+ const rad = (angle * Math.PI) / 180;
880
+ // Calculate finger positions at start and end
881
+ const f1StartX = Math.round(cx + startRadius * Math.cos(rad));
882
+ const f1StartY = Math.round(cy + startRadius * Math.sin(rad));
883
+ const f1EndX = Math.round(cx + endRadius * Math.cos(rad));
884
+ const f1EndY = Math.round(cy + endRadius * Math.sin(rad));
885
+ const f2StartX = Math.round(cx - startRadius * Math.cos(rad));
886
+ const f2StartY = Math.round(cy - startRadius * Math.sin(rad));
887
+ const f2EndX = Math.round(cx - endRadius * Math.cos(rad));
888
+ const f2EndY = Math.round(cy - endRadius * Math.sin(rad));
889
+ // Determine method
890
+ let useMethod = method;
891
+ if (useMethod === "auto") {
892
+ // Check root + touchscreen availability
893
+ const touchDev = await detectTouchDevice(ctx.bridge, serial);
894
+ useMethod = touchDev ? "sendevent" : "swipe";
895
+ }
896
+ if (useMethod === "sendevent") {
897
+ // ── sendevent: true multi-touch MT Type B protocol via atomic binary writes ──
898
+ // Each frame (events between SYN_REPORTs) is written as a single binary blob
899
+ // to the touchscreen device node via `xxd -r -p`. This ensures Android's
900
+ // MultiTouchInputMapper receives all slot updates atomically, which is required
901
+ // for reliable multi-pointer gesture recognition. Individual `sendevent` calls
902
+ // are too slow (~5-10ms per fork) and cause the InputReader to miss the gesture.
903
+ const touchDev = await detectTouchDevice(ctx.bridge, serial);
904
+ if (!touchDev) {
905
+ return {
906
+ content: [{ type: "text", text: "sendevent method requires root and a detected touchscreen. Use method='swipe' instead." }],
907
+ isError: true,
908
+ };
909
+ }
910
+ const node = touchDev.eventNode;
911
+ // Validate event node path — defense-in-depth even though it comes from getevent -p
912
+ if (!node.startsWith("/dev/") || /["'`$\\!;|&(){}<>\n\r]/.test(node) || node.includes("..")) {
913
+ return {
914
+ content: [{ type: "text", text: `Invalid touchscreen device node: ${node}` }],
915
+ isError: true,
916
+ };
917
+ }
918
+ const pressure = Math.min(50, touchDev.maxPressure);
919
+ const sleepPerStep = (durationMs / steps / 1000).toFixed(4);
920
+ // Encode a single struct input_event (24 bytes on ARM64) as hex.
921
+ // struct input_event { long tv_sec, long tv_usec, u16 type, u16 code, s32 value }
922
+ // Timestamps set to 0 — kernel's evdev_write() fills them from system clock.
923
+ const ev = (type, code, value) => {
924
+ const ts = "00000000000000000000000000000000"; // 16 bytes zeros (tv_sec + tv_usec)
925
+ const t0 = (type & 0xff).toString(16).padStart(2, "0");
926
+ const t1 = ((type >> 8) & 0xff).toString(16).padStart(2, "0");
927
+ const c0 = (code & 0xff).toString(16).padStart(2, "0");
928
+ const c1 = ((code >> 8) & 0xff).toString(16).padStart(2, "0");
929
+ const uv = value < 0 ? value + 0x100000000 : value;
930
+ const v0 = (uv & 0xff).toString(16).padStart(2, "0");
931
+ const v1 = ((uv >> 8) & 0xff).toString(16).padStart(2, "0");
932
+ const v2 = ((uv >> 16) & 0xff).toString(16).padStart(2, "0");
933
+ const v3 = ((uv >> 24) & 0xff).toString(16).padStart(2, "0");
934
+ return ts + t0 + t1 + c0 + c1 + v0 + v1 + v2 + v3;
935
+ };
936
+ // Helper: write a complete frame (all events + SYN_REPORT) atomically
937
+ const writeFrame = (events) => `echo '${events}' | xxd -r -p > '${node}'`;
938
+ const cmds = [];
939
+ // Frame 1: Initial touch down — both fingers + SYN_REPORT
940
+ let downFrame = "";
941
+ downFrame += ev(3, 47, 0); // ABS_MT_SLOT 0
942
+ downFrame += ev(3, 57, 1000); // ABS_MT_TRACKING_ID finger 1
943
+ downFrame += ev(3, 53, f1StartX); // ABS_MT_POSITION_X
944
+ downFrame += ev(3, 54, f1StartY); // ABS_MT_POSITION_Y
945
+ downFrame += ev(3, 48, 50); // ABS_MT_TOUCH_MAJOR
946
+ downFrame += ev(3, 58, pressure); // ABS_MT_PRESSURE
947
+ downFrame += ev(3, 47, 1); // ABS_MT_SLOT 1
948
+ downFrame += ev(3, 57, 1001); // ABS_MT_TRACKING_ID finger 2
949
+ downFrame += ev(3, 53, f2StartX); // ABS_MT_POSITION_X
950
+ downFrame += ev(3, 54, f2StartY); // ABS_MT_POSITION_Y
951
+ downFrame += ev(3, 48, 50); // ABS_MT_TOUCH_MAJOR
952
+ downFrame += ev(3, 58, pressure); // ABS_MT_PRESSURE
953
+ downFrame += ev(1, 330, 1); // BTN_TOUCH down
954
+ downFrame += ev(0, 0, 0); // SYN_REPORT
955
+ cmds.push(writeFrame(downFrame));
956
+ // Move frames — interpolate both fingers toward/away from center
957
+ for (let i = 1; i <= steps; i++) {
958
+ const t = i / steps;
959
+ const x1 = Math.round(f1StartX + (f1EndX - f1StartX) * t);
960
+ const y1 = Math.round(f1StartY + (f1EndY - f1StartY) * t);
961
+ const x2 = Math.round(f2StartX + (f2EndX - f2StartX) * t);
962
+ const y2 = Math.round(f2StartY + (f2EndY - f2StartY) * t);
963
+ let moveFrame = "";
964
+ moveFrame += ev(3, 47, 0); // SLOT 0
965
+ moveFrame += ev(3, 53, x1); // POSITION_X
966
+ moveFrame += ev(3, 54, y1); // POSITION_Y
967
+ moveFrame += ev(3, 47, 1); // SLOT 1
968
+ moveFrame += ev(3, 53, x2); // POSITION_X
969
+ moveFrame += ev(3, 54, y2); // POSITION_Y
970
+ moveFrame += ev(0, 0, 0); // SYN_REPORT
971
+ cmds.push(`sleep ${sleepPerStep}`);
972
+ cmds.push(writeFrame(moveFrame));
973
+ }
974
+ // Final frame: release both fingers
975
+ let upFrame = "";
976
+ upFrame += ev(3, 47, 0); // SLOT 0
977
+ upFrame += ev(3, 57, -1); // TRACKING_ID -1 = finger up
978
+ upFrame += ev(3, 47, 1); // SLOT 1
979
+ upFrame += ev(3, 57, -1); // TRACKING_ID -1 = finger up
980
+ upFrame += ev(1, 330, 0); // BTN_TOUCH up
981
+ upFrame += ev(0, 0, 0); // SYN_REPORT
982
+ cmds.push(writeFrame(upFrame));
983
+ // Execute as a single batched shell command via root
984
+ const script = cmds.join("; ");
985
+ await ctx.bridge.rootShell(script, {
986
+ device: serial,
987
+ timeout: durationMs + 5000,
988
+ ignoreExitCode: true,
989
+ });
990
+ const gesture = endRadius < startRadius ? "pinch" : "spread";
991
+ return {
992
+ content: [{
993
+ type: "text",
994
+ text: `${gesture} (sendevent): center (${cx},${cy}), radius ${startRadius}→${endRadius}px, ${durationMs}ms, ${steps} steps, ${angle}° axis\nDevice: ${node} (${touchDev.maxX}×${touchDev.maxY})\nFinger 1: (${f1StartX},${f1StartY})→(${f1EndX},${f1EndY})\nFinger 2: (${f2StartX},${f2StartY})→(${f2EndX},${f2EndY})`,
995
+ }],
996
+ };
997
+ }
998
+ // ── swipe: parallel input swipe with backgrounding ──
999
+ // Two concurrent single-touch swipes that converge/diverge
1000
+ const cmd = `input swipe ${f1StartX} ${f1StartY} ${f1EndX} ${f1EndY} ${durationMs} & ` +
1001
+ `input swipe ${f2StartX} ${f2StartY} ${f2EndX} ${f2EndY} ${durationMs}`;
1002
+ await ctx.bridge.shell(cmd, {
1003
+ device: serial,
1004
+ timeout: durationMs + 5000,
1005
+ ignoreExitCode: true,
1006
+ });
1007
+ const gesture = endRadius < startRadius ? "pinch" : "spread";
1008
+ return {
1009
+ content: [{
1010
+ type: "text",
1011
+ text: `${gesture} (swipe): center (${cx},${cy}), radius ${startRadius}→${endRadius}px, ${durationMs}ms, ${angle}° axis\nFinger 1: (${f1StartX},${f1StartY})→(${f1EndX},${f1EndY})\nFinger 2: (${f2StartX},${f2StartY})→(${f2EndX},${f2EndY})`,
1012
+ }],
1013
+ };
1014
+ }
1015
+ catch (error) {
1016
+ return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
1017
+ }
1018
+ });
765
1019
  }
766
1020
  //# sourceMappingURL=input-gestures.js.map