Project 1: Capability Navigator

Build a read-only-first control plane that explains what an Android automation app can do now, what requires user action, and why.

Quick Reference

Attribute Value
Difficulty Level 1 — Beginner
Time Estimate 10-14 hours
Language Kotlin; Java is a viable alternative for platform checkers
Prerequisites Kotlin basics, Android components, Compose state, basic testing
Key Topics Capability modeling, permissions, special access, lifecycle, consent UX, compatibility

1. Learning Objectives

By completing this project, you will:

  1. Distinguish platform support, declared authority, user consent, service health, and administrative mode.
  2. Model capability state as an exhaustive domain result rather than a Boolean permission flag.
  3. Build consent journeys that start with explanation and end with verification.
  4. Refresh capability truth after lifecycle changes, process recreation, and external Settings changes.
  5. Reuse one capability registry from both Compose UI and headless execution code.
  6. Explain safe degradation when an optional capability is denied or revoked.
  7. Test unsupported, denied, temporarily unavailable, and policy-managed states without broad access.

2. Theoretical Foundation

2.1 Core Concepts

Capability versus permission

A permission is one possible gate. A capability is the complete answer to whether a specific operation can be attempted safely. The answer can depend on API level, hardware feature, manifest declaration, runtime permission, app-op, special Settings access, enabled service, package role, one-session consent token, current connection health, or enterprise provisioning. The registry must retain this richer meaning.

Static support versus dynamic authority

Static checks answer whether the installed build and device could support a feature. Dynamic checks answer whether the app may use it now. Notification-listener support can exist while access is disabled. Exact-alarm APIs can exist while special access is absent. Device-policy APIs can exist while a normal consumer install has no owner authority.

Process lifetime and re-verification

An Android process is disposable. Cached capability truth can become false while the app is backgrounded. The user may revoke access in Settings, a service may disconnect, policy may change, or the package may be updated. A lifecycle return is therefore a signal to observe reality again, not proof that the previous result remains valid.

Consent journey

A trustworthy journey contains purpose, data scope, visible behavior, denial behavior, system transition, return verification, and revocation instructions. It requests authority only when the user enables a dependent feature. A consent journey is not a splash-screen checklist and does not repeatedly nag after denial.

Evidence-bearing state

Every state needs a reason code and evidence. Needs consent because notification access is disabled differs from temporarily unavailable because the listener is enabled but disconnected. Unsupported because the API is missing differs from misconfigured because the manifest component was omitted.

2.2 Why This Matters

Tasker-style products combine many unrelated Android authority systems. If every adapter invents its own permission check, the editor, executor, and support UI will disagree. Users see actions that cannot run, background code attempts forbidden work, and diagnostics reduce everything to permission denied.

A capability control plane prevents that drift. The rule editor can mark an action unavailable without deleting it. The executor can reject stale authority before a side effect. The support screen can show the exact failing gate. Product copy can promise only what the current installation mode supports.

This architecture also limits pressure to request everything during onboarding. Users can explore an automation in simulation, understand its requirement, and decide whether that single benefit justifies the access. Denial becomes a normal modeled state.

2.3 Historical Context / Background

Early Android applications often treated manifest declarations as the primary authority story. Runtime permissions, special app access, package roles, background limits, target-SDK behavior changes, and policy controls gradually made that model incomplete. Modern automation software must coordinate multiple Settings surfaces and service lifecycles while remaining truthful across API levels and OEM variations.

This progression is a security feature, not an obstacle to route around. Android separates high-impact authority from ordinary app installation so the user or administrator retains control. Capability-aware design accepts that authority can be absent or revoked.

2.4 Common Misconceptions

  • A granted permission means the feature is healthy: a user-enabled service may be disconnected or unavailable in the current profile.
  • An API existing means a normal app can use it: device owner, privileged permissions, shell, and root are separate installation identities.
  • The app should request all access once: progressive journeys are clearer, safer, and easier to justify.
  • Returning from Settings means success: the app must recheck current state.
  • Unsupported and denied are equivalent: one may be resolvable by the user; the other may require a different device or product mode.
  • A service runs forever: process and service lifetime remain system-controlled.

3. Project Specification

3.1 What You Will Build

Build a Compose application with a capability dashboard, detail sheet, consent-journey coordinator, debug-state simulator, and reusable registry. Include these capability families:

  1. Ordinary runtime permission.
  2. Notification-listener access.
  3. Usage access.
  4. Exact-alarm access.
  5. Accessibility-service enablement.
  6. MediaProjection session capability.
  7. Plugin/package availability.
  8. Managed-device authority.

The first release remains read-only for sensitive services. It observes and explains state; it does not implement notification collection, UI automation, capture, or policy changes.

3.2 Functional Requirements

  1. Capability catalog: Render every descriptor in a stable category and order.
  2. Exhaustive status: Show Available, Needs consent, Temporarily unavailable, Unsupported, Policy-managed, or Misconfigured.
  3. Reason evidence: Present a machine-stable reason code and human explanation.
  4. Resolution metadata: Offer a system journey only when a safe handler exists.
  5. Progressive disclosure: Explain purpose, observed data, visible indicator, degraded mode, and revocation before leaving the app.
  6. Return verification: Refresh after Settings or consent activity returns.
  7. Lifecycle refresh: Recheck on foreground return without creating a request loop.
  8. Debug simulation: Override checker results in debug builds only.
  9. Headless query: Allow later executors to ask for one capability without depending on Compose.
  10. Safe fallback: Show manual navigation instructions when an OEM has no matching Settings intent.

3.3 Non-Functional Requirements

  • Privacy: No capability grant is requested at launch and no sensitive source data is collected.
  • Reliability: A failed checker yields typed diagnostic state rather than crashing the dashboard.
  • Usability: Every card answers what, why, current state, next step, and how to revoke.
  • Accessibility: Status is communicated through text and semantics, not color alone.
  • Compatibility: Checkers isolate API-level differences behind one domain port.
  • Testability: Platform reads and resolution launchers are replaceable with fakes.

3.4 Example Usage / Output

Automation capabilities

Notification access
Status: NEEDS CONSENT
Evidence: notification listener is declared but not enabled
Data if enabled: package, channel, selected notification fields
Degraded behavior: notification-triggered rules remain disabled
[Review access]

Managed device
Status: POLICY-MANAGED
Evidence: app is not profile owner or device owner
Resolution: no consumer consent journey exists

3.5 Real World Outcome

Open the app and land on a dashboard grouped into Signals, Timing, Interaction, Integrations, and Administration. Each card has an icon, title, status label, one-line evidence, and disclosure arrow. The status remains understandable in grayscale and under TalkBack.

Expand Notification access. The sheet explains that future notification rules can observe only packages selected by the user, that access is enabled in system Settings, and that revocation disables dependent rules without deleting them. Press Review access. The system settings page opens. Return without enabling it; the card still says Needs consent and does not nag.

Use the debug drawer to simulate service disconnected. The same card changes to Temporarily unavailable and reports that authority exists but runtime health is absent. Simulate a missing manifest component; it becomes Misconfigured and offers no misleading Settings action.

Rotate the device, background the app, alter a grant in Settings, and return. The dashboard rechecks automatically and preserves only presentation state. Force-stop and reopen; the result is reconstructed from platform reality. Install on an older emulator or fake an unsupported API and confirm the card explains the missing platform requirement.


4. Solution Architecture

4.1 High-Level Design

                  +----------------------+
                  | Compose dashboard    |
                  | cards + detail sheet |
                  +----------+-----------+
                             |
                             v
                  +----------------------+
                  | Capability registry  |
                  | query / observe all  |
                  +----+------------+----+
                       |            |
              static checkers   dynamic checkers
                       |            |
             API / feature /   grant / service /
             manifest support   role / owner state
                       |            |
                       +------+-----+
                              |
                              v
                 CapabilityAssessment
                 state + reason + evidence
                              |
              +---------------+----------------+
              |                                |
     consent journey coordinator      headless executor gate
              |
      system surface -> return -> recheck

4.2 Key Components

Component Responsibility Key Decisions
CapabilityDescriptor Stable identity and product metadata Contains no Android Context or live grant
CapabilityChecker Reads one platform capability Returns evidence-bearing assessment
CapabilityRegistry Queries, combines, and observes checkers Single source for UI and executor
ConsentJourney Describes rationale, scope, resolution, denial, revocation Separate from checker
JourneyCoordinator Launches resolvable system surfaces and rechecks Never assumes result from navigation
CapabilityViewModel Converts registry stream into immutable screen state Survives configuration changes
DebugOverrideSource Produces deterministic fake states Removed or disabled in release

4.3 Data Structures

CapabilityDescriptor
  id
  category
  title
  required_platform
  data_classes
  degraded_behavior

CapabilityAssessment
  capability_id
  state
  reason_code
  evidence
  checked_at
  resolution_descriptor optional

CapabilityState
  AVAILABLE
  NEEDS_CONSENT
  TEMPORARILY_UNAVAILABLE
  UNSUPPORTED
  POLICY_MANAGED
  MISCONFIGURED

Do not serialize Android Intent objects into the domain result. A resolution descriptor names an abstract journey; the Android layer builds and verifies the actual system intent.

4.4 Algorithm Overview

Key Algorithm: Assess One Capability

  1. Load the stable descriptor.
  2. Check minimum API and required device features.
  3. Confirm build-time manifest declarations or components.
  4. Check current grant, role, service enablement, session state, or owner mode.
  5. Check transient health when the capability has a connection lifecycle.
  6. Select the most specific state and reason code.
  7. Attach a resolution only when user action can legitimately change the state.
  8. Timestamp and emit the immutable assessment.

Complexity Analysis:

  • Time: O(C) for a full refresh across C capabilities, assuming each checker performs bounded platform queries.
  • Space: O(C) for the current assessment snapshot.

5. Implementation Guide

5.1 Development Environment Setup

$ adb devices
List of devices attached
emulator-5554    device

$ adb shell getprop ro.build.version.sdk
36

Use the current stable Android Studio, SDK Platform 36 reference emulator, an older supported emulator, Compose, lifecycle libraries, and Android test tooling. Do not enable broad sensitive capabilities merely to complete setup.

5.2 Project Structure

capability-navigator/
├── app/
│   ├── ui/capabilities/
│   ├── navigation/
│   └── platform/journeys/
├── capability-domain/
│   ├── descriptor/
│   ├── assessment/
│   └── registry/
├── capability-android/
│   ├── runtime-permission/
│   ├── special-access/
│   ├── service-state/
│   └── managed-mode/
└── tests/
    ├── domain/
    ├── instrumented/
    └── fixtures/

5.3 The Core Question You Are Answering

What does this app actually have the authority to do right now, and how can it explain that truth to both the user and the executor?

Before implementation, write one sentence distinguishing support, authority, and health. If those collapse into one Boolean, redesign the model.

5.4 Concepts You Must Understand First

Stop and research these before coding:

  1. Android process and component lifetime
    • What survives configuration change but not process death?
    • Why is a service not an immortal daemon?
    • Book Reference: Operating Systems: Three Easy Pieces — Processes.
  2. Permission classes
    • Which permissions use an in-app dialog?
    • Which use Settings, roles, session consent, or provisioning?
    • Official Reference: Android permissions overview.
  3. State machines and sealed results
    • How does exhaustive rendering prevent hidden fallbacks?
    • What evidence should accompany each state?
    • Book Reference: Effective Java, 3rd Edition — Items 15-25.
  4. Lifecycle-aware observation
    • When should the registry refresh?
    • How will duplicate resume signals be coalesced?
  5. Consent UX
    • Can the user understand purpose before leaving for Settings?
    • Can they find revocation instructions later?

5.5 Questions to Guide Your Design

  1. Which checks are static and which can change while the app is backgrounded?
  2. Which state wins when the API is supported but the manifest is wrong?
  3. What distinguishes enabled service from connected service?
  4. Can a consumer user resolve a policy-managed state?
  5. How will OEM-specific missing handlers degrade?
  6. Does denial preserve the future rule configuration?
  7. Can headless execution obtain the same reason code shown by the UI?
  8. How will debug overrides remain impossible in release?

5.6 Thinking Exercise

Draw Four Authority State Machines

Draw runtime location, notification access, MediaProjection, and device owner. For each transition, label the actor: app, user, system, or administrator.

Questions to answer:

  • Which state can the app request directly?
  • Which requires leaving the app?
  • Which exists only for one session?
  • Which cannot be reached by a normal consumer install?
  • What happens to a dependent rule after revocation?

5.7 The Interview Questions They Will Ask

  1. How are dangerous runtime permissions different from special app access?
  2. How do you detect revocation that occurs outside your activity?
  3. Why can a normal app not request device-owner status?
  4. How would you test a Settings-based consent journey?
  5. Why should a capability result contain evidence?
  6. What changes when target SDK increases?

5.8 Hints in Layers

Hint 1: Begin read-only

Render platform truth before adding any resolution action.

Hint 2: Separate descriptor from assessment

Product metadata is stable; current authority is observed.

Hint 3: Separate checker from journey

The checker never launches UI. The coordinator never invents truth.

Hint 4: Recheck, do not infer

Navigation back from Settings only means the user returned.

5.9 Books That Will Help

Topic Book Chapter
Immutable API state Effective Java, 3rd Edition Items 15-25
Process lifetime Operating Systems: Three Easy Pieces Processes
Access control Foundations of Information Security Access control chapters
Boundary design Clean Architecture Component boundaries

5.10 Implementation Phases

Phase 1: Read-Only Domain and Dashboard (3-4 hours)

Goals:

  • Define descriptors, states, reasons, and evidence.
  • Render fake assessments in Compose.

Tasks:

  1. Create seven or more stable capability descriptors.
  2. Build card, detail, empty, loading, and error states.
  3. Add fake registry scenarios for every state.

Checkpoint: A screenshot test renders every state without Android authority.

Phase 2: Platform Checkers and Journeys (4-6 hours)

Goals:

  • Replace selected fakes with real read-only checks.
  • Add one complete Settings journey.

Tasks:

  1. Implement bounded checkers behind ports.
  2. Verify resolution intent availability.
  3. Add rationale, system transition, and return recheck.

Checkpoint: Grant and revoke one capability externally; the same card updates correctly.

Phase 3: Lifecycle, Compatibility, and Polish (3-4 hours)

Goals:

  • Survive recreation and handle unsupported paths.
  • Make evidence accessible and testable.

Tasks:

  1. Add lifecycle refresh and duplicate-signal coalescing.
  2. Test old API and missing-handler fixtures.
  3. Add debug overrides, TalkBack semantics, and denial copy.

Checkpoint: The full matrix passes on two API levels and after process recreation.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
State shape Boolean; nullable Boolean; sealed assessment Sealed assessment Preserves reason and resolution
Refresh Cache forever; poll; lifecycle and explicit signals Lifecycle plus explicit signals Accurate without wasteful polling
Settings launch Construct in domain; abstract resolution Abstract resolution Keeps Android objects at edge
Error behavior Throw; mark denied; typed misconfigured/temporary Typed state Prevents misleading denial
Onboarding Request all; progressive journey Progressive Matches user intent and least privilege

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Domain tests Prove exhaustive mapping Static unsupported, dynamic denial, transient disconnect
ViewModel tests Prove state refresh Resume signal replaces stale assessment
Compose tests Prove understandable UI Status text, rationale, disabled resolution
Instrumented tests Prove Android checks Settings handler, service declaration, owner mode
Compatibility tests Prove API/OEM degradation Missing intent handler, older API

6.2 Critical Test Cases

  1. No launch requests: App launch causes zero permission or Settings prompts.
  2. Revocation: Available changes to Needs consent after external revocation and resume.
  3. Disconnected service: Enabled but disconnected maps to Temporarily unavailable.
  4. Missing manifest: Misconfigured wins over a misleading consent action.
  5. Unsupported API: Card explains minimum platform level.
  6. Policy mode: Normal install reports Policy-managed and no self-enrollment resolution.
  7. Process recreation: Registry reconstructs state; no stale in-memory grant survives.
  8. Missing handler: Manual instructions appear without crash.
  9. Accessibility semantics: Screen reader announces capability, status, evidence, and action.

6.3 Test Data

Scenario A
  api_supported: true
  manifest_declared: true
  user_granted: false
  expected: NEEDS_CONSENT / USER_GATE_DISABLED

Scenario B
  api_supported: true
  manifest_declared: true
  user_granted: true
  service_connected: false
  expected: TEMPORARILY_UNAVAILABLE / SERVICE_DISCONNECTED

Scenario C
  api_supported: true
  owner_mode: NONE
  expected: POLICY_MANAGED / ADMIN_PROVISIONING_REQUIRED

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

Pitfall Symptom Solution
Cached grant Card remains Available after revoke Recheck on lifecycle return
Boolean model Unsupported appears as denied Preserve typed reason
Journey in checker Refresh unexpectedly launches Settings Separate observation and resolution
Assumed handler OEM crashes on intent launch Resolve first and show fallback
UI-only registry Worker uses different logic Expose registry as headless domain service
Debug leakage Release can fake authority Build-time exclusion and release test

7.2 Debugging Strategies

  • Evidence first: Display reason code and checker timestamp in a debug panel.
  • Compare layers: Inspect API support, manifest, user gate, and health separately.
  • Use external mutation: Change grants in Settings while app is backgrounded.
  • Test two APIs: Distinguish code defect from version behavior.
  • Inspect manifest: Confirm the component and permission declaration actually merged.

7.3 Performance Traps

Avoid polling every capability continuously. Refresh on explicit events, foreground return, and bounded service callbacks. Run slow package or policy checks off the main thread, but preserve a single immutable screen update. Coalesce bursts of lifecycle signals.


8. Extensions & Challenges

8.1 Beginner Extensions

  • Add search and category filtering.
  • Add a capability glossary inside each detail sheet.
  • Add a copyable diagnostic reason without sensitive data.

8.2 Intermediate Extensions

  • Add dependency previews showing which disabled rules need a capability.
  • Record capability transition history with bounded retention.
  • Add localized copy and screenshot tests for long text.

8.3 Advanced Extensions

  • Generate a compatibility report across emulator API levels.
  • Model consumer, enterprise, and developer distribution tracks.
  • Add a policy fitness test that rejects any capability without revocation copy.

9. Real-World Connections

9.1 Industry Applications

  • Automation platforms: Gate triggers and actions before authoring and execution.
  • Password managers: Explain autofill, accessibility, and overlay authority distinctly.
  • Enterprise agents: Separate normal install from profile/device-owner capabilities.
  • VPN and capture tools: Represent session and foreground visibility accurately.
  • Health and location apps: Use progressive permission scope and revocation handling.
  • Android Settings samples: https://github.com/android/platform-samples — official platform behavior examples.
  • Now in Android: https://github.com/android/nowinandroid — Compose architecture and state examples.
  • Test DPC: https://github.com/googlesamples/android-testdpc — managed-device capability reference for later study.

9.3 Interview Relevance

  • Permission architecture tests whether you understand the platform rather than only APIs.
  • State modeling demonstrates product-safe handling of denial and revocation.
  • Lifecycle refresh shows awareness of external mutation and process death.
  • Capability boundaries reveal whether you distinguish consumer, privileged, and managed authority.

10. Resources

10.1 Essential Reading

  • Permissions on Android: https://developer.android.com/guide/topics/permissions/overview — permission taxonomy and principles.
  • Request special permissions: https://developer.android.com/training/permissions/requesting-special — Settings-mediated access.
  • Activity Result APIs: https://developer.android.com/training/basics/intents/result — lifecycle-safe result handling.
  • Processes and app lifecycle: https://developer.android.com/guide/components/activities/process-lifecycle — disposable-process model.
  • Application fundamentals: https://developer.android.com/guide/components/fundamentals — components, sandbox, and manifest.
  • Device policy controller: https://developer.android.com/work/dpc/build-dpc — why administrative authority is a separate track.

10.2 Video Resources

  • Android Developers permission and privacy sessions: https://www.youtube.com/@AndroidDevelopers
  • Android architecture learning pathway: https://developer.android.com/courses/pathways/android-architecture

10.3 Tools & Documentation

  • ADB: https://developer.android.com/tools/adb — inspect device and package state.
  • Compose testing: https://developer.android.com/develop/ui/compose/testing — semantic UI verification.
  • Lifecycle: https://developer.android.com/topic/libraries/architecture/lifecycle — refresh and observation boundaries.
  • App architecture: https://developer.android.com/topic/architecture — domain and platform separation.
  • Next — Project 2: Context Signal Monitor: Uses capability health to decide whether a signal source is trustworthy.
  • Project 5: Timekeeper Scheduler: Reuses exact-alarm assessment and degraded timing state.
  • Projects 6-13: Add real high-authority adapters behind this control plane.

11. Self-Assessment Checklist

Before considering this project complete, verify:

11.1 Understanding

  • I can distinguish platform support, authority, and health without notes.
  • I can explain five different Android consent or provisioning mechanisms.
  • I understand why returning from Settings does not imply success.
  • I can explain why device owner is not a runtime permission.
  • I can name the degraded behavior for every capability.

11.2 Implementation

  • At least seven capability types render exhaustive states.
  • Every assessment contains a stable reason and evidence.
  • No capability is requested during launch.
  • One complete journey includes rationale, launch, return recheck, denial, and revocation.
  • UI and headless code share the same registry.
  • Process recreation and unsupported-device tests pass.
  • Debug overrides cannot enter the release build.

11.3 Growth

  • I documented one assumption that a real device disproved.
  • I can explain the project in a system-design interview.
  • I identified one capability that should not ship in a consumer build.
  • I wrote a short retrospective about consent copy and technical state.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Seven capability descriptors and all required states are visible.
  • At least three real read-only platform checkers work.
  • One Settings journey rechecks denial and grant correctly.
  • No launch-time permission request exists.
  • Domain and UI tests cover every state.

Full Completion:

  • All minimum criteria plus:
  • Eight capability families include reason, evidence, degraded behavior, and revocation.
  • Process recreation, missing-handler, unsupported API, and temporary health tests pass.
  • TalkBack output and zero-grant onboarding are verified.
  • The registry serves both Compose and a fake headless executor.

Excellence — Going Above & Beyond:

  • Produce a two-API compatibility report with screenshots and state evidence.
  • Add consumer, managed, and developer-track policy metadata.
  • Add a build-time fitness test preventing undocumented capabilities.
  • Demonstrate external revocation while the app is backgrounded with an immediate truthful refresh.

This guide was generated from ANDROID_AUTOMATION_APPS_MASTERY.md. For the complete learning path, see the parent guide and directory README.