Project 10: Plugin SDK and IPC Host
Build a versioned Android plugin protocol and a separately installed demo plugin, then prove the host contains untrusted failures and verifies identity at every boundary.
Quick Reference
- Main language: Kotlin
- Alternative language: Java
- Difficulty: Level 4 - Expert
- Estimated time: 28-40 hours
- Primary APIs: bound services, Binder, AIDL or Messenger,
PackageManager - Supporting tools: Gradle multi-repository fixtures, Compose catalog, instrumentation tests
- Main book: Enterprise Integration Patterns by Gregor Hohpe and Bobby Woolf
- Safety boundary: targeted discovery, explicit enrollment, signer trust, bounded versioned messages
1. Learning Objectives
You will learn to:
- Design an Android plugin as a protocol rather than a shared implementation shortcut.
- Compare AIDL, Messenger, intents, and content-provider boundaries.
- Discover candidate plugins through targeted declarations without broad package inventory.
- Verify package, component, signer, protocol version, and declared capability.
- Recheck caller identity on each sensitive Binder request.
- Negotiate compatible protocol ranges before invocation.
- Bound message count, string length, collection size, and payload bytes.
- Correlate request, progress, cancellation, and result.
- Handle Binder death, timeout, malformed replies, and plugin uninstall.
- Prevent replay and confused-deputy behavior.
- Preserve user configuration when a plugin becomes unavailable.
- Build hostile-plugin tests that prove containment.
Mastery signal: The host invokes one enrolled demo capability successfully and rejects or contains wrong-signature, incompatible, oversized, malformed, replayed, timed-out, crashed, and uninstalled plugins.
2. Theoretical Foundation
2.1 A Plugin Boundary Is a Trust Boundary
Separately installed code runs in another application identity and process. Even if you authored both apps, production must assume version skew, crashes, malformed data, compromised builds, replacement packages, and hostile callers.
Do not expose internal repositories or framework objects. Define a narrow message protocol with explicit semantics and failure outcomes.
host domain <-> host adapter <== Binder protocol ==> plugin adapter <-> plugin domain
trust check bounded data caller check
2.2 Why Binder IPC
Binder gives Android process isolation, caller identity, lifecycle signals, and efficient IPC. It does not automatically provide semantic trust, compatible versions, bounded payloads, or safe business behavior.
Candidate approaches:
- AIDL: explicit typed interfaces; best when protocol evolution is disciplined.
- Messenger: serialized message handling; useful for simple command channels.
- Explicit intents: good for coarse fire-and-result interactions.
- Content provider: appropriate for query-like data contracts, not arbitrary execution.
Select one and document why. The learning project can use AIDL or Messenger, but the domain protocol should remain transport-independent.
2.3 Targeted Discovery and Package Visibility
Modern Android limits visibility into installed apps. A plugin host should not request broad inventory merely for convenience. Use a specific intent action or service contract and declare only the narrow queries needed for discovery.
Discovery yields candidates, not trusted plugins. The user should review candidate identity and explicitly enroll one before execution.
2.4 Identity and Signer Trust
A package name alone is not a durable trust guarantee. A plugin enrollment record should bind:
- package name;
- explicit service component;
- accepted signing-certificate digest or lineage policy;
- supported protocol range;
- approved capability IDs;
- enrollment timestamp and user decision.
Re-read current package and signer information before binding and on reconnect. Never trust signer metadata supplied by the plugin itself.
2.5 Caller Authentication
The plugin must also defend itself. On every Binder transaction, it should obtain the actual calling UID, resolve packages associated with that UID, and apply its host trust policy. A field saying callerPackage=trusted.host is merely attacker-controlled data.
Be careful when work is handed to another thread: capture and verify identity at the Binder entry boundary before identity context is lost.
2.6 Version Negotiation
Versioning should describe protocol compatibility, not app marketing versions.
host supports: [2, 4]
plugin supports: [3, 5]
intersection: [3, 4]
selected: highest mutually supported version 4
If the intersection is empty, fail before sending an execution request. Capability versions may evolve independently from the transport protocol.
2.7 Bounded Messages
Binder transactions have practical size limits and share a transaction buffer within a process. A robust protocol defines strict bounds well below platform failure thresholds.
Bound:
- maximum request bytes;
- maximum reply bytes;
- maximum strings and string length;
- maximum collection entries;
- maximum nesting depth;
- maximum progress events;
- maximum execution duration;
- maximum concurrent requests per plugin.
Large data should move through a purpose-built, permission-scoped channel, not an oversized Binder parcel.
2.8 Correlation, Timeout, and Cancellation
Each request needs a host-generated unguessable correlation ID and deadline. The plugin reports one terminal result for that request. Cancellation is best-effort but explicit. A late reply after timeout must not resurrect a completed host run.
The host owns its deadline. A plugin cannot extend it by continually sending progress.
2.9 Binder Death and Process Failure
Binding can fail, the remote process can die, or a transaction can throw. Link to death where appropriate, but still model all remote calls as fallible. After death:
- mark active requests with a typed plugin-unavailable outcome;
- clear transient proxy references;
- release connection resources;
- apply bounded rebind policy;
- reverify identity before future use.
2.10 Confused Deputy and Scope
A confused deputy occurs when a less-privileged caller convinces a privileged component to act on its behalf. Prevent it by validating the real caller, authorizing named capabilities, bounding arguments, and refusing generic shell, intent, file, or network execution.
A plugin action should be a narrow operation such as transform.text_length, not execute_arbitrary_command.
2.11 Replay Defense
A request ID that has already reached a terminal state must not execute again accidentally. Maintain a bounded replay ledger per enrolled plugin or require the plugin to enforce idempotency for its capability. Define expiry and process-death behavior explicitly.
2.12 Common Misconceptions
Misconception: Package name is sufficient authentication.
Correction: verify installed signer and actual Binder caller identity.
Misconception: AIDL makes a protocol backward compatible.
Correction: wire typing does not replace version negotiation and semantic evolution rules.
Misconception: Discovery means a plugin is trusted.
Correction: discovery produces untrusted candidates that require validation and enrollment.
Misconception: Binder calls are local and therefore reliable.
Correction: remote process death, timeouts, and malformed behavior are normal cases.
Misconception: The plugin can report its own signer.
Correction: identity evidence must come from trusted platform APIs.
2.13 Key Terms
- Binder: Android kernel-mediated IPC mechanism.
- AIDL: interface definition language for Binder contracts.
- Caller UID: OS identity of the process making the Binder call.
- Signer digest: fingerprint derived from an installed package’s signing certificate.
- Capability ID: stable name for a narrow plugin-provided operation.
- Protocol range: minimum and maximum compatible protocol versions.
- Binder death: loss of the remote process hosting an IPC endpoint.
- Confused deputy: privileged component tricked into misusing its authority.
- Replay: repeated processing of a previously accepted request.
- Enrollment: explicit user decision to trust a validated plugin identity and scope.
3. Project Specification
3.1 What You Will Build
Build two separately installed applications:
Plugin Host
- targeted discovery catalog;
- identity and signer inspection;
- explicit enrollment workflow;
- protocol negotiation;
- capability catalog;
- test invocation UI;
- typed result and diagnostic viewer;
- disabled-state handling after uninstall or trust change.
Demo Plugin
- one synthetic trigger capability;
- one action capability named
transform.text_length; - host caller verification;
- bounded request parser;
- cancellation and timeout cooperation;
- debug-only hostile behavior modes for tests.
3.2 Functional Requirements
- Discover only services matching the exact plugin contract.
- Show package, service, signer digest, protocol range, and capabilities.
- Require explicit enrollment before binding for execution.
- Persist trusted signer and approved scopes.
- Reverify installed identity before every new connection.
- Negotiate one protocol version from the intersection.
- Send bounded versioned requests with correlation IDs and deadlines.
- Return typed success and failure results.
- Support cancellation.
- Detect Binder death and timeout.
- Reject replayed request IDs.
- Reject malformed, oversized, or unknown fields according to protocol rules.
- Safely disable dependent rules when plugin is uninstalled.
- Preserve those rules for later repair or re-enrollment.
3.3 Non-Functional Requirements
- No
QUERY_ALL_PACKAGESdependency. - No generic command, shell, file, or arbitrary-intent capability.
- No sensitive data in the demo protocol.
- Every external collection and string has a maximum size.
- Every call has a deadline.
- Remote code cannot block the host main thread.
- Diagnostics identify the plugin and correlation without exposing payload content.
- Host and plugin tests can run from independently versioned fixtures.
3.4 Demo Interaction
Candidate plugin
package: dev.example.lengthplugin
service: .AutomationPluginService
signer: sha256/9C:...
protocol: 2..3
capabilities: transform.text_length
trust: not enrolled
User enrolls capability: transform.text_length
Request
protocol: 3
request_id: req-17
input: synthetic text, 12 bytes
deadline: 2 seconds
Result
request_id: req-17
status: completed
output: length=12
Hostile case:
Result: plugin_rejected
Reason: signer_changed
Dependent rule: disabled, configuration preserved
Resolution: review and enroll the new signer explicitly
3.5 Hostile Test Modes
- wrong signer fixture;
- incompatible protocol range;
- malformed catalog;
- unknown capability;
- oversized request demand;
- oversized response;
- delayed response past deadline;
- plugin process crash;
- duplicate terminal response;
- replayed request ID;
- uninstall during an active request.
3.6 Real-World Outcome
A reviewer installs the host and demo plugin, sees a targeted candidate, reviews signer and capabilities, enrolls only the text-length action, and completes a correlated request. The reviewer then runs every hostile mode and observes typed containment. Uninstalling the plugin disables, but does not erase, dependent automation rules.
4. Solution Architecture
4.1 High-Level Architecture
Android PackageManager
|
targeted intent query
|
candidate catalog
|
identity + signer verifier
|
user enrollment store
|
automation rule --> plugin host gateway
|
protocol/version negotiator
|
request limiter + correlator
|
Binder client adapter
====================== process boundary ======================
Binder service stub
|
actual caller UID + signer check
|
bounded protocol decoder
|
capability authorization
|
demo plugin action executor
|
correlated typed result
4.2 Component Responsibilities
| Component | Responsibility | Must Not Do |
|---|---|---|
| Discovery adapter | query exact declared plugin contract | enumerate all packages |
| Identity verifier | read component and signer from platform | trust plugin self-report |
| Enrollment store | bind user trust to identity and scope | auto-trust new signer |
| Negotiator | select mutual protocol version | guess compatibility |
| Host gateway | enforce bounds, deadline, correlation | call remote service on main thread |
| Binder adapter | transport typed messages | expose host internals |
| Plugin caller guard | verify real calling UID | trust request package field |
| Capability registry | authorize named operations | expose arbitrary execution |
| Replay ledger | reject completed request IDs | grow without expiry bound |
| Health projector | disable unavailable dependencies | delete user configuration |
4.3 Discovery Manifest Contract
Illustrative configuration, not a copy-paste production manifest:
<queries>
<intent>
<action android:name="dev.example.AUTOMATION_PLUGIN" />
</intent>
</queries>
<service
android:name=".AutomationPluginService"
android:exported="true">
<intent-filter>
<action android:name="dev.example.AUTOMATION_PLUGIN" />
</intent-filter>
</service>
Production design must add an appropriate signature permission or equivalent trust control and validate actual callers.
4.4 Protocol Schemas
PluginDescriptor {
protocolMin
protocolMax
pluginInstanceId
capabilities[]
maxRequestBytes
maxConcurrentRequests
}
CapabilityDescriptor {
capabilityId
capabilityVersion
inputSchemaId
outputSchemaId
declaredEffects
}
PluginRequest {
protocolVersion
requestId
capabilityId
capabilityVersion
deadlineElapsed
payload
}
PluginResult {
protocolVersion
requestId
status
boundedPayload?
typedError?
}
4.5 Enrollment Record
PluginEnrollment {
packageName
serviceComponent
acceptedSignerDigest
signerLineagePolicy
approvedCapabilities[]
protocolRangeAtEnrollment
enrolledAt
status
}
4.6 Host Invocation Algorithm
resolve enrollment by plugin ID
query current explicit service component
verify package and current signer against enrollment
bind using explicit component
obtain descriptor within handshake deadline
validate descriptor bounds and negotiate version
verify requested capability is enrolled and advertised
create request ID and monotonic deadline
record in-flight request before dispatch
send bounded request off main thread
accept at most one matching terminal result before deadline
on timeout, death, mismatch, or malformed data: close request with typed failure
ignore late terminal replies
4.7 Plugin Entry Algorithm
on Binder entry:
capture actual calling UID
verify UID resolves to an enrolled trusted host signer
parse message within size and structure bounds
validate negotiated version and capability scope
reject replayed request ID
enforce concurrency and deadline
execute named capability only
emit one bounded correlated terminal result
4.8 Failure Taxonomy
| Class | Examples | Host behavior |
|---|---|---|
| identity | signer changed, component moved | reject and require review |
| compatibility | no version intersection | disable with upgrade guidance |
| protocol | malformed, unknown, oversized | reject and record safe diagnostic |
| availability | bind failure, crash, uninstall | fail active run; retain configuration |
| timing | handshake or execution timeout | cancel, close correlation, ignore late reply |
| authorization | unapproved capability, wrong caller | deny without execution |
| replay | duplicate request or result | reject or ignore by terminal state |
4.9 Critical Invariants
- Discovery never implies trust.
- Package name alone never implies signer identity.
- Every sensitive Binder entry validates actual caller identity.
- Every request is bounded, correlated, timed, and scoped.
- No remote call blocks the main thread.
- Exactly one terminal result closes a request.
- Late replies cannot revive timed-out work.
- Plugin loss disables dependent execution without deleting rules.
5. Implementation Guide
5.1 Environment Setup
- Use current stable Android Studio and SDK Platform 36.
- Create host and plugin as separately installable apps.
- Use independent application IDs and signing fixtures.
- Generate at least two debug keystores for signer-change tests.
- Add a second plugin fixture with incompatible protocol range.
- Use an emulator without personal data.
5.2 Suggested Repository Structure
plugin-lab/
protocol-spec/
schemas/
compatibility.md
limits.md
host-app/
discovery/
identity/
enrollment/
negotiation/
gateway/
health/
ui/
demo-plugin/
caller-guard/
protocol/
capabilities/
hostile-fixtures/
tests/
5.3 Core Question
How can separately installed automation plugins cooperate without becoming a confused deputy, a brittle shared implementation, or an unbounded crash path?
5.4 Concepts to Understand First
- Android application UID and process isolation.
- Bound-service and Binder lifecycle.
- AIDL or Messenger transport semantics.
- Package visibility and targeted queries.
- APK signing identity and certificate rotation.
- Protocol compatibility and schema evolution.
- Deadlines, cancellation, replay, and backpressure.
- Capability-based authorization.
5.5 Design Questions
- Why is the chosen transport appropriate?
- What exactly makes a candidate trusted?
- How does the plugin authenticate the actual host caller?
- What are every message’s explicit bounds?
- Which fields may be ignored for forward compatibility?
- Which unknown fields or values must fail closed?
- How is one terminal result enforced?
- What happens to rules after signer change or uninstall?
- How does certificate rotation affect enrollment?
5.6 Thinking Exercise
Trace platform identity, durable state, transient state, and final outcome for:
- valid plugin first enrollment;
- attacker installs a same-looking package with another signer;
- plugin upgrades from protocol 2..3 to 3..4;
- plugin sends a result after host timeout;
- host process dies after dispatch;
- plugin process dies during execution;
- plugin is uninstalled while a rule references it;
- request ID is replayed after a successful result.
5.7 Interview Questions
- Why is an AIDL interface not a complete security boundary?
- How do you authenticate a Binder caller?
- Why should plugin discovery be targeted?
- How do you evolve a plugin protocol safely?
- What happens when the remote Binder dies?
- How do deadlines and correlation prevent stale replies?
- What is the confused-deputy risk in an automation host?
5.8 Hints in Layers
Hint 1 - Write the protocol before apps
Define messages, limits, errors, and compatibility examples.
Hint 2 - Build discovery without binding
Catalog candidates and verify identity first.
Hint 3 - Add explicit enrollment
Persist signer and capability scope from a user decision.
Hint 4 - Implement one tiny capability
Text length is deterministic, bounded, and harmless.
Hint 5 - Make the plugin hostile
Reliability evidence comes from malformed, slow, and crashing fixtures.
5.9 Books That Will Help
| Topic | Book | Suggested focus |
|---|---|---|
| Messaging | Enterprise Integration Patterns | request/reply, correlation, adapters |
| Security | Security Engineering | trust boundaries and authentication |
| Reliability | Release It! | remote calls, timeouts, bulkheads |
| Evolution | Building Evolutionary Architectures | compatibility and fitness functions |
5.10 Implementation Phases
Phase 1 - Protocol specification
- Choose AIDL or Messenger.
- Define descriptor, request, result, and error schemas.
- Define compatibility rules.
- Define strict size and timing limits.
Phase 2 - Targeted discovery
- Declare the exact plugin intent query.
- Resolve matching service candidates.
- Read package and signer from platform APIs.
- Display an untrusted catalog.
Phase 3 - Enrollment
- Show identity and capabilities.
- Record explicit user approval.
- Bind approval to signer and component.
- Approve only selected capability IDs.
Phase 4 - Demo plugin guard
- Verify actual caller UID.
- Resolve trusted host signer.
- Add concurrency and replay limits.
- Reject untrusted entry before parsing expensive data.
Phase 5 - Handshake and negotiation
- Bind by explicit component.
- Retrieve a bounded descriptor.
- Compute version intersection.
- Reject incompatibility before execution.
Phase 6 - Request pipeline
- Create correlation and deadline.
- Validate request bounds.
- Dispatch off main thread.
- Accept one correlated terminal result.
Phase 7 - Failure containment
- Handle timeout and cancellation.
- Link to remote death.
- Ignore late and duplicate replies.
- Reverify identity before rebind.
Phase 8 - Hostile fixtures
- Change signer.
- Change protocol range.
- Send malformed and oversized data.
- Delay, crash, replay, and uninstall.
Phase 9 - Rule integration
- Reference plugin and capability IDs in a rule.
- Disable execution when unhealthy.
- Preserve configuration and resolution guidance.
- Restore only after trust revalidation.
5.11 Key Decisions
- Protocol contract instead of shared internals.
- Targeted discovery instead of broad inventory.
- Platform-derived signer evidence.
- User enrollment scoped to capabilities.
- Actual Binder caller verification.
- Strict message and concurrency bounds.
- Monotonic deadlines and one terminal result.
- Safe degradation without configuration loss.
6. Testing Strategy
6.1 Protocol Contract Tests
- Lowest supported mutual version succeeds.
- Highest supported mutual version succeeds.
- Empty version intersection fails.
- Required unknown enum value fails safely.
- Permitted unknown optional field is ignored.
- Strings, lists, nesting, and payload bytes respect limits.
- Exactly one terminal result is accepted.
6.2 Identity Tests
- Enrolled package and signer succeed.
- Same package fixture with different signer fails.
- Component change requires policy evaluation.
- Plugin-supplied signer claim is ignored.
- Plugin rejects host fixture with wrong signer.
- Caller package field cannot spoof actual Binder UID.
6.3 Lifecycle Tests
- Bind, invoke, unbind, and rebind.
- Kill plugin before handshake.
- Kill plugin during request.
- Kill host after dispatch.
- Uninstall plugin during request.
- Reinstall with same signer.
- Reinstall with different signer.
6.4 Hostile Protocol Tests
- Malformed descriptor.
- Oversized capability catalog.
- Unknown capability response.
- Mismatched correlation ID.
- Duplicate terminal result.
- Result after deadline.
- Progress flood.
- Replay of completed request ID.
- Plugin refuses cancellation.
6.5 Rule-Degradation Tests
- Referenced plugin unavailable at startup.
- Plugin uninstalled while rule enabled.
- Signer changes after enrollment.
- Protocol becomes incompatible after upgrade.
- Capability disappears from catalog.
- Configuration survives every case.
- Execution resumes only after valid resolution.
6.6 Security Review Checklist
- Enumerate exported components.
- Verify explicit binding.
- Verify signer lookup uses platform state.
- Verify actual caller UID at Binder entry.
- Verify no arbitrary command capability.
- Verify strict message limits.
- Verify diagnostics contain no request payload.
- Verify replay ledger is bounded.
6.7 Acceptance Transcript
Save a transcript for valid enrollment and invocation plus wrong signer, no version overlap, malformed, oversized, timeout, crash, replay, late result, and uninstall. Include correlation IDs, typed outcomes, and rule-health projections.
7. Common Pitfalls & Debugging
Problem 1: Candidate never appears
- Why: intent query, service action, exported state, or package visibility differs.
- Fix: compare the exact action and resolve through
PackageManagerdiagnostics. - Quick test: install only the demo plugin and query the explicit contract.
Problem 2: Host trusts a replacement build
- Why: enrollment stored only package name.
- Fix: bind trust to platform-derived signer evidence and recheck it.
- Quick test: reinstall a same-ID hostile fixture signed differently.
Problem 3: Plugin accepts a spoofed host field
- Why: it trusts message data rather than Binder caller UID.
- Fix: authenticate at the Binder entry boundary.
- Quick test: invoke from an untrusted caller claiming the host package.
Problem 4: Host freezes on a plugin call
- Why: remote work runs on the main thread or lacks a deadline.
- Fix: isolate calls and close them on host-owned deadlines.
- Quick test: enable delayed hostile mode while profiling UI responsiveness.
Problem 5: Late result changes a failed run to success
- Why: correlation state remains open after timeout.
- Fix: terminally close the request and ignore later replies.
- Quick test: deliver success one second after deadline.
Problem 6: Uninstall deletes rules
- Why: plugin health is coupled to rule identity.
- Fix: retain configuration and project an unavailable dependency.
- Quick test: uninstall and reinstall the enrolled plugin.
Problem 7: Large parcel fails unpredictably
- Why: protocol has no conservative payload bounds.
- Fix: validate before transport and use a different channel for large data.
- Quick test: exercise values immediately below and above each documented limit.
8. Extensions & Challenges
Extension 1: Capability Schema Registry
Add versioned schemas for a few harmless synthetic operations and compatibility fixtures.
Extension 2: Certificate Rotation Policy
Model signing-certificate lineage and require explicit rules for accepted rotation.
Extension 3: Plugin Health Dashboard
Show last handshake, version, latency, death count, timeout count, and disabled dependencies.
Extension 4: Fuzzed Decoder Fixtures
Generate bounded malformed messages and prove parsers fail without crashing either app.
Extension 5: SDK Documentation
Publish a protocol-only developer guide with limits, threat model, conformance tests, and sample transcripts.
Forbidden Extensions
- Arbitrary shell or ADB execution.
- Generic file-system or intent proxying.
- Broad package inventory for discovery.
- Auto-trusting any package with a matching name.
- Unbounded payloads, concurrency, retries, or execution time.
9. Real-World Connections
Android plugin ecosystems appear in automation apps, keyboards, launchers, password managers, enterprise tools, and media applications. Sustainable ecosystems require a stable protocol, independent release cadence, conformance tests, trust enrollment, compatibility telemetry, and deprecation policy.
The lessons also apply to microservices and browser extensions: network or process isolation creates a boundary, but the protocol still needs authentication, authorization, limits, timeouts, correlation, and evolution rules.
Production Gap Analysis
| Learning build | Production requirement |
|---|---|
| one demo plugin | third-party SDK governance and review |
| debug signer fixtures | release signing and rotation operations |
| local catalog | localized consent and support diagnostics |
| one protocol version family | deprecation windows and compatibility telemetry |
| simple replay ledger | durable idempotency and abuse controls |
10. Resources
Official Android Documentation
- Bound services overview
- AIDL
- Messenger-based bound service
- Binder reference
- Package visibility overview
- Package visibility use cases
- PackageManager reference
- App signing
- Intents and intent filters
Official Policy
- Google Play package visibility policy
- Google Play Developer Program Policies
- Device and Network Abuse policy
Suggested Reading Order
- Read bound-service and Binder lifecycle guidance.
- Compare AIDL and Messenger.
- Study package visibility and narrow query use cases.
- Review signing identity and rotation.
- Revisit the parent guide’s IPC, security, and observability chapters.
11. Self-Assessment Checklist
Knowledge
- I can explain why IPC is a trust boundary.
- I can compare AIDL, Messenger, and explicit intents.
- I understand package visibility and targeted discovery.
- I can authenticate an actual Binder caller.
- I can explain version intersection and Binder death.
Design
- Discovery, validation, enrollment, and execution are distinct phases.
- Enrollment binds package, component, signer, and capability scope.
- Every message and execution dimension has a bound.
- Every request has correlation, deadline, and cancellation semantics.
- The protocol exposes no arbitrary execution primitive.
Verification
- I tested wrong signer and wrong caller.
- I tested incompatible versions.
- I tested malformed and oversized messages.
- I tested timeout, crash, replay, and late reply.
- I tested uninstall without rule deletion.
Reflection
- I can defend the selected transport.
- I documented certificate-rotation assumptions.
- I can identify one confused-deputy path that was closed.
- I can describe how protocol version 4 could evolve safely.
12. Submission / Completion Criteria
Submit:
- Protocol specification with compatibility rules.
- Complete message, size, concurrency, and timing limits.
- Targeted discovery and package-visibility design.
- Identity, signer, and caller-authentication threat model.
- Enrollment and capability-scope schema.
- Host and plugin sequence diagram.
- Failure taxonomy and recovery rules.
- Hostile-fixture automated test report.
- Redacted acceptance transcript.
- SDK conformance checklist for future plugin authors.
Definition of Done
- Targeted discovery works without broad package inventory.
- Package, component, signer, protocol range, and capability scope are verified.
- Sensitive Binder entries authenticate the actual caller.
- Requests are versioned, bounded, correlated, timed, cancellable, and replay-aware.
- Wrong signer, incompatible version, malformed, oversized, timeout, crash, replay, and late reply are contained.
- Remote calls never block the host main thread.
- Exactly one terminal result closes each request.
- Plugin uninstall safely disables dependent rules without deleting configuration.
- No arbitrary command or confused-deputy primitive exists.
- Another developer can implement a conforming plugin from the protocol document alone.
Expanded from ANDROID_AUTOMATION_APPS_MASTERY.md. For the complete learning path, see the parent guide.