implementing-android-code

Implements Bitwarden Android features using State-Action-Event ViewModels, type-safe navigation, and layered data architecture.

9.3k|1.0k|Updated Apr 30, 2016
One-click install
npx skills add https://github.com/bitwarden/android --skill implementing-android-code
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: implementing-android-code
Source: https://github.com/bitwarden/android/tree/main/.claude/skills/implementing-android-code
Command: npx skills add https://github.com/bitwarden/android --skill implementing-android-code

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Implementing features in the Bitwarden Android codebase requires following strict, project-specific patterns for ViewModels, navigation, data layers, and security that differ from generic Android development. This Skill provides the exact patterns, templates, and anti-patterns so new code passes review and survives process death without security leaks.

Core Features & Use Cases

  • State-Action-Event ViewModels: Enforces the BaseViewModel pattern with @Parcelize state, SavedStateHandle persistence, and internal actions posted from coroutines.
  • Type-Safe Navigation: Provides @Serializable route templates with Args helpers, NavController extensions, and NavGraphBuilder destinations.
  • Data Layer & Security Patterns: Covers repository/manager/data-source layering, Hilt modules, encrypted vs unencrypted storage, Clock injection, and ViewModel testing with Turbine and MockK.
  • Use Case: When asked to create a new screen, the Skill produces a complete ViewModel, route, Compose screen, repository, Hilt module, and unit test that all conform to Bitwarden conventions.

Quick Start

Ask the assistant to create a new screen with a ViewModel, navigation route, and repository for a feature in the Bitwarden Android app.

Frequently Asked Questions about implementing-android-code

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I implement a ViewModel in the Bitwarden Android app?

Extend BaseViewModel with State, Event, and Action types, annotate with @HiltViewModel, and make the state a @Parcelize data class. Implement handleAction synchronously, post internal actions from coroutines via sendAction, and persist state to SavedStateHandle for process death recovery.

How do I add type-safe navigation with Jetpack Compose?

Define a @Serializable route data class, an Args helper extracted from SavedStateHandle via toRoute, a NavController.navigateTo extension, and a NavGraphBuilder destination using composableWithSlideTransitions. This avoids string-based navigation and gives compile-time parameter safety.

Why should ViewModel state not be updated inside coroutines?

Direct mutableStateFlow updates inside coroutines break the synchronous dispatch contract of the State-Action-Event pattern. Instead, coroutines should post internal actions with sendAction, and state updates happen only inside handleAction.

When should I use encrypted versus unencrypted SharedPreferences?

Use @EncryptedPreferences for credentials, tokens, and keys, and @UnencryptedPreferences for UI state and non-sensitive preferences. Disk sources extend BaseEncryptedDiskSource, which exposes putEncryptedString and putBoolean helpers for each store.

How do I test a Bitwarden ViewModel with MockK and Turbine?

Extend BaseViewModelTest, mock repository interfaces with MockK using coEvery for suspend functions, and run tests with runTest. Assert state and events with Turbine's test block or the stateEventFlow helper, and inject a fixed Clock for time-dependent logic.

What are common mistakes when adding a repository in this codebase?

Common mistakes include injecting implementation classes instead of interfaces, throwing exceptions instead of returning domain-specific sealed result classes, and leaking implementation details into interface KDoc. Repositories should aggregate data sources and managers and expose StateFlow for observed data.