C1 android_location: last-known GPS via LocationManager across
providers, staleness warning, no fresh-fix requests from background.
C2 android_search_contacts: ContactsContract filter + phone number
resolution, privacy-respecting logging.
C3 android_call: auto-dial via ACTION_CALL on sideload, fallback to
ACTION_DIAL on googlePlay / permission-denied. Destructive-verb
confirmation modal gates every call.
C4 android_send_sms: direct SmsManager.sendTextMessage +
sendMultipartTextMessage with PendingIntent result callback (actual
wait for send completion, not fire-and-forget). API-version-aware
SmsManager retrieval. Voice-to-bridge SendSms intent handler now
emits a real /send_sms bridge.command envelope instead of a
malformed tool.call payload; contact->number resolution marked
TODO(C4) with a sketch since fire-and-forget dispatch lacks
response correlation. Destructive-verb confirmation modal gates
every send.
All four permissions added to app/src/sideload/AndroidManifest.xml
only - NOT the main manifest. Flavor gate via
FeatureFlags.BuildFlavor.isSideload in BridgeCommandHandler. Tools
return 'sideload-only' errors on googlePlay devices. Every call/send
logs the full payload to the safety-rails activity log via the
confirmation modal's method + text fields.
Tests: 39 stdlib-unittest cases across
plugin/tests/test_android_{location,search_contacts,call,send_sms}.py
- happy / denied / timeout / schema coverage for each tool. Existing
test_android_tool.py tool-count assertion bumped 14 -> 18.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>