# Multi-finger Touch

In addition to regular automation, we also provide an advanced multi-finger touch interface, which supports hardware trajectory recording, replay, construction, saving, and other functions, allowing you to implement complex finger operations.

```{attention}
The multi-finger touch interface requires your client to be upgraded to at least version 9.22. For optimal compatibility, we recommend upgrading the server as well.
```

To quickly get started, we recommend enabling Developer Options - Input - Show taps and Pointer location (if not enabled, you may not see any feedback). The following example code shows how to draw an X symbol at the top-left corner of the screen.

```python
touch = d.touch()
finger0 = touch.contact(0)
finger1 = touch.contact(1)

# --- 1. Press at start points ---
finger0.down(150, 320)
finger1.down(450, 320)
touch.wait(20)

# --- 2. Move along trajectory (10 coordinate points) ---
finger0.move(180, 350)
finger1.move(420, 350)
touch.wait(20)

finger0.move(210, 380)
finger1.move(390, 380)
touch.wait(20)

finger0.move(240, 410)
finger1.move(360, 410)
touch.wait(20)

finger0.move(270, 440)
finger1.move(330, 440)
touch.wait(20)

finger0.move(300, 470)  # Crossing center point
finger1.move(300, 470)
touch.wait(20)

finger0.move(330, 500)
finger1.move(270, 500)
touch.wait(20)

finger0.move(360, 530)
finger1.move(240, 530)
touch.wait(20)

finger0.move(390, 560)
finger1.move(210, 560)
touch.wait(20)

finger0.move(420, 590)
finger1.move(180, 590)
touch.wait(20)

finger0.move(450, 620)  # End point
finger1.move(150, 620)
touch.wait(20)

# --- 3. Lift fingers ---
finger0.up()
finger1.up()

# Perform the operation
touch.perform()
```

## Recording Trajectories

To make trajectory construction easier, we also provide a recording function. This function requires you to operate on a physical device.

```python
# Get a multi-touch session
touch = d.touch()

# After calling record(), it will wait for you to operate on the physical device screen within the timeout (120 seconds).
# When all fingers are lifted, recording ends and returns.
touch.record()

# You can save the trajectory as a binary file
touch.save("/sdcard/touch.bin")

# You can also directly replay the trajectory
touch.perform()
```

## Saving Trajectories

To avoid reconstructing trajectories through code each time, we provide a trajectory saving function to persist trajectories to files.

```python
# Get a multi-touch session
touch = d.touch()

# You can save the trajectory you just built for later loading
touch.save("/sdcard/track0.bin")
```

## Loading Trajectories

You can directly load a trajectory from a file on disk into the session.

```python
# Get a multi-touch session
touch = d.touch()

# Load trajectory from file
touch.load("/sdcard/track0.bin")
```

## Constructing Trajectories

In addition to constructing trajectories through recording, you can also manually construct touch trajectories via code. Below we introduce manual construction and other available functions. A valid touch operation consists of three event types: press, move, and release; you can set pressure parameters for events such as press and move.

```python
# Get a multi-touch session
touch = d.touch()

# Get two (or more) fingertip inputs
finger0 = touch.contact(0)
finger1 = touch.contact(1)

# Finger 0 presses at coordinate (150,320)
# Parameter z represents finger pressure, valid values 1-255, default 128
finger0.down(150, 320, z=128)

# Finger 0 moves from (150,320) to (180,350)
finger0.move(180, 350, z=128)

# Wait 20 milliseconds (equivalent to finger0.wait(20))
touch.wait(20)

# Finger 0 lifts up
finger0.up()

# Clear all trajectories
touch.reset()

# Perform the operation (wait parameter indicates whether to wait for operation completion)
touch.perform(wait=True)
```