Contents
Compatibility
- Minimum SDK: 29
- Target SDK: 35
- Device Types Supported: Phone and Tablet
- Orientations Supported: Portrait and Landscape
Setup
-
Clone the repository:
$ git clone github.com/bitwarden/android
-
Create a
user.properties
file in the root directory of the project and add the following properties:gitHubToken
: A “classic” Github Personal Access Token (PAT) with theread:packages
scope (ex:gitHubToken=gph_xx...xx
). These can be generated by going to the Github tokens page. See the Github Packages user documentation concerning authentication for more details.localSdk
: A boolean value to determine if the SDK should be loaded from the local maven artifactory (ex:localSdk=true
). This is particularly useful when developing new SDK capabilities. Review Linking SDK to clients for more details.
-
Setup the code style formatter:
All code must follow the guidelines described in the Code Style Guidelines document. To aid in adhering to these rules, all contributors should apply
docs/bitwarden-style.xml
as their code style scheme. In IntelliJ / Android Studio:- Navigate to
Preferences > Editor > Code Style
. - Hit the
Manage
button next toScheme
. - Select
Import
. - Find the
bitwarden-style.xml
file in the project’sdocs/
directory. - Import “from”
BitwardenStyle
“to”BitwardenStyle
. - Hit
Apply
andOK
to save the changes and exit Preferences.
Note that in some cases you may need to restart Android Studio for the changes to take effect.
All code should be formatted before submitting a pull request. This can be done manually but it can also be helpful to create a macro with a custom keyboard binding to auto-format when saving. In Android Studio on OS X:
- Select
Edit > Macros > Start Macro Recording
- Select
Code > Optimize Imports
- Select
Code > Reformat Code
- Select
File > Save All
- Select
Edit > Macros > Stop Macro Recording
This can then be mapped to a set of keys by navigating to
Android Studio > Preferences
and editing the macro underKeymap
(ex : shift + command + s).Please avoid mixing formatting and logical changes in the same commit/PR. When possible, fix any large formatting issues in a separate PR before opening one to make logical changes to the same code. This helps others focus on the meaningful code changes when reviewing the code.
- Navigate to
Dependencies
Application Dependencies
The following is a list of all third-party dependencies included as part of the application beyond the standard Android SDK.
-
AndroidX Appcompat
- https://developer.android.com/jetpack/androidx/releases/appcompat
- Purpose: Allows access to new APIs on older API versions.
- License: Apache 2.0
-
AndroidX Autofill
- https://developer.android.com/jetpack/androidx/releases/autofill
- Purpose: Allows access to tools for building inline autofill UI.
- License: Apache 2.0
-
AndroidX Biometrics
- https://developer.android.com/jetpack/androidx/releases/biometric
- Purpose: Authenticate with biometrics or device credentials.
- License: Apache 2.0
-
AndroidX Browser
- https://developer.android.com/jetpack/androidx/releases/browser
- Purpose: Displays webpages with the user’s default browser.
- License: Apache 2.0
-
AndroidX CameraX Camera2
- https://developer.android.com/jetpack/androidx/releases/camera
- Purpose: Display and capture images for barcode scanning.
- License: Apache 2.0
-
AndroidX Compose
- https://developer.android.com/jetpack/androidx/releases/compose
- Purpose: A Kotlin-based declarative UI framework.
- License: Apache 2.0
-
AndroidX Core SplashScreen
- https://developer.android.com/jetpack/androidx/releases/core
- Purpose: Backwards compatible SplashScreen API implementation.
- License: Apache 2.0
-
AndroidX Credentials
- https://developer.android.com/jetpack/androidx/releases/credentials
- Purpose: Unified access to user’s credentials.
- License: Apache 2.0
-
AndroidX Lifecycle
- https://developer.android.com/jetpack/androidx/releases/lifecycle
- Purpose: Lifecycle aware components and tooling.
- License: Apache 2.0
-
AndroidX Room
- https://developer.android.com/jetpack/androidx/releases/room
- Purpose: A convenient SQLite-based persistence layer for Android.
- License: Apache 2.0
-
AndroidX Security
- https://developer.android.com/jetpack/androidx/releases/security
- Purpose: Safely manage keys and encrypt files and sharedpreferences.
- License: Apache 2.0
-
AndroidX WorkManager
- https://developer.android.com/jetpack/androidx/releases/work
- Purpose: The WorkManager is used to schedule deferrable, asynchronous tasks that must be run reliably.
- License: Apache 2.0
-
Dagger Hilt
- https://github.com/google/dagger
- Purpose: Dependency injection framework.
- License: Apache 2.0
-
Firebase Cloud Messaging
- https://github.com/firebase/firebase-android-sdk
- Purpose: Allows for push notification support. (NOTE: This dependency is not included in builds distributed via F-Droid.)
- License: Apache 2.0
-
Firebase Crashlytics
- https://github.com/firebase/firebase-android-sdk
- Purpose: SDK for crash and non-fatal error reporting. (NOTE: This dependency is not included in builds distributed via F-Droid.)
- License: Apache 2.0
-
Glide
- https://github.com/bumptech/glide
- Purpose: Image loading and caching.
- License: BSD, part MIT and Apache 2.0
-
kotlinx.collections.immutable
- https://github.com/Kotlin/kotlinx.collections.immutable
- Purpose: Immutable collection interfaces and implementation prototypes for Kotlin.
- License: Apache 2.0
-
kotlinx.coroutines
- https://github.com/Kotlin/kotlinx.coroutines
- Purpose: Kotlin coroutines library for asynchronous and reactive code.
- License: Apache 2.0
-
kotlinx.serialization
- https://github.com/Kotlin/kotlinx.serialization/
- Purpose: JSON serialization library for Kotlin.
- License: Apache 2.0
-
kotlinx.serialization converter
- https://github.com/square/retrofit/tree/trunk/retrofit-converters/kotlinx-serialization
- Purpose: Converter for Retrofit 2 and kotlinx.serialization.
- License: Apache 2.0
-
OkHttp 3
- https://github.com/square/okhttp
- Purpose: An HTTP client used by the library to intercept and log traffic.
- License: Apache 2.0
-
Retrofit 2
- https://github.com/square/retrofit
- Purpose: A networking layer interface.
- License: Apache 2.0
-
Timber
- https://github.com/JakeWharton/timber
- Purpose: Extensible logging library for Android.
- License: Apache 2.0
-
zxcvbn4j
- https://github.com/nulab/zxcvbn4j
- Purpose: Password strength estimation.
- License: MIT
-
ZXing
- https://github.com/zxing/zxing
- Purpose: Barcode scanning and generation.
- License: Apache 2.0
Development Environment Dependencies
The following is a list of additional third-party dependencies used as part of the local development environment. This includes test-related artifacts as well as tools related to code quality and linting. These are not present in the final packaged application.
-
detekt
- https://github.com/detekt/detekt
- Purpose: A static code analysis tool for the Kotlin programming language.
- License: Apache 2.0
-
JUnit 5
- https://github.com/junit-team/junit5
- Purpose: Unit Testing framework for testing application code.
- License: Eclipse Public License 2.0
-
MockK
- https://github.com/mockk/mockk
- Purpose: Kotlin-friendly mocking library.
- License: Apache 2.0
-
Robolectric
- https://github.com/robolectric/robolectric
- Purpose: A unit testing framework for code directly depending on the Android framework.
- License: MIT
-
Turbine
- https://github.com/cashapp/turbine
- Purpose: A small testing library for kotlinx.coroutine’s Flow.
- License: Apache 2.0
CI/CD Dependencies
The following is a list of additional third-party dependencies used as part of the CI/CD workflows. These are not present in the final packaged application.
-
Fastlane
- https://fastlane.tools/
- Purpose: Automates building, signing, and distributing applications.
- License: MIT
-
Kover
- https://github.com/Kotlin/kotlinx-kover
- Purpose: Kotlin code coverage toolset.
- License: Apache 2.0
What’s Changed
- PM-13937: Consolidate button UI and logic by @david-livefront in #4149
- QA-950: Adding testTag for VaultUnlockedNavBar component by @ifernandezdiaz in #4146
- Update Firebase BOM to 33.5.1 by @david-livefront in #4150
- PM-13886 show dialog when no logins were imported by @dseverns-livefront in #4139
- QA-951: Adding missing IDs for Attachment rows by @ifernandezdiaz in #4148
- PM-13937: Update button padding, remove unused buttons, and rename button by @david-livefront in #4151
- Remove query params from network logging by @david-livefront in #4155
- PM-14009 Refactor storing first time values to the first time action manager by @dseverns-livefront in #4161
- QA-952: Adding test tags for Toggle items by @ifernandezdiaz in #4153
- QA-955: Adding testTag to About screen rows by @ifernandezdiaz in #4163
- Make
isBuildVersionBelow
in authenticatorbridge internal by @ahaisting-livefront in #4157 - PM-14036: Update the slider UI by @david-livefront in #4164
- Autosync Crowdin Translations by @github-actions in #4159
- Simplify usages of turbineScope by @david-livefront in #4167
- BITAU-182 BITAU-107 Don’t show authetnicator sync toggle below API 31 by @ahaisting-livefront in #4156
- PM-13401: Update fab design by @david-livefront in #4168
- [deps]: Lock file maintenance by @renovate in #4174
- [deps]: Update gh minor by @renovate in #4173
- [deps]: Update com.google.devtools.ksp to v2.0.21-1.0.26 by @renovate in #4172
- QA-953: Adding testTag to elements in Add TOTP screen by @ifernandezdiaz in #4160
- PM-13698 only dismiss the card if the user dismisses or completes the… by @dseverns-livefront in #4165
- PM-14184: Update the switch thoughout the app by @david-livefront in #4170
- [PM-13908] Disable ExtraTranslation lint warning by @SaintPatrck in #4176
- PM-14009 complete fix importlogins card show logic by @dseverns-livefront in #4175
- PM-13908 fixing copy on step2 and step3 and making vault url dynamic by @dseverns-livefront in #4154
- QA-957: Adding missing testTag for collection list container by @ifernandezdiaz in #4178
- PM-13988 observe changes to unlock status on settings screen by @dseverns-livefront in #4180
- PM-14201: Update the default divider thickness by @david-livefront in #4182
- PM-14200: Update the eyebrows throughout the app by @david-livefront in #4181
- PM-11188 show snackbar after import success. PM-13943 add relay for snackbar events across screen contexts. by @dseverns-livefront in #4152
- Update copy and generate icons by @david-livefront in #4185
- [PM-14224] Automate Play Store prod variant publishing by @vvolkgang in #4183
- PM-14044: Update generator line breaks to account for padding on both sides by @david-livefront in #4187
- [PM-10405] Add SSH key cipher type by @SaintPatrck in #4158
- QA-954: Add testtags to Send screen elements by @ifernandezdiaz in #4162
- [PM-14241] Backport Timber hotfix by @aj-rosado in #4195
- [PM-14254] Keep Android verifier for JNI usage by @SaintPatrck in #4197
- PM-13155 add shortcuts file to beta source set for beta app id by @dseverns-livefront in #4196
- [PM-13900] Update Bitwarden SDK to add
canManage
to Collection objects by @SaintPatrck in #4169 - [PM-14186] Update SDK to make SSH key properties required by @SaintPatrck in #4200
- PM-13842: Hide ownership when the user has no organizations by @david-livefront in #4199
- [PM-14261] Update README and bugs template to remove Beta references by @vvolkgang in #4198
- Update the camera library by @david-livefront in #4210
- Update genrator icons on bottom nav by @david-livefront in #4211
- PM-14255: Remove accessibility logic to improve overall performance by @david-livefront in #4206
- Update compose BOM to 2024.10.01 by @david-livefront in #4213
- [PM-14346] Run alias generation on the IO dispatcher by @SaintPatrck in #4215
- [PM-14271] Disable editing SSH key fields in edit mode by @SaintPatrck in #4201
- [PM-14273] Add copy functionality for SSH key fields by @SaintPatrck in #4204
- Update to AGP 8.7.2 by @david-livefront in #4216
- PM-14044: Fix line-breaking logic by @david-livefront in #4218
- PM-14379: Stop storing ‘null’ in as the word separator by @david-livefront in #4219
- QA-970: Adding testTags for radiobutton and floating options elements by @ifernandezdiaz in #4188
- PM-14036: Add extra slider padding by @david-livefront in #4220
- [PM-12406] Introduce new endpoint and replace SSO details response flow by @andrebispo5 in #4177
- Bump authenticatorbridge sdk version to 1.0.0 by @ahaisting-livefront in #4221
- PM-13848 Handle URIs with ports and host matching by @dseverns-livefront in #4203
- PM-14458: Update notifications permissions request by @david-livefront in #4229
- PM-14480: Update IntentManager to be able to launch apps by @david-livefront in #4233
- Autosync Crowdin Translations by @github-actions in #4217
- PM-14410: App restart timeout action by @david-livefront in #4237
- PM-14353 : Clean up consumed snackbar on quick resubmission due to state based nav. by @dseverns-livefront in #4235
- [PM-12922] Disable delete if user can’t manage collection by @SaintPatrck in #4179
- [PM-13360] Respect manage permission to assign collections by @SaintPatrck in #4190
- PM-14621 update the copy for step three instruction and cta button by @dseverns-livefront in #4259
- PM-14644: Segmented control should be conditionally displayed for modal generator screen by @david-livefront in #4262
- Autosync Crowdin Translations by @github-actions in #4260
- PM-14433 update flow type to nullable so we can handle gracefully and avoid crash by @SaintPatrck in #4263
- [PM-11753] Listening to vaultUnlock state on mutableCiphers, folders, collections and send state flow by @aj-rosado in #4214
- PM-14433: Null domain data by @SaintPatrck in #4268
- PM-14411: Allow accessibility autofill to run when app is already in background by @david-livefront in #4255
- [PM-14656] Add default value to
BaseEnumeratedIntSerializer
by @SaintPatrck in #4272 - PM-14458: Fix notifications prompt on first use by @david-livefront in #4275
- [deps]: Lock file maintenance by @renovate in #4280
- PM-13988 Hide the action card if the user makes a selection but does not click continue on setup unlock by @dseverns-livefront in #4249
- [deps]: Update com.google.devtools.ksp to v2.0.21-1.0.27 by @renovate in #4278
- PM-13803 Check to see if an existing admin request is pending before … by @dseverns-livefront in #4271
- Clean up the generator screen and handlers by @david-livefront in #4270
- [PM-11303] Add button missing for folders by @andrebispo5 in #4250
- [PM-14589] Prevent SSH key item creation by @SaintPatrck in #4251
- [PM-14526] Add JsonNames annotation to SyncResponseJson by @SaintPatrck in #4269
- PM-14805: Ensure results cannot be double wrapped from ‘asSuccess’ by @david-livefront in #4283
- PM-14597 remove notification if device login is declined by @dseverns-livefront in #4256
- Improve accessibility autofill performance by @david-livefront in #4276
- PM-14805: Use network result in all Retrofit API requests by @david-livefront in #4286
- PM-14854: Keep NetworkResult to avoid obfuscation crash in release by @david-livefront in #4289
- [deps]: Update gh minor by @renovate in #4279
- BITAU-200 Log non-fatal authenticator bridge errors by @ahaisting-livefront in #4228
- PM-14352 Dismiss Snackbar when user clicks it as a default unless the specific dismiss action is present. by @dseverns-livefront in #4291
- PM-14851: Blank names should be considered null by @david-livefront in #4292
- [PM-14897] Enhance build.yml run summary and fix f-droid distribution by @vvolkgang in #4296
- PM-14414 hides autofill card for all users if autofill service is enabled. by @dseverns-livefront in #4297
- Update androidx dependecies and target API by @david-livefront in #4212
- PM-14411: Autofill logic to work better with QuickTile by @david-livefront in #4300
- [PM-11598] GitHub Release Workflow by @vvolkgang in #4285
- [PM-14879] Release Branch creation workflow by @vvolkgang in #4294
- [PM-11304] Ownership Not Defaulting To Org and Collection by @andrebispo5 in #4254
- [PM-14553] Make canManage property of collections optional by @SaintPatrck in #4284
- [PM-14596] Sync on database scheme change by @SaintPatrck in #4304
- PM-14429 Set the min and max range of the slider to match the restrictions not update the min with the computed min. by @dseverns-livefront in #4305
- PM-15062 prevent account lockout when biometrics is only unlock method and no longer supported class. by @dseverns-livefront in #4341
Full Changelog: v2024.10.1...v2024.11.6
Builds Source: https://github.com/bitwarden/android/actions/runs/11937564954