Files
Meshtastic-Android/core/api
niccellular 6ce565f16c feat(lockdown): thread max_session_seconds through coordinator and UI
End-to-end plumbing for LockdownAuth.max_session_seconds (per-boot
uptime cap on the unlocked session; 0 = unlimited).

Wire:
- CommandSenderImpl populates LockdownAuth.max_session_seconds in the
  outbound admin packet (clamped non-negative).

Coordinator + persistence:
- LockdownCoordinator.submitPassphrase gains optional maxSessionSeconds
  (default 0); persisted alongside boots/hours and replayed by
  auto-unlock so cached sessions keep the operator's cap on reconnect.
- StoredPassphrase gains a new field with a default of 0 so existing
  call sites stay source-compatible.
- LockdownPassphraseStore (Android EncryptedSharedPreferences impl):
  reads/writes the new field with a `_maxSessionSeconds` key suffix;
  legacy entries decode to 0.
- LockdownPassphraseStore (JVM file-backed impl): bumps the per-entry
  on-disk serialization from 3-line to 4-line; legacy 3-line entries
  still decode (treated as maxSessionSeconds=0).

IPC + radio plumbing:
- IMeshService.sendLockdownUnlock AIDL gains a 4th int parameter.
- MeshService stub, MeshActionHandler, RadioController interface, and
  both impls (AndroidRadioControllerImpl, DirectRadioControllerImpl)
  thread the field through.
- FakeIMeshService, FakeRadioController, FakeLockdownCoordinator
  updated to match.

UI:
- LockdownDialog adds a single optional "Session cap (minutes)" field
  below the boots/hours row. Operators enter minutes for ergonomics;
  the dialog multiplies by 60 before passing to the coordinator. Blank
  or 0 = unlimited (firmware default).
- UIViewModel.sendLockdownUnlock gains the new param with default 0.
- New string resources: lockdown_session_minutes,
  lockdown_session_minutes_help. Strings re-sorted via
  scripts/sort-strings.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 16:57:49 -04:00
..

:core:api (Meshtastic Android API)

Deprecation notice

The AIDL-based service integration (IMeshService) is deprecated and will be removed in a future release. The recommended integration path for ATAK and other external apps is the built-in Local TAK Server introduced in core:takserver. Connect ATAK to 127.0.0.1:8087 (TCP) and import the DataPackage exported from the TAK Config screen to complete setup. No AIDL binding or JitPack dependency is required.

Overview

The :core:api module contains the AIDL interface and dependencies for third-party applications that currently integrate with the Meshtastic Android app via service binding. New integrations should use the Local TAK Server instead (see deprecation notice above).

Integration

To communicate with the Meshtastic Android service from your own application, we recommend using JitPack.

Dependencies

Add the following to your build.gradle.kts:

dependencies {
    // The core AIDL interface and Intent constants
    implementation("com.github.meshtastic.Meshtastic-Android:meshtastic-android-api:v2.x.x")
    
    // Data models (DataPacket, MeshUser, NodeInfo, etc.) - Kotlin Multiplatform
    implementation("com.github.meshtastic.Meshtastic-Android:meshtastic-android-model:v2.x.x")
    
    // Protobuf definitions (PortNum, Telemetry, etc.) - Kotlin Multiplatform
    implementation("com.github.meshtastic.Meshtastic-Android:meshtastic-android-proto:v2.x.x")
}

(Replace v2.x.x with the latest stable version).

Usage

1. Bind to the Service

Use the IMeshService interface to bind to the Meshtastic service.

val intent = Intent("com.geeksville.mesh.Service")
// ... query package manager and bind

2. Interact with the API

Once bound, cast the IBinder to IMeshService.

3. Register a BroadcastReceiver

Use MeshtasticIntent constants for actions. Remember to use RECEIVER_EXPORTED on Android 13+.

Key Components

  • IMeshService.aidl: The primary AIDL interface.
  • MeshtasticIntent.kt: Defines Intent actions for received messages and status changes.

Module dependency graph

graph TB
  :core:api[api]:::android-library
  :core:api --> :core:model

classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef compose-desktop-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-library-compose fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library-compose fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;