Skip to main content

Device Model

The Device model represents Android devices registered with the FYI Automation Tool. It stores device information, capabilities, and connection details for automation execution.

Schema Definition

model Device {
id String @id @default(uuid())
deviceId String @unique
name String?
brand String?
model String?
androidVersion String?
screenWidth Int?
screenHeight Int?
isActive Boolean @default(true)
lastSeenAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
androidId String?
avdName String?
buildFingerprint String?
buildId String?
cpuAbi String?
deviceName String?
fingerprint String? @unique
hardwareSerial String?
isEmulator Boolean @default(false)
lastAdbId String?
marketingName String?
productName String?
}

Field Descriptions

Primary Identification

FieldTypeDescription
idStringUUID primary key
deviceIdStringUnique device identifier (ADB serial)
fingerprintString?Unique device fingerprint for deduplication

Basic Information

FieldTypeDescription
nameString?Human-readable device name
brandString?Device manufacturer (e.g., "Google", "Samsung")
modelString?Device model (e.g., "Pixel 6", "Galaxy S21")
marketingNameString?Marketing name of the device
deviceNameString?Device codename

Android Information

FieldTypeDescription
androidVersionString?Android OS version (e.g., "13", "14")
androidIdString?Android ID of the device
buildFingerprintString?Complete build fingerprint
buildIdString?Build ID
cpuAbiString?CPU ABI (e.g., "arm64-v8a", "x86_64")

Hardware Information

FieldTypeDescription
screenWidthInt?Screen width in pixels
screenHeightInt?Screen height in pixels
productNameString?Product name
hardwareSerialString?Hardware serial number

Emulator Information

FieldTypeDescription
isEmulatorBooleanWhether this is an Android emulator (default: false)
avdNameString?Android Virtual Device name (for emulators)

Status and Tracking

FieldTypeDescription
isActiveBooleanWhether the device is active and available (default: true)
lastSeenAtDateTimeLast time the device was seen/connected
lastAdbIdString?Last ADB identifier used
createdAtDateTimeDevice registration timestamp
updatedAtDateTimeLast update timestamp

Relationships

The Device model doesn't have direct foreign key relationships but is referenced by:

  • Flow execution (via targetDevice string field)
  • Coordinate caching (via deviceId in FlowCoordinateCache)
  • Recordings (via deviceId in Recording)

Usage Examples

Registering a Physical Device

const device = await prisma.device.create({
data: {
deviceId: "HT1A12345678",
name: "Samsung Galaxy S21",
brand: "Samsung",
model: "SM-G991U",
androidVersion: "13",
screenWidth: 1080,
screenHeight: 2400,
androidId: "a1b2c3d4e5f6g7h8",
buildFingerprint: "samsung/beyond2lte/beyond2:13/TP1A.220624.014/G975FXXS7CUF1:user/release-keys",
cpuAbi: "arm64-v8a",
fingerprint: "unique-device-hash-123"
}
});

Registering an Emulator

const emulator = await prisma.device.create({
data: {
deviceId: "emulator-5554",
name: "Pixel 6 API 34",
brand: "Google",
model: "sdk_gphone64_arm64",
androidVersion: "14",
screenWidth: 1080,
screenHeight: 2400,
isEmulator: true,
avdName: "Pixel_6_API_34",
cpuAbi: "arm64-v8a",
fingerprint: "emulator-fingerprint-456"
}
});

Updating Device Status

await prisma.device.update({
where: { deviceId: "emulator-5554" },
data: {
lastSeenAt: new Date(),
isActive: true
}
});

Finding Active Devices

const activeDevices = await prisma.device.findMany({
where: {
isActive: true,
lastSeenAt: {
gte: new Date(Date.now() - 5 * 60 * 1000) // Active in last 5 minutes
}
},
orderBy: { lastSeenAt: "desc" }
});

Query Examples

Get Device by Serial

const device = await prisma.device.findUnique({
where: { deviceId: "emulator-5554" }
});

Get Devices by Brand

const googleDevices = await prisma.device.findMany({
where: {
brand: "Google",
isActive: true
}
});

Get Available Emulators

const emulators = await prisma.device.findMany({
where: {
isEmulator: true,
isActive: true
},
orderBy: { name: "asc" }
});

Get Devices by Android Version

const android14Devices = await prisma.device.findMany({
where: {
androidVersion: "14"
}
});

Update Device Fingerprint

await prisma.device.update({
where: { deviceId: "HT1A12345678" },
data: {
fingerprint: "new-unique-fingerprint"
}
});

Deactivate Offline Devices

await prisma.device.updateMany({
where: {
lastSeenAt: {
lt: new Date(Date.now() - 24 * 60 * 60 * 1000) // Not seen for 24 hours
}
},
data: {
isActive: false
}
});

Device Fingerprinting

Device fingerprints are used to uniquely identify devices and prevent duplicate registrations. The fingerprint is typically generated from:

  • Android ID
  • Build fingerprint
  • Hardware serial
  • Device properties
// Example fingerprint generation
const fingerprint = crypto
.createHash('sha256')
.update(`${androidId}-${buildFingerprint}-${hardwareSerial}`)
.digest('hex');

Device Discovery Process

  1. ADB Device Scan: System scans for connected devices via ADB
  2. Device Information: Retrieves device properties using ADB commands
  3. Fingerprint Check: Generates/checks device fingerprint for uniqueness
  4. Registration: Creates or updates device record
  5. Coordinate Calculation: Calculates screen coordinates for automation

Coordinate System

Device screen coordinates are crucial for UI automation:

interface DeviceCoordinates {
width: number;
height: number;
density: number;
normalizedWidth: number;
normalizedHeight: number;
}

Performance Considerations

Indexing

  • Primary key on id
  • Unique index on deviceId
  • Unique index on fingerprint
  • Index on isActive for active device queries
  • Index on isEmulator for emulator filtering
  • Index on lastSeenAt for activity-based queries
  • Index on brand and model for device type queries

Query Optimization

  • Use select to fetch only needed fields
  • Cache device information to reduce ADB calls
  • Implement device health checks periodically
  • Use connection pooling for database access

Data Management

  • Regular cleanup of inactive devices
  • Archive old device records for analytics
  • Monitor device connection patterns
  • Implement device usage statistics

Migration and Compatibility

ADB Integration

The device model is closely tied to ADB device information:

# ADB device properties
adb -s <deviceId> shell getprop | grep -E "(ro\.product\.|ro\.build\.)"

Emulator Detection

Emulators are identified by:

  • Device ID format: emulator-<port>
  • AVD name presence
  • Emulator-specific properties

Device State Management

Devices can be in various states:

  • Active: Currently connected and usable
  • Inactive: Disconnected but registered
  • Stale: Not seen for extended period
  • Removed: Explicitly removed from system

Monitoring and Alerts

Consider monitoring:

  • Device connection/disconnection events
  • Device health and battery status
  • Screen coordinate changes
  • Device performance metrics
  • ADB connection stability