Device resources¶
Device records use the shared DeviceDescription projection. In the canonical shape,
static facts such as osVersion, runtimeId, and formFactor are top-level, while live state
such as lifecycle, readiness, session, lock, and orientation is grouped under runtime.
Legacy aliases were removed in phase 3, and unknown facts are explicit null values. See
the device-description audit.
Configured-image enrichment is shared by tools and resources. A booted virtual device retains
its configured display, capabilityInventory, deviceType, runtimeId, and Android
image.{path,target,basedOn} provenance when those facts are available. Physical devices and
virtual devices started outside AutoMobile keep unavailable image-only facts as null.
runtime.locked is populated only by the existing Android keyguard probe; otherwise it is
null. runtime.orientation comes from a bounded live orientation probe (Android) and remains
null where no safe read signal exists (currently iOS).
runtime.serviceStatus, when observed, carries the complete service diagnostic: installation,
enablement, running and compatibility flags; nullable installed and expected checksums; structured
runner version; and nullable supportedCommandsComplete / supportedFeaturesComplete flags.
The booted resource’s top-level serviceStatus is a resource-specific diagnostic sibling, not a
DeviceDescription alias. Canonical top-level formFactor always uses phone, tablet,
foldable, or unknown.
DeviceResource describes observed resource state for one device. Its resources
property is a JSON object keyed by logical resource name. AndroidDeviceResource
and AppleDeviceResource add platform-specific keys and preserve AutoMobile’s
android and ios platform identifiers.
The generic base is a shared view and extension point; its default guarantees only
the common keys. Producers of complete platform reports use AndroidDeviceResource
or AppleDeviceResource. Consumers needing platform narrowing accept their union,
AndroidDeviceResource | AppleDeviceResource, rather than widening to the base.
Known map fields are declared explicitly so an unchecked Record<string, ...>
cannot stand in for a complete platform snapshot. Compile-only contract fixtures
run through the normal TypeScript gate. These types do not validate external JSON;
a future I/O boundary must validate incoming data before constructing a report.
The interfaces use structural typing: they require the known fields but do not
strip or reject additional properties on already-assembled objects.
This contract defines reporting semantics. setDeviceResources and the optional
provisionDevice.resources field accept a separate desired configuration and
return verification evidence. Requested configuration is never treated as
observed state.
Resource groups¶
| Key | Platform | Scope |
|---|---|---|
backgroundSync |
Both | OS-scheduled app background refresh/sync, excluding the platform-specific cloud/account service groups below. |
searchIndexing |
Both | OS-maintained search indexes; excludes app-owned indexes. |
animations |
Both | System UI transition animations; excludes app-rendered animation. |
wallpaperRendering |
Both | System wallpaper rendering; excludes widgets and Live Activities. |
widgets |
Both | App and system widget refresh; excludes wallpaper and Live Activities. |
liveActivities |
Both | Live Activities and Dynamic Island updates; excludes wallpaper and widgets. |
googlePlayServices |
Android | Google Play services background infrastructure, including account sync and push; excludes the Play Store app. |
icloudSync |
iOS | OS-managed iCloud data synchronization, including photo sync; excludes app-owned networking. |
photoAnalysis |
iOS | On-device analysis of the system photo library; excludes photo synchronization. |
The groups describe separate functions even when they share infrastructure. For
example, photo sync belongs to icloudSync, while local photo analysis belongs to
photoAnalysis. Common background scheduling and platform-specific account
services may share dependencies; changing one does not establish the other’s state.
Native service names and commands stay inside platform implementations.
Observed state¶
Each concrete platform interface requires its core reporting keys, including on physical devices or images without a particular service. Additional configurable groups are optional in platform snapshots. Key presence does not promise support.
enabled: verified active and available to run; need not be consuming CPU now.disabled: verified disabled to reduce resource use.unsupported: the device cannot provide or control the resource. The optionalreasoncan explain which limitation applies.unknown: not verified. Also use this for mixed or incomplete group evidence, with an optionalreasonexplaining the uncertainty.
A group is enabled or disabled only when evidence covers the whole defined
group. A single inactive process, absent observation, or requested setting is
insufficient. A future producer must define its evidence coverage for each OS and
device type; it must report unknown when that coverage is incomplete.
Desired provisioning configuration is separate from this snapshot. There is no overall mode or profile identity, and callers must not infer that a requested reduction succeeded.
Configuring resources¶
setDeviceResources is disabled by default. Enable it for the MCP session with
setToolEnabled using {"toolName":"setDeviceResources","enabled":true}, or
start AutoMobile with --enable-tool setDeviceResources. Tool names are
case-sensitive. The optional provisionDevice.resources field does not require
enabling the standalone tool.
Both tools accept the same partial map of resource names to enabled or
disabled. Omitted entries remain untouched; an empty map, raw service names,
unknown keys, and profile names are rejected. Ordinary provisioning without
resources preserves existing behavior.
{
"resources": {
"wallpaperRendering": "disabled",
"widgets": "enabled",
"liveActivities": "enabled",
"healthServices": "disabled",
"fitnessServices": "disabled"
}
}
Pass this map to setDeviceResources with the usual session/device targeting,
or add it alongside device in provisionDevice. Provisioning requires
boot: true when resources are supplied and applies settings before automation
readiness. Resource settings participate in the provisioning operation ID’s
fingerprint; retries re-read and reconcile resource state, including after a
completed operation.
setDeviceResources.timeoutMs defaults to 300,000 milliseconds for requests
that configure many services. Provisioning uses its existing shared deadline
for creation, boot, resource configuration, and automation readiness.
Within that deadline, resource configuration reserves time for readiness and
session binding. It cannot consume the whole remaining provisioning budget.
The iOS Simulator implementation controls narrow, disjoint service groups. Wallpaper, widgets, and Live Activities are three independent controls: disabling wallpaper never disables widget updates or Live Activities. No resource is disabled by default. Settings can affect optional system features; they are choices for the test workload, not a claim that every app remains fully functional with every resource disabled.
| Controls | Scope and tradeoff |
|---|---|
wallpaperRendering, widgets, liveActivities |
Separate wallpaper rendering, widget refresh, and Live Activity updates. App widgets need widgets enabled. |
healthServices, homeServices, fitnessServices |
HealthKit/Health, HomeKit, and Fitness background services. Apps using those integrations need them enabled. |
familyServices, screenTime |
Family approvals/parental controls and Screen Time/usage tracking. Keep enabled for restriction tests. |
newsServices, weatherServices, tipsServices, gameServices |
Apple content apps and Game Center/save sync; controller input remains untouched. |
mapsSync |
Maps synchronization and suggested destinations; MapKit rendering and general location services remain untouched. |
advertising, diagnosticReporting |
Promoted Apple content and selected diagnostic reporting. Ad privacy, DeviceCheck, setup state, and feature configuration remain untouched. Disabling reporting reduces diagnostic evidence. |
photoAnalysis |
Only background Photos analysis. Library access, cloud transfers, and shared media-analysis services remain untouched. Photo search and recognition can degrade. |
assistantSuggestions, appleIntelligence |
Selected Siri suggestion and Apple Intelligence background services. Speech, system voices, shared language/model services, and runtime-gated intelligence workflows remain untouched. System intelligence features may degrade. |
searchIndexing |
System search and app-provided Spotlight indexes; excludes an app’s own search service. Settings/Spotlight search may fail. |
appStoreServices, appleMediaSync |
App Store installation/update services and Apple media-library/subscription services; push, generic audio/video transport, and StoreKit payment daemons remain untouched by these controls. |
mailServices, calendarServices, reminderServices, personalDataSync |
Local Mail, Calendar, Reminders, and Exchange/CalDAV/CardDAV sync. Local Contacts access remains untouched. These are separate from apps’ server-side calendars and reminders. |
safariSync, icloudSettingsSync |
Safari history/bookmark sync and selected system-settings sync/storage recommendations. Associated domains, shared credentials, browsing protection, Apple accounts, CloudKit, Drive, and Photos transfers remain untouched. |
messagingMaintenance |
Apple Messages history cleanup/attachment transfer and FaceTime message storage; database XPC helpers, identity, CallKit, and VoIP infrastructure remain untouched. |
watchConnectivity, carPlay, tvRemote, findMy, continuity |
Separate companion/device services. Continuity affects cross-device workflows; system share sheets, keyboard stickers, and avatars remain untouched. |
walletServices, businessServices |
Wallet/payment/digital-identity services and Apple business messaging. Disabling Wallet can also prevent dependent StoreKit payment sheets; keep it enabled for payment tests. |
App-hosted XPC helpers and the runtime-gated intelligence workflow engine remain under OS control; these are not standalone service definitions to force-load.
The shared schema is defined by src/models/deviceResourceDescriptions.ts; native
labels are scoped in src/utils/iosDeviceResourceCatalog.ts. Callers cannot supply
raw launchd labels, shell commands, or arbitrary service paths. Every group is
preflighted against the exact booted runtime before writing. Missing labels are
reported individually and excluded from that runtime’s group; a group with no
installed services is unsupported. A mismatched, default-disabled, or conditional
definition makes the whole group unsupported without mutations. Native read
failures are unknown, not evidence that a service is absent.
For compatible definitions the controller changes the launchd override, unloads or restores the exact job without rebooting, then verifies both the override and job registration. Runtime discovery is shared within a request. Group membership does not overlap, so enabling one resource cannot silently restore another.
Broad backgroundSync and icloudSync remain unsupported. Physical iOS devices
remain unsupported. Android controls are described below; requests can apply
supported entries and report unsupported entries in the same result.
Results contain requested, a resources map of observed states for requested
entries, services with per-daemon evidence, changed (resource groups with
acknowledged native writes), verification: "current_boot",
and success. Only a full match of every requested entry is successful. Native
failures or incomplete evidence produce unknown, never a guessed enabled or
disabled state. Group success requires every installed compatible service to
match; runtime-absent services remain visible as unsupported in services.
Retrying reconciles partial changes. Overrides may survive a
reboot depending on the runtime, but these tools verify only the current boot.
For setDeviceResources, an incomplete result is an MCP tool error with the
evidence intact. Provisioning returns that same result under resources and
also marks the response as an error if configuration is incomplete; it retains
the provisioned device identity and session so the caller can inspect or retry.
Device boot/readiness and resource-configuration success are separate facts.
Booted provisioning responses expose the session as a top-level sessionId
field, with no sessionUuid alias, including resource failures and replayed
operations. With boot: false, no top-level session field is present.
Automation capabilities¶
Resource state does not establish whether screenshots, interaction, notifications, purchases, or other automation capabilities work. Continue to report capabilities separately using AutoMobile’s existing supported/partial/unavailable/unsupported conventions. Only mark a capability unavailable because of a disabled resource when its dependency is known for the device and app context.
Android controls¶
Android emulator controls are independent and opt-in. Optional-app groups disable only installed system packages in a fixed catalog for the current Android user. They preserve ContactsProvider, CalendarProvider, MediaProvider, DocumentsUI, SystemUI, the launcher, credentials, networking and automation packages. Active apps, default role holders, the selected keyboard and enabled accessibility services are protected. If role inspection is unavailable, package disablement fails closed; older Android versions can still support individual settings.
animationssets the three system animation scales to zero or one.screensaverscontrols dream activation, separately from wallpaper and widgets.backupcontrols Backup Manager for the current user.mailApp,calendarApp,contactsApp,mapsApp,videoApp,musicApp,photosApp,assistantApp,digitalWellbeing,printing,accessibilityApps,textToSpeech, andwallpaperAppscontrol optional applications. Disabling an app removes its integrations and intent handlers. Wallpaper picker removal is not equivalent to disabling wallpaper rendering.healthConnect,adServices,onDevicePersonalization,storeApp,dialerApp,messagesApp,googlePlayServicesandgoogleServicesFrameworkare explicit feature tradeoffs. Shared Google infrastructure must remain enabled for workloads that depend on its notifications or authentication. Mainline/APEX containers are never removed.
An Android response can include a restore receipt. Pass it back as
setDeviceResources({restore: receipt, ...deviceTargeting}), without resources,
to restore the exact previous overrides. Receipts are restricted to the same
emulator serial, boot ID and user. This prevents accidental restoration onto a
recycled emulator. They preserve default package state and absent settings;
enabled is an explicit enable operation, not a substitute for restoration.
Default override restoration may report observed state unknown while returning
success: true: the original override was verified, but the runtime’s effective
default was not inferred. Save the receipt from partial-error responses too.
A request cancelled before returning a response may have made partial changes;
inspect/reconcile state rather than assuming rollback. Receipts are not a durable
transaction journal and do not promise restoration across reboot or lost responses.
Android changed records targets for which a native write was attempted. Each
successful target is re-read; failed or ignored writes produce an error result.
No package availability observation proves it consumes CPU, and no resource
configuration result promises measured performance gains.
Android provisioning hardware¶
provisionDevice.device.spec.configuration accepts memoryMb, cpuCores,
gpuMode, screenWidth, screenHeight, screenDensity, cameraFront,
cameraBack, audioInput, and audioOutput. These persist in the AVD configuration
before boot. GPU modes are auto, host, software, swiftshader, lavapipe,
and swangle; actual backend availability depends on the installed emulator and
host. Camera values are none or emulated. Existing modern Play-image minimum
memory checks remain in effect. Replay can reconcile hardware only while the
AVD is stopped; a mismatched running device is an identity conflict.
Headless launch controls the window independently of audio.
AUTOMOBILE_EMULATOR_AUDIO=false passes -no-audio; otherwise the emulator and
AVD audio settings apply. AUTOMOBILE_EMULATOR_HEADLESS retains its existing
platform defaults. This changes the old implicit headless-audio-off behavior.
Audio-dependent workflows can now run headless.
Further Android work and the measurement protocol are tracked in Android emulator optimization.