22 KiB
CLAUDE.md - Launcher3 AOSP 13+ Development Guide for AI Assistants
Project Overview
Project Name: Launcher3 for AOSP (Android Open Source Project)
Base Version: android16-s2-release (based on Android 16, but supports Android 13+)
Repository: https://android.googlesource.com/platform/packages/apps/Launcher3/
Language: Mixed Java and Kotlin
Build System: Gradle (8.13.1) + Android.bp (Soong) for AOSP integration
Package: com.android.launcher3
Purpose
Launcher3 is the default home screen and app launcher for AOSP-based Android devices. It provides:
- Home screen with app icons, widgets, and folders
- App drawer (all apps list)
- Quickstep: Recent apps/multitasking interface
- Search functionality
- Desktop mode support
- Taskbar support
Codebase Structure
Root Directory Organization
Launcher3Aosp13/
├── src/ # Main launcher source (Java/Kotlin)
├── quickstep/ # Quickstep (recents) implementation
├── src_no_quickstep/ # Fallback when Quickstep is disabled
├── src_plugins/ # Plugin interfaces
├── src_build_config/ # Build configuration sources
├── src_ui_overrides/ # UI override sources (without Quickstep)
├── res/ # Main resources
├── tests/ # Test suite
│ ├── src/ # Test sources
│ ├── tapl/ # Test Automation Platform Library
│ └── multivalentTests/ # Multi-variant tests
├── go/ # Launcher3Go variant (Android Go)
├── modules/ # All Gradle library modules live here
│ ├── animationlib/ # Animation library module
│ ├── iconloaderlib/ # Icon loading library module
│ ├── shared/ # Shared utilities module
│ ├── wm_shared/ # Window Manager shared code
│ ├── msdllib/ # MSDL (Multi-Sensory Design Language) module
│ ├── flagslib/ # Feature flags module
│ ├── hidden-api/ # Hidden API stubs module
│ ├── SettingsLib/ # Partial SettingsLib port (11 preference modules)
│ ├── compatLib/ # Per-API-level compat shims (VQ..VBaklava)
│ ├── systemUIPluginCore/ # SystemUI plugin core
│ └── androidx-lib/ # AndroidX overrides
├── compose/ # Jetpack Compose integration
├── protos/ # Protocol buffer definitions
├── prebuilts/ # Prebuilt JAR dependencies
├── tools/ # Build and development tools
├── checks/ # Lint checks
├── Android.bp # AOSP build configuration
├── build.gradle # Gradle build configuration
└── settings.gradle # Gradle module settings
Key Source Directories
Main Launcher (src/com/android/launcher3/)
Core launcher components:
Launcher.java- Main activity (entry point)LauncherApplication.java- Application classWorkspace.java- Home screen workspaceCellLayout.java- Grid layout for iconsHotseat.java- Bottom dockDeviceProfile.java- Device-specific UI configurationBubbleTextView.java- App icon with labelFolder.java- Folder implementationmodel/- Data models and loadinggraphics/- Graphics and icon renderingallapps/- App drawer implementationtouch/- Touch handling and gestureswidget/- Widget supportanim/- Animationsutil/- Utility classespm/- Package manager integrationlogging/- Analytics and logging
Quickstep (quickstep/src/com/android/launcher3/)
Recent apps and multitasking:
RecentsActivity.java- Recents containerTaskView.java- Individual task cardTaskbarActivity.java- Taskbar implementationtaskbar/- Taskbar controllers and viewsuioverrides/- Quickstep UI overridestouch/- Gesture navigationdagger/- Dependency injection modules- Desktop mode support
- Split screen support
- Bubble bar support
Build Variants
The project supports multiple build flavors:
Flavor Dimensions
-
App Dimension:
aosp- Standard AOSP launcherl3go- Launcher3Go (Android Go edition)
-
Recents Dimension:
withQuickstep- Full Quickstep recent apps UIwithoutQuickstep- Legacy/simple recents
Build Variants
aospWithQuickstep- Standard launcher with QuickstepaospWithoutQuickstep- Standard launcher without Quickstepl3goWithQuickstep- Go launcher with Quickstepl3goWithoutQuickstep- Go launcher without Quickstep
Module Dependencies
The project is organized into multiple Gradle modules:
Main App
├── IconLoader (:IconLoader → iconloaderlib/)
├── Animation (:Animation → animationlib/)
├── Shared (:Shared → shared/)
├── WMShared (:WMShared → wm_shared/)
├── msdl (:msdl → msdllib/)
└── flags (:flags → flagslib/)
Technology Stack
Languages
- Java (targetCompatibility: Java 21)
- Kotlin (2.2.21) with coroutines
- JVM default compatibility:
-Xjvm-default=all
Build Tools
- Gradle: 8.13.1
- Android Gradle Plugin: 8.13.1
- Kotlin Gradle Plugin: 2.2.21
- KSP (Kotlin Symbol Processing): 2.3.3
- Protobuf Gradle Plugin: 0.9.5
Key Dependencies
AndroidX Libraries
- AppCompat
- Core KTX
- RecyclerView
- DynamicAnimation
- Preference
- Slice Builders
- Graphics Shapes
- Window API
- Material3 (Jetpack Compose)
- Lifecycle (common-java8, extensions, runtime-ktx)
Dependency Injection
- Dagger 2 (2.56.2) with KAPT
Async/Concurrency
- Kotlin Coroutines (kotlinx-coroutines-android)
Serialization
- Protobuf JavaLite (4.33.1)
UI/Animation
- Lottie (animations)
- Material Design Components
Testing
- JUnit
- Mockito + Dexmaker
- AndroidX Test (runner, rules, uiautomator)
System Libraries (Prebuilt)
- SystemUI Shared Library
- WindowManager Shell Shared
- Plugin Core Library
- Platform Animation Library
- View Capture Library
- Feature Flags Libraries (launcher3, wm_shell, systemui)
Development Workflows
Building the Project
Standard Gradle Build
# Build all variants
./gradlew build
# Build specific variant
./gradlew assembleAospWithQuickstepDebug
# Clean build
./gradlew clean build
# Run tests
./gradlew test
./gradlew connectedAndroidTest
AOSP Build (using Android.bp)
# From AOSP root
m Launcher3QuickStep # Standard Quickstep launcher
m Launcher3 # Basic launcher
m Launcher3Go # Go launcher
Build Configuration
SDK Versions
minSdkVersion: 33 (Android 13)targetSdkVersion: 36 (Android 16)compileSdkVersion: android-36
Build Config Fields
Located in build.gradle, these flags control features:
IS_STUDIO_BUILD: falseQSB_ON_FIRST_SCREEN: true (Quick Search Box)IS_DEBUG_DEVICE: falseWIDGET_ON_FIRST_SCREEN: trueWIDGETS_ENABLED: trueNOTIFICATION_DOTS_ENABLED: true
Code Organization Conventions
Package Structure
com.android.launcher3/
├── (root) - Core launcher classes
├── model/ - Data models and loading
├── graphics/ - Graphics and rendering
├── allapps/ - App drawer
├── folder/ - Folder implementation
├── widget/ - Widgets
├── touch/ - Touch and gestures
├── anim/ - Animations
├── util/ - Utilities
├── logging/ - Analytics
├── pm/ - Package manager
├── config/ - Configuration
├── states/ - State management
└── views/ - Custom views
File Naming
- Activities:
*Activity.java(e.g.,Launcher.java,RecentsActivity.java) - Views:
*View.java(e.g.,BubbleTextView.java,TaskView.java) - Controllers:
*Controller.java(e.g.,TaskbarController.java) - Models:
*Info.javafor data classes (e.g.,ItemInfo.java,AppInfo.java) - Utilities:
*Util.javaor*Utils.java - Kotlin files: Use same conventions with
.ktextension
Code Style
- Java: Follow AOSP code style
- Kotlin: Use Kotlin coding conventions
- Indentation: 4 spaces (no tabs)
- Line length: Prefer 100 characters
- Use
@Overrideannotations - Add Javadoc/KDoc for public APIs
Protobuf Usage
The project uses Protocol Buffers for data serialization:
Proto Files
protos/*.proto- Main proto definitionsprotos_overrides/*.proto- Override definitionsquickstep/protos_overrides/*.proto- Quickstep-specific protos
Generated Code
- Build task:
generateProto - Output:
build/generated/source/proto/ - Type: Lite (mobile-optimized)
Testing
Test Structure
tests/src/- Instrumentation teststests/tapl/- Test Automation Platform Library (UI testing framework)tests/multivalentTests/- Tests across variants- Unit tests: In module directories (e.g.,
animationlib/tests/)
Running Tests
# All tests
./gradlew test connectedAndroidTest
# Specific test class
./gradlew test --tests com.android.launcher3.ClassName
# TAPL tests (UI automation)
adb shell am instrument -w com.android.launcher3.tests/androidx.test.runner.AndroidJUnitRunner
Dependency Management
Framework JARs
Located in prebuilts/libs/:
framework-16.jar- Android framework (compile-only)SystemUI-core.jar- SystemUI core componentsSystemUI-statsd.jar- StatsD integrationsysui_shared.jar- SystemUI shared libraryWindowManager-Shell-shared.jar- WM Shell shared- Various feature flag libraries
Adding Dependencies
- Check if available in Maven/Google repositories
- Add to
build.gradledependencies block - Sync Gradle
- For framework JARs, place in
prebuilts/libs/and reference
Feature Flags
The project uses multiple feature flag systems:
Flag Libraries
com_android_launcher3_flags- Launcher3 flagscom_android_wm_shell_flags- WindowManager Shell flagscom_android_systemui_flags- SystemUI flagscom_android_systemui_shared_flags- SystemUI shared flags
Usage
// Check feature flag
if (FeatureFlags.ENABLE_NEW_FEATURE.get()) {
// Feature-specific code
}
Git Workflow
Branches
main- android16-s2-release (Android 16)Launcher3-15-qc- Qualcomm Android 15Launcher3-15-s1-release- Android 15Launcher3-14-s2-release- Android 14Launcher3-13- Android 13 (base for this repo)- Various version-specific branches
Current Branch
- Working on:
claude/claude-md-mixzf7lcxsd8twfo-015j4Q48NKcmqLRRwAJ5Zxba
Committing Changes
# Stage changes
git add .
# Commit with descriptive message
git commit -m "Brief description of changes"
# Push to branch
git push -u origin claude/claude-md-mixzf7lcxsd8twfo-015j4Q48NKcmqLRRwAJ5Zxba
Key Development Patterns
1. Dependency Injection (Dagger 2)
The project uses Dagger 2 extensively in Quickstep:
// Module definition
@Module
class AppModule {
@Provides
@Singleton
fun provideContext(app: Application): Context = app
}
// Component
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {
fun inject(activity: LauncherActivity)
}
2. State Management
Launcher uses a state machine pattern:
// LauncherState defines different UI states
// - NORMAL: Home screen
// - ALL_APPS: App drawer
// - OVERVIEW: Recent apps
// - HINT_STATE: Gesture hints
// Transition between states
launcher.getStateManager().goToState(LauncherState.ALL_APPS);
3. Model-View-Controller Pattern
- Model:
model/package - Data loading and management - View: Custom view classes extending Android views
- Controller: Controller classes managing view behavior
4. Touch Handling
Complex gesture system in touch/ package:
AbstractStateChangeTouchController- Base for touch controllersPortraitStatesTouchController- Portrait mode gesturesLandscapeStatesTouchController- Landscape gestures
5. Animation Framework
Custom animation system:
AnimatorSetfor complex animationsStateAnimationConfigfor state transitionsPendingAnimationfor collecting animations- Interpolators in
anim/Interpolators.java
6. Device Profile System
DeviceProfile.java and InvariantDeviceProfile.java:
- Calculates UI dimensions based on device
- Handles different form factors (phone, tablet, foldable)
- Grid size configuration
- Icon size calculations
7. Plugin System
Located in src_plugins/:
- Define plugin interfaces
- Launcher listens for plugin implementations
- Allows customization without modifying core code
8. Compose Integration
Optional Jetpack Compose support:
- Enabled via
release_enable_compose_in_launcherflag - Facades in
compose/facade/ - Features in
compose/features/ - Disabled by default for stability
Important Files to Know
Configuration Files
Android.bp- AOSP build configuration (Soong)build.gradle- Gradle build configurationsettings.gradle- Module configurationgradle.properties- Gradle properties and versionsproguard.flags- ProGuard/R8 ruleslocal.properties- Local SDK paths (auto-generated)
Manifest Files
AndroidManifest.xml- Base manifest (without Quickstep)AndroidManifest-common.xml- Common manifest entriesquickstep/AndroidManifest.xml- Quickstep additionsquickstep/AndroidManifest-launcher.xml- Launcher-specific Quickstepgo/AndroidManifest.xml- Android Go additions
Resource Files
res/- Main resources (layouts, drawables, values)quickstep/res/- Quickstep-specific resourcesgo/res/- Android Go resources
Entry Points
src/com/android/launcher3/Launcher.java- Main launcher activityquickstep/src/com/android/launcher3/RecentsActivity.java- Recentsquickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java- Quickstep launchersrc/com/android/launcher3/LauncherApplication.java- Application class
AI Assistant Guidelines
When Making Changes
-
Understand the Build Variant: Know which variant you're modifying (aosp vs l3go, with/without Quickstep)
-
Respect the Architecture:
- Don't mix UI logic with model code
- Use controllers for complex UI behavior
- Follow MVC patterns
-
Handle Both Java and Kotlin:
- New code can be Kotlin (preferred for new features)
- Maintain existing Java code in Java unless refactoring
- Use appropriate null-safety (
@Nullable,@NonNullin Java;?in Kotlin)
-
Test Thoroughly:
- Run unit tests:
./gradlew test - Run instrumentation tests:
./gradlew connectedAndroidTest - Test on different build variants
- Test with Quickstep enabled and disabled
- Run unit tests:
-
Consider Performance:
- Launcher is performance-critical (home screen)
- Avoid heavy operations on main thread
- Use background threads for loading
- Optimize animations (60 FPS target)
-
Follow AOSP Guidelines:
- Check AOSP code style: https://source.android.com/docs/setup/contribute/code-style
- Add license headers to new files
- Use proper visibility modifiers
-
Handle Configuration Changes:
- Launcher handles orientation, screen size, fold/unfold
- Test rotation and configuration changes
- Use
DeviceProfilefor layout calculations
-
Accessibility:
- Add content descriptions to views
- Support TalkBack
- Keyboard navigation support
-
Localization:
- Use string resources (no hardcoded strings)
- Support RTL (right-to-left) languages
- Test with different locales
- The app's own strings live in
res/values/strings_murine.xml. The rest ofres/values/strings.xmlis inherited from AOSP Launcher3 and translated upstream, so onlystrings_murine.xmlis ours to maintain - New strings start as English + Italian only. When adding strings for a new feature,
write
res/values/strings_murine.xmlandres/values-it/strings_murine.xmland stop there. The other languages are filled in later, in one pass, when the wording has settled and the maintainer explicitly asks for it. Do not translate a feature's strings into every shipped language unprompted - Read
docs/_data/languages.ymlbefore adding or changing any string. It lists every language currently shipped; each of them eventually needs the new string in its ownres/values-<code>/strings_murine.xml, and until then that language falls back to English for the new text. Changing the wording of an existing string is different: update every language that already has it, since a stale translation is worse than a missing one - Every translated file mirrors the base file's structure. Same string order, same blank
lines between groups, same
<!-- section -->comments in the same places. Never reorder or alphabetize a translation: matching line positions are what makes a missing or stale string obvious when diffing two languages side by side. New entries indocs/_data/languages.ymlfollow the same rule, keeping the existing key order (code,name,native,status,strings,by_git,by,note) - Keep
docs/_data/languages.ymlup to date. Bumptotalwhen the base string count changes, and update each language'sstringscount. It drives the public status page at/localization-status/, so a stale file publishes wrong numbers - When adding a new language, read both the English and the Italian strings first.
Italian is hand-written and frequently disambiguates wording that English leaves open
(grammatical gender, formal vs informal address, whether a short label is a noun or a verb),
which makes the new translation noticeably more accurate. Add the language to
docs/_data/languages.ymlwithstatus: aiunless a speaker has actually reviewed it
-
Dependency Updates:
- Update
gradle.propertiesfor version changes - Sync prebuilt JARs with AOSP versions
- Test after dependency updates
- Update
Common Tasks
Adding a New Feature
- Create feature flag in
flagslib/if needed - Implement in appropriate package
- Add resources to
res/ - Update manifest if needed
- Add tests in
tests/ - Document in comments
Fixing a Bug
- Identify the build variant affected
- Write a failing test first (TDD)
- Implement fix
- Verify test passes
- Test related functionality
- Check for regressions
Refactoring Code
- Ensure tests exist and pass
- Make incremental changes
- Run tests after each change
- Keep backward compatibility
- Update documentation
Adding Resources
- Add to appropriate
res/directory - Consider variant-specific resources (e.g.,
quickstep/res/) - Support different densities (drawable-mdpi, -hdpi, etc.)
- Add translations for strings: English and Italian only for new features until otherwise requested (see Localization above)
Debugging Tips
-
Enable Debug Logging:
- Use
Log.d(),Log.v()for debug logs - Check ProtoLog for Quickstep logs
- Use
-
Layout Inspector: Use Android Studio's Layout Inspector
-
Device Profile Info: Check
DeviceProfile.dump()for layout info -
State Machine: Log state transitions to understand flow
-
Touch Events: Enable touch event logging in
MotionEventsUtils
Code Review Checklist
- Code follows AOSP style guidelines
- No hardcoded strings (use resources)
- Null safety annotations/checks
- Performance considerations (no main thread blocking)
- Accessibility support (content descriptions)
- Tests added/updated
- Works on different build variants
- Configuration change handling (rotation)
- RTL support
- License header on new files
- Comments for complex logic
- No compiler warnings
External Resources
Official Documentation
- AOSP Launcher3: https://cs.android.com/android/platform/superproject/+/master:packages/apps/Launcher3/
- Android Source: https://source.android.com/
- Android Developer Docs: https://developer.android.com/
Tutorials (Chinese)
Referenced in README.md - series by 墨香 on Launcher3 (based on Android 6.0):
- Overview: http://www.codemx.cn/2016/07/30/Launcher01/
- Data Loading: http://www.codemx.cn/2016/08/05/Launcher02/
- Binding: http://www.codemx.cn/2016/08/14/Launcher03/
- App Install/Update: http://www.codemx.cn/2016/08/21/Launcher04/
- Workspace Sliding: http://www.codemx.cn/2016/10/16/Launcher05/
- Drag and Drop: http://www.codemx.cn/2016/11/21/Launcher06/
- Widgets: http://www.codemx.cn/2016/12/18/Launcher07/
- Icons/Wallpapers: http://www.codemx.cn/2017/05/19/Launcher08/
Note: These tutorials are based on Android 6.0 Launcher3. Modern versions differ significantly but core concepts remain.
Dependencies
- Dagger 2: https://dagger.dev/
- Kotlin Coroutines: https://kotlinlang.org/docs/coroutines-overview.html
- Protobuf: https://github.com/protocolbuffers/protobuf
- Lottie: https://airbnb.io/lottie/
Recent Updates
Latest Update: 2025-10-14
- Base: android16-s2-release
- Source: https://android.googlesource.com/platform/packages/apps/Launcher3/+/refs/heads/android16-s2-release
Recent Commits:
946c706: update depence654821d: 添加手势注释 (Add gesture annotations)bbf3dbb: update libs- 12a6c41/aa1088d: Update README.md
Notes for AI Assistants
-
This is a large, complex project: Take time to understand the module you're working on before making changes.
-
Multiple entry points: Understand whether you're modifying Launcher (home screen) or Quickstep (recents).
-
Performance matters: This runs on the home screen - every millisecond counts.
-
AOSP integration: Changes should work both with Gradle (development) and Android.bp (AOSP build).
-
Backward compatibility: Support multiple Android versions and form factors.
-
Chinese documentation: Some comments and the README are in Chinese. Use translation if needed.
-
Prebuilt dependencies: Many system libraries are prebuilt JARs in
prebuilts/libs/- these come from AOSP framework. -
Feature flags: Check if new features should be behind feature flags.
-
Variant-specific code: Use source sets for variant-specific implementations.
-
Documentation: Update this CLAUDE.md when project structure or conventions change significantly.
Last Updated: 2025-12-09 Generated by: Claude AI Assistant Purpose: Guide AI assistants in understanding and modifying this codebase effectively