Full Code of beemdevelopment/Aegis for AI

master 59d5c640d6a2 cached
579 files
3.8 MB
1.0M tokens
2633 symbols
1 requests
Download .txt
Showing preview only (4,108K chars total). Download the full file or copy to clipboard to get everything.
Repository: beemdevelopment/Aegis
Branch: master
Commit: 59d5c640d6a2
Files: 579
Total size: 3.8 MB

Directory structure:
gitextract_rgq5wf8x/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   └── feature.md
│   └── workflows/
│       ├── build-app-workflow.yaml
│       ├── codeql-analysis.yml
│       └── crowdin.yml
├── .gitignore
├── CONTRIBUTING.md
├── FAQ.md
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── config/
│   │   ├── libraries/
│   │   │   ├── krop.json
│   │   │   ├── libsu.json
│   │   │   ├── textdrawable.json
│   │   │   └── trustedintents.json
│   │   └── licenses/
│   │       └── 3ca920d1875f7ad7ab04a2a331958577.json
│   ├── lint.xml
│   ├── proguard-rules.pro
│   ├── schemas/
│   │   └── com.beemdevelopment.aegis.database.AppDatabase/
│   │       └── 1.json
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── beemdevelopment/
│       │               └── aegis/
│       │                   ├── AegisTest.java
│       │                   ├── AegisTestApplication.java
│       │                   ├── AegisTestRunner.java
│       │                   ├── BackupExportTest.java
│       │                   ├── DeepLinkTest.java
│       │                   ├── EmptySecretTest.java
│       │                   ├── IntroTest.java
│       │                   ├── OverallTest.java
│       │                   ├── PanicTriggerTest.java
│       │                   ├── rules/
│       │                   │   └── ScreenshotTestRule.java
│       │                   └── vault/
│       │                       └── VaultRepositoryTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── assets/
│       │   │   ├── changelog.html
│       │   │   └── license.html
│       │   ├── java/
│       │   │   ├── com/
│       │   │   │   ├── amulyakhare/
│       │   │   │   │   └── textdrawable/
│       │   │   │   │       ├── LICENSE
│       │   │   │   │       ├── TextDrawable.java
│       │   │   │   │       └── util/
│       │   │   │   │           └── ColorGenerator.java
│       │   │   │   └── beemdevelopment/
│       │   │   │       └── aegis/
│       │   │   │           ├── AccountNamePosition.java
│       │   │   │           ├── AegisApplication.java
│       │   │   │           ├── AegisApplicationBase.java
│       │   │   │           ├── AegisBackupAgent.java
│       │   │   │           ├── AegisModule.java
│       │   │   │           ├── BackupsVersioningStrategy.java
│       │   │   │           ├── CopyBehavior.java
│       │   │   │           ├── EventType.java
│       │   │   │           ├── GroupPlaceholderType.java
│       │   │   │           ├── PassReminderFreq.java
│       │   │   │           ├── Preferences.java
│       │   │   │           ├── SortCategory.java
│       │   │   │           ├── Theme.java
│       │   │   │           ├── ThemeMap.java
│       │   │   │           ├── VibrationPatterns.java
│       │   │   │           ├── ViewMode.java
│       │   │   │           ├── crypto/
│       │   │   │           │   ├── CryptParameters.java
│       │   │   │           │   ├── CryptResult.java
│       │   │   │           │   ├── CryptoUtils.java
│       │   │   │           │   ├── KeyStoreHandle.java
│       │   │   │           │   ├── KeyStoreHandleException.java
│       │   │   │           │   ├── MasterKey.java
│       │   │   │           │   ├── MasterKeyException.java
│       │   │   │           │   ├── SCryptParameters.java
│       │   │   │           │   ├── bc/
│       │   │   │           │   │   ├── SCrypt.java
│       │   │   │           │   │   └── Salsa20Engine.java
│       │   │   │           │   ├── otp/
│       │   │   │           │   │   ├── HOTP.java
│       │   │   │           │   │   ├── MOTP.java
│       │   │   │           │   │   ├── OTP.java
│       │   │   │           │   │   ├── TOTP.java
│       │   │   │           │   │   └── YAOTP.java
│       │   │   │           │   └── pins/
│       │   │   │           │       └── GuardianProjectFDroidRSA2048.java
│       │   │   │           ├── database/
│       │   │   │           │   ├── AppDatabase.java
│       │   │   │           │   ├── AuditLogDao.java
│       │   │   │           │   ├── AuditLogEntry.java
│       │   │   │           │   └── AuditLogRepository.java
│       │   │   │           ├── encoding/
│       │   │   │           │   ├── Base32.java
│       │   │   │           │   ├── Base64.java
│       │   │   │           │   ├── EncodingException.java
│       │   │   │           │   └── Hex.java
│       │   │   │           ├── helpers/
│       │   │   │           │   ├── AnimationsHelper.java
│       │   │   │           │   ├── BiometricSlotInitializer.java
│       │   │   │           │   ├── BiometricsHelper.java
│       │   │   │           │   ├── BitmapHelper.java
│       │   │   │           │   ├── CenterVerticalSpan.java
│       │   │   │           │   ├── ContextHelper.java
│       │   │   │           │   ├── DropdownHelper.java
│       │   │   │           │   ├── EditTextHelper.java
│       │   │   │           │   ├── FabMenuHelper.java
│       │   │   │           │   ├── FabScrollHelper.java
│       │   │   │           │   ├── ItemTouchHelperAdapter.java
│       │   │   │           │   ├── MetricsHelper.java
│       │   │   │           │   ├── PasswordStrengthHelper.java
│       │   │   │           │   ├── PermissionHelper.java
│       │   │   │           │   ├── QrCodeAnalyzer.java
│       │   │   │           │   ├── QrCodeHelper.java
│       │   │   │           │   ├── SafHelper.java
│       │   │   │           │   ├── SimpleAnimationEndListener.java
│       │   │   │           │   ├── SimpleItemTouchHelperCallback.java
│       │   │   │           │   ├── SimpleTextWatcher.java
│       │   │   │           │   ├── TextDrawableHelper.java
│       │   │   │           │   ├── ThemeHelper.java
│       │   │   │           │   ├── UiRefresher.java
│       │   │   │           │   ├── UiThreadExecutor.java
│       │   │   │           │   ├── VibrationHelper.java
│       │   │   │           │   ├── ViewHelper.java
│       │   │   │           │   └── comparators/
│       │   │   │           │       ├── AccountNameComparator.java
│       │   │   │           │       ├── FavoriteComparator.java
│       │   │   │           │       ├── IssuerNameComparator.java
│       │   │   │           │       ├── LastUsedComparator.java
│       │   │   │           │       └── UsageCountComparator.java
│       │   │   │           ├── icons/
│       │   │   │           │   ├── IconPack.java
│       │   │   │           │   ├── IconPackException.java
│       │   │   │           │   ├── IconPackExistsException.java
│       │   │   │           │   ├── IconPackManager.java
│       │   │   │           │   └── IconType.java
│       │   │   │           ├── importers/
│       │   │   │           │   ├── AegisImporter.java
│       │   │   │           │   ├── AndOtpImporter.java
│       │   │   │           │   ├── AuthenticatorPlusImporter.java
│       │   │   │           │   ├── AuthyImporter.java
│       │   │   │           │   ├── BattleNetImporter.java
│       │   │   │           │   ├── BitwardenImporter.java
│       │   │   │           │   ├── DatabaseImporter.java
│       │   │   │           │   ├── DatabaseImporterEntryException.java
│       │   │   │           │   ├── DatabaseImporterException.java
│       │   │   │           │   ├── DuoImporter.java
│       │   │   │           │   ├── EnteAuthImporter.java
│       │   │   │           │   ├── FreeOtpImporter.java
│       │   │   │           │   ├── FreeOtpPlusImporter.java
│       │   │   │           │   ├── GoogleAuthImporter.java
│       │   │   │           │   ├── GoogleAuthUriImporter.java
│       │   │   │           │   ├── MicrosoftAuthImporter.java
│       │   │   │           │   ├── ProtonAuthenticatorImporter.java
│       │   │   │           │   ├── SqlImporterHelper.java
│       │   │   │           │   ├── SteamImporter.java
│       │   │   │           │   ├── StratumImporter.java
│       │   │   │           │   ├── TotpAuthenticatorImporter.java
│       │   │   │           │   ├── TwoFASImporter.java
│       │   │   │           │   └── WinAuthImporter.java
│       │   │   │           ├── otp/
│       │   │   │           │   ├── GoogleAuthInfo.java
│       │   │   │           │   ├── GoogleAuthInfoException.java
│       │   │   │           │   ├── HotpInfo.java
│       │   │   │           │   ├── MotpInfo.java
│       │   │   │           │   ├── OtpInfo.java
│       │   │   │           │   ├── OtpInfoException.java
│       │   │   │           │   ├── SteamInfo.java
│       │   │   │           │   ├── TotpInfo.java
│       │   │   │           │   ├── Transferable.java
│       │   │   │           │   └── YandexInfo.java
│       │   │   │           ├── receivers/
│       │   │   │           │   ├── QsTileRefreshReceiver.java
│       │   │   │           │   └── VaultLockReceiver.java
│       │   │   │           ├── services/
│       │   │   │           │   ├── LaunchAppTileService.java
│       │   │   │           │   ├── LaunchScannerTileService.java
│       │   │   │           │   └── NotificationService.java
│       │   │   │           ├── ui/
│       │   │   │           │   ├── AboutActivity.java
│       │   │   │           │   ├── AegisActivity.java
│       │   │   │           │   ├── AssignIconsActivity.java
│       │   │   │           │   ├── AuthActivity.java
│       │   │   │           │   ├── EditEntryActivity.java
│       │   │   │           │   ├── ExitActivity.java
│       │   │   │           │   ├── GroupManagerActivity.java
│       │   │   │           │   ├── ImportEntriesActivity.java
│       │   │   │           │   ├── IntroActivity.java
│       │   │   │           │   ├── LicensesActivity.java
│       │   │   │           │   ├── MainActivity.java
│       │   │   │           │   ├── PanicResponderActivity.java
│       │   │   │           │   ├── PreferencesActivity.java
│       │   │   │           │   ├── ScannerActivity.java
│       │   │   │           │   ├── TransferEntriesActivity.java
│       │   │   │           │   ├── components/
│       │   │   │           │   │   ├── DropdownCheckBoxes.java
│       │   │   │           │   │   └── NoAutofillEditText.java
│       │   │   │           │   ├── dialogs/
│       │   │   │           │   │   ├── ChangelogDialog.java
│       │   │   │           │   │   ├── Dialogs.java
│       │   │   │           │   │   ├── IconPickerDialog.java
│       │   │   │           │   │   ├── LicenseDialog.java
│       │   │   │           │   │   └── SimpleWebViewDialog.java
│       │   │   │           │   ├── fragments/
│       │   │   │           │   │   └── preferences/
│       │   │   │           │   │       ├── AppearancePreferencesFragment.java
│       │   │   │           │   │       ├── AuditLogPreferencesFragment.java
│       │   │   │           │   │       ├── BackupsPreferencesFragment.java
│       │   │   │           │   │       ├── BehaviorPreferencesFragment.java
│       │   │   │           │   │       ├── IconPacksManagerFragment.java
│       │   │   │           │   │       ├── ImportExportPreferencesFragment.java
│       │   │   │           │   │       ├── MainPreferencesFragment.java
│       │   │   │           │   │       ├── PreferencesFragment.java
│       │   │   │           │   │       └── SecurityPreferencesFragment.java
│       │   │   │           │   ├── glide/
│       │   │   │           │   │   ├── AegisGlideModule.java
│       │   │   │           │   │   ├── GlideHelper.java
│       │   │   │           │   │   ├── SvgBytesDecoder.java
│       │   │   │           │   │   ├── SvgDecoder.java
│       │   │   │           │   │   ├── SvgDrawableTranscoder.java
│       │   │   │           │   │   ├── VaultEntryIconKey.java
│       │   │   │           │   │   └── VaultEntryIconLoader.java
│       │   │   │           │   ├── intro/
│       │   │   │           │   │   ├── IntroActivityInterface.java
│       │   │   │           │   │   ├── IntroBaseActivity.java
│       │   │   │           │   │   ├── SlideFragment.java
│       │   │   │           │   │   └── SlideIndicator.java
│       │   │   │           │   ├── models/
│       │   │   │           │   │   ├── AssignIconEntry.java
│       │   │   │           │   │   ├── AuditLogEntryModel.java
│       │   │   │           │   │   ├── ErrorCardInfo.java
│       │   │   │           │   │   ├── ImportEntry.java
│       │   │   │           │   │   └── VaultGroupModel.java
│       │   │   │           │   ├── preferences/
│       │   │   │           │   │   └── SwitchPreference.java
│       │   │   │           │   ├── slides/
│       │   │   │           │   │   ├── DoneSlide.java
│       │   │   │           │   │   ├── SecurityPickerSlide.java
│       │   │   │           │   │   ├── SecuritySetupSlide.java
│       │   │   │           │   │   └── WelcomeSlide.java
│       │   │   │           │   ├── tasks/
│       │   │   │           │   │   ├── Argon2Task.java
│       │   │   │           │   │   ├── ExportTask.java
│       │   │   │           │   │   ├── IconOptimizationTask.java
│       │   │   │           │   │   ├── ImportFileTask.java
│       │   │   │           │   │   ├── ImportIconPackTask.java
│       │   │   │           │   │   ├── KeyDerivationTask.java
│       │   │   │           │   │   ├── PBKDFTask.java
│       │   │   │           │   │   ├── PasswordSlotDecryptTask.java
│       │   │   │           │   │   ├── ProgressDialogTask.java
│       │   │   │           │   │   ├── QrDecodeTask.java
│       │   │   │           │   │   └── RootShellTask.java
│       │   │   │           │   └── views/
│       │   │   │           │       ├── AssignIconAdapter.java
│       │   │   │           │       ├── AssignIconHolder.java
│       │   │   │           │       ├── AuditLogAdapter.java
│       │   │   │           │       ├── AuditLogHolder.java
│       │   │   │           │       ├── EntryAdapter.java
│       │   │   │           │       ├── EntryHolder.java
│       │   │   │           │       ├── EntryListView.java
│       │   │   │           │       ├── ErrorCardHolder.java
│       │   │   │           │       ├── GroupAdapter.java
│       │   │   │           │       ├── GroupHolder.java
│       │   │   │           │       ├── IconAdapter.java
│       │   │   │           │       ├── IconCategoryHolder.java
│       │   │   │           │       ├── IconHolder.java
│       │   │   │           │       ├── IconPackAdapter.java
│       │   │   │           │       ├── IconPackHolder.java
│       │   │   │           │       ├── IconRecyclerView.java
│       │   │   │           │       ├── ImportEntriesAdapter.java
│       │   │   │           │       ├── ImportEntryHolder.java
│       │   │   │           │       └── TotpProgressBar.java
│       │   │   │           ├── util/
│       │   │   │           │   ├── ClipboardUtils.java
│       │   │   │           │   ├── Cloner.java
│       │   │   │           │   ├── CollectionUtils.java
│       │   │   │           │   ├── IOUtils.java
│       │   │   │           │   ├── JsonUtils.java
│       │   │   │           │   ├── PreferenceParser.java
│       │   │   │           │   ├── TimeUtils.java
│       │   │   │           │   └── UUIDMap.java
│       │   │   │           └── vault/
│       │   │   │               ├── Vault.java
│       │   │   │               ├── VaultBackupManager.java
│       │   │   │               ├── VaultBackupPermissionException.java
│       │   │   │               ├── VaultEntry.java
│       │   │   │               ├── VaultEntryException.java
│       │   │   │               ├── VaultEntryIcon.java
│       │   │   │               ├── VaultEntryIconException.java
│       │   │   │               ├── VaultException.java
│       │   │   │               ├── VaultFile.java
│       │   │   │               ├── VaultFileCredentials.java
│       │   │   │               ├── VaultFileException.java
│       │   │   │               ├── VaultGroup.java
│       │   │   │               ├── VaultHtmlExporter.java
│       │   │   │               ├── VaultManager.java
│       │   │   │               ├── VaultRepository.java
│       │   │   │               ├── VaultRepositoryException.java
│       │   │   │               └── slots/
│       │   │   │                   ├── BiometricSlot.java
│       │   │   │                   ├── PasswordSlot.java
│       │   │   │                   ├── RawSlot.java
│       │   │   │                   ├── Slot.java
│       │   │   │                   ├── SlotException.java
│       │   │   │                   ├── SlotIntegrityException.java
│       │   │   │                   ├── SlotList.java
│       │   │   │                   └── SlotListException.java
│       │   │   └── info/
│       │   │       └── guardianproject/
│       │   │           ├── GuardianProjectRSA4096.java
│       │   │           └── trustedintents/
│       │   │               ├── ApkSignaturePin.java
│       │   │               ├── LICENSE.txt
│       │   │               └── TrustedIntents.java
│       │   ├── proto/
│       │   │   └── google_auth.proto
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── fade_in.xml
│       │       │   ├── fade_out.xml
│       │       │   ├── item_animation_fall_down.xml
│       │       │   ├── item_scale_in.xml
│       │       │   ├── item_scale_out.xml
│       │       │   ├── layout_animation_fall_down.xml
│       │       │   ├── slide_down_fade_in.xml
│       │       │   ├── slide_down_fade_out.xml
│       │       │   ├── slide_in_left.xml
│       │       │   ├── slide_in_right.xml
│       │       │   ├── slide_out_left.xml
│       │       │   └── slide_out_right.xml
│       │       ├── drawable/
│       │       │   ├── baseline_arrow_right_24.xml
│       │       │   ├── favorite_indicator.xml
│       │       │   ├── ic_aegis_notification.xml
│       │       │   ├── ic_aegis_quicksettings.xml
│       │       │   ├── ic_counter_black_24.xml
│       │       │   ├── ic_export_notes.xml
│       │       │   ├── ic_filled_star_24.xml
│       │       │   ├── ic_folder_zip.xml
│       │       │   ├── ic_lock.xml
│       │       │   ├── ic_lock_open.xml
│       │       │   ├── ic_outline_add_24.xml
│       │       │   ├── ic_outline_add_photo_alternate_24.xml
│       │       │   ├── ic_outline_android_24.xml
│       │       │   ├── ic_outline_arrow_left_alt_24.xml
│       │       │   ├── ic_outline_arrow_right_alt_24.xml
│       │       │   ├── ic_outline_brush_24.xml
│       │       │   ├── ic_outline_camera_front_24.xml
│       │       │   ├── ic_outline_camera_rear_24.xml
│       │       │   ├── ic_outline_check_24.xml
│       │       │   ├── ic_outline_close_24.xml
│       │       │   ├── ic_outline_cloud_upload_24.xml
│       │       │   ├── ic_outline_code_24.xml
│       │       │   ├── ic_outline_construction_24.xml
│       │       │   ├── ic_outline_content_copy_24.xml
│       │       │   ├── ic_outline_delete_24.xml
│       │       │   ├── ic_outline_description_24.xml
│       │       │   ├── ic_outline_done_all_24.xml
│       │       │   ├── ic_outline_edit_24.xml
│       │       │   ├── ic_outline_error_24.xml
│       │       │   ├── ic_outline_expand_more_24.xml
│       │       │   ├── ic_outline_fiber_pin_24.xml
│       │       │   ├── ic_outline_group_24.xml
│       │       │   ├── ic_outline_history_24.xml
│       │       │   ├── ic_outline_info_24.xml
│       │       │   ├── ic_outline_key_24.xml
│       │       │   ├── ic_outline_layers_24.xml
│       │       │   ├── ic_outline_lock_24.xml
│       │       │   ├── ic_outline_mail_24.xml
│       │       │   ├── ic_outline_menu_24.xml
│       │       │   ├── ic_outline_more_vert_24.xml
│       │       │   ├── ic_outline_notes_24.xml
│       │       │   ├── ic_outline_package_variant_24.xml
│       │       │   ├── ic_outline_person_24.xml
│       │       │   ├── ic_outline_public_24.xml
│       │       │   ├── ic_outline_qr_code_2_24.xml
│       │       │   ├── ic_outline_refresh_24.xml
│       │       │   ├── ic_outline_reset_image_24.xml
│       │       │   ├── ic_outline_sort_24.xml
│       │       │   ├── ic_outline_star_24.xml
│       │       │   ├── ic_outline_touch_app_24.xml
│       │       │   ├── ic_outline_warning_24.xml
│       │       │   ├── ic_qrcode_scan.xml
│       │       │   ├── ic_share.xml
│       │       │   ├── ic_tag_24.xml
│       │       │   ├── ic_timeline_24.xml
│       │       │   ├── ic_unselected.xml
│       │       │   ├── item_selected.xml
│       │       │   ├── progress_horizontal.xml
│       │       │   └── rounded_popup.xml
│       │       ├── layout/
│       │       │   ├── activity_about.xml
│       │       │   ├── activity_assign_icons.xml
│       │       │   ├── activity_auth.xml
│       │       │   ├── activity_edit_entry.xml
│       │       │   ├── activity_groups.xml
│       │       │   ├── activity_import_entries.xml
│       │       │   ├── activity_intro.xml
│       │       │   ├── activity_main.xml
│       │       │   ├── activity_preferences.xml
│       │       │   ├── activity_scanner.xml
│       │       │   ├── activity_share_entry.xml
│       │       │   ├── card_assign_icon_entry.xml
│       │       │   ├── card_audit_log.xml
│       │       │   ├── card_entry.xml
│       │       │   ├── card_entry_compact.xml
│       │       │   ├── card_entry_small.xml
│       │       │   ├── card_entry_tile.xml
│       │       │   ├── card_error.xml
│       │       │   ├── card_footer.xml
│       │       │   ├── card_group.xml
│       │       │   ├── card_icon.xml
│       │       │   ├── card_icon_category.xml
│       │       │   ├── card_icon_pack.xml
│       │       │   ├── card_import_entry.xml
│       │       │   ├── card_importer.xml
│       │       │   ├── chip_group_filter.xml
│       │       │   ├── content_about.xml
│       │       │   ├── dialog_add_entry.xml
│       │       │   ├── dialog_backups_versioning_strategy.xml
│       │       │   ├── dialog_checkbox.xml
│       │       │   ├── dialog_delete_entry.xml
│       │       │   ├── dialog_duplicate_entry.xml
│       │       │   ├── dialog_error.xml
│       │       │   ├── dialog_export.xml
│       │       │   ├── dialog_icon_picker.xml
│       │       │   ├── dialog_importers.xml
│       │       │   ├── dialog_number_picker.xml
│       │       │   ├── dialog_password.xml
│       │       │   ├── dialog_plaintext_warning.xml
│       │       │   ├── dialog_progress.xml
│       │       │   ├── dialog_select_group.xml
│       │       │   ├── dialog_select_groups.xml
│       │       │   ├── dialog_text_input.xml
│       │       │   ├── dialog_time_sync.xml
│       │       │   ├── dialog_web_view.xml
│       │       │   ├── dropdown_checkbox.xml
│       │       │   ├── dropdown_list_item.xml
│       │       │   ├── fab_menu.xml
│       │       │   ├── fragment_audit_log.xml
│       │       │   ├── fragment_done_slide.xml
│       │       │   ├── fragment_entry_list_view.xml
│       │       │   ├── fragment_icon_packs.xml
│       │       │   ├── fragment_security_picker_slide.xml
│       │       │   ├── fragment_security_setup_slide.xml
│       │       │   ├── fragment_welcome_slide.xml
│       │       │   ├── popup_password.xml
│       │       │   ├── scrim_layout.xml
│       │       │   └── view_preference_switch.xml
│       │       ├── menu/
│       │       │   ├── menu_action_mode.xml
│       │       │   ├── menu_assign_icons.xml
│       │       │   ├── menu_edit.xml
│       │       │   ├── menu_groups.xml
│       │       │   ├── menu_import_entries.xml
│       │       │   ├── menu_main.xml
│       │       │   └── menu_scanner.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   ├── ic_launcher_debug.xml
│       │       │   └── ic_launcher_debug_round.xml
│       │       ├── mipmap-anydpi-v33/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_debug.xml
│       │       ├── raw/
│       │       │   ├── aboutlibraries.json
│       │       │   └── keep.xml
│       │       ├── values/
│       │       │   ├── arrays.xml
│       │       │   ├── attrs.xml
│       │       │   ├── colors.xml
│       │       │   ├── dimens.xml
│       │       │   ├── strings.xml
│       │       │   └── themes.xml
│       │       ├── values-ar-rSA/
│       │       │   └── strings.xml
│       │       ├── values-ar-rSA-v29/
│       │       │   └── strings.xml
│       │       ├── values-ast-rES/
│       │       │   └── strings.xml
│       │       ├── values-ast-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-bg-rBG/
│       │       │   └── strings.xml
│       │       ├── values-bg-rBG-v29/
│       │       │   └── strings.xml
│       │       ├── values-ca-rES/
│       │       │   └── strings.xml
│       │       ├── values-ca-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-cs-rCZ/
│       │       │   └── strings.xml
│       │       ├── values-cs-rCZ-v29/
│       │       │   └── strings.xml
│       │       ├── values-da-rDK/
│       │       │   └── strings.xml
│       │       ├── values-da-rDK-v29/
│       │       │   └── strings.xml
│       │       ├── values-de-rDE/
│       │       │   └── strings.xml
│       │       ├── values-de-rDE-v29/
│       │       │   └── strings.xml
│       │       ├── values-el-rGR/
│       │       │   └── strings.xml
│       │       ├── values-el-rGR-v29/
│       │       │   └── strings.xml
│       │       ├── values-es-rES/
│       │       │   └── strings.xml
│       │       ├── values-es-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-et-rEE/
│       │       │   └── strings.xml
│       │       ├── values-et-rEE-v29/
│       │       │   └── strings.xml
│       │       ├── values-eu-rES/
│       │       │   └── strings.xml
│       │       ├── values-eu-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-fa-rIR/
│       │       │   └── strings.xml
│       │       ├── values-fa-rIR-v29/
│       │       │   └── strings.xml
│       │       ├── values-fi-rFI/
│       │       │   └── strings.xml
│       │       ├── values-fi-rFI-v29/
│       │       │   └── strings.xml
│       │       ├── values-fr-rFR/
│       │       │   └── strings.xml
│       │       ├── values-fr-rFR-v29/
│       │       │   └── strings.xml
│       │       ├── values-fy-rNL/
│       │       │   └── strings.xml
│       │       ├── values-fy-rNL-v29/
│       │       │   └── strings.xml
│       │       ├── values-gl-rES/
│       │       │   └── strings.xml
│       │       ├── values-gl-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-hi-rIN/
│       │       │   └── strings.xml
│       │       ├── values-hi-rIN-v29/
│       │       │   └── strings.xml
│       │       ├── values-hu-rHU/
│       │       │   └── strings.xml
│       │       ├── values-hu-rHU-v29/
│       │       │   └── strings.xml
│       │       ├── values-in-rID/
│       │       │   └── strings.xml
│       │       ├── values-in-rID-v29/
│       │       │   └── strings.xml
│       │       ├── values-it-rIT/
│       │       │   └── strings.xml
│       │       ├── values-it-rIT-v29/
│       │       │   └── strings.xml
│       │       ├── values-iw-rIL/
│       │       │   └── strings.xml
│       │       ├── values-iw-rIL-v29/
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP/
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP-v29/
│       │       │   └── strings.xml
│       │       ├── values-kn-rIN/
│       │       │   └── strings.xml
│       │       ├── values-kn-rIN-v29/
│       │       │   └── strings.xml
│       │       ├── values-ko-rKR/
│       │       │   └── strings.xml
│       │       ├── values-ko-rKR-v29/
│       │       │   └── strings.xml
│       │       ├── values-lt-rLT/
│       │       │   └── strings.xml
│       │       ├── values-lt-rLT-v29/
│       │       │   └── strings.xml
│       │       ├── values-lv-rLV/
│       │       │   └── strings.xml
│       │       ├── values-lv-rLV-v29/
│       │       │   └── strings.xml
│       │       ├── values-ml-rIN/
│       │       │   └── strings.xml
│       │       ├── values-ml-rIN-v29/
│       │       │   └── strings.xml
│       │       ├── values-nb-rNO/
│       │       │   └── strings.xml
│       │       ├── values-nb-rNO-v29/
│       │       │   └── strings.xml
│       │       ├── values-nl-rNL/
│       │       │   └── strings.xml
│       │       ├── values-nl-rNL-v29/
│       │       │   └── strings.xml
│       │       ├── values-pl-rPL/
│       │       │   └── strings.xml
│       │       ├── values-pl-rPL-v29/
│       │       │   └── strings.xml
│       │       ├── values-pt-rBR/
│       │       │   └── strings.xml
│       │       ├── values-pt-rBR-v29/
│       │       │   └── strings.xml
│       │       ├── values-pt-rPT/
│       │       │   └── strings.xml
│       │       ├── values-pt-rPT-v29/
│       │       │   └── strings.xml
│       │       ├── values-ro-rRO/
│       │       │   └── strings.xml
│       │       ├── values-ro-rRO-v29/
│       │       │   └── strings.xml
│       │       ├── values-ru-rRU/
│       │       │   └── strings.xml
│       │       ├── values-ru-rRU-v29/
│       │       │   └── strings.xml
│       │       ├── values-sk-rSK/
│       │       │   └── strings.xml
│       │       ├── values-sk-rSK-v29/
│       │       │   └── strings.xml
│       │       ├── values-sr-rSP/
│       │       │   └── strings.xml
│       │       ├── values-sr-rSP-v29/
│       │       │   └── strings.xml
│       │       ├── values-sv-rSE/
│       │       │   └── strings.xml
│       │       ├── values-sv-rSE-v29/
│       │       │   └── strings.xml
│       │       ├── values-tr-rTR/
│       │       │   └── strings.xml
│       │       ├── values-tr-rTR-v29/
│       │       │   └── strings.xml
│       │       ├── values-uk-rUA/
│       │       │   └── strings.xml
│       │       ├── values-uk-rUA-v29/
│       │       │   └── strings.xml
│       │       ├── values-v27/
│       │       │   └── themes.xml
│       │       ├── values-v29/
│       │       │   └── strings.xml
│       │       ├── values-vi-rVN/
│       │       │   └── strings.xml
│       │       ├── values-vi-rVN-v29/
│       │       │   └── strings.xml
│       │       ├── values-w820dp/
│       │       │   └── dimens.xml
│       │       ├── values-zh-rCN/
│       │       │   └── strings.xml
│       │       ├── values-zh-rCN-v29/
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW/
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW-v29/
│       │       │   └── strings.xml
│       │       └── xml/
│       │           ├── backup_rules.xml
│       │           ├── backup_rules_old.xml
│       │           ├── file_paths.xml
│       │           ├── preferences.xml
│       │           ├── preferences_appearance.xml
│       │           ├── preferences_backups.xml
│       │           ├── preferences_behavior.xml
│       │           ├── preferences_import_export.xml
│       │           └── preferences_security.xml
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── beemdevelopment/
│           │           └── aegis/
│           │               ├── PreferencesTest.java
│           │               ├── crypto/
│           │               │   ├── SCryptTest.java
│           │               │   └── otp/
│           │               │       ├── HOTPTest.java
│           │               │       ├── MOTPTest.java
│           │               │       ├── TOTPTest.java
│           │               │       └── YAOTPTest.java
│           │               ├── helpers/
│           │               │   └── QrCodeAnalyzerTest.java
│           │               ├── importers/
│           │               │   └── DatabaseImporterTest.java
│           │               ├── otp/
│           │               │   ├── GoogleAuthInfoTest.java
│           │               │   ├── HotpInfoTest.java
│           │               │   ├── MotpInfoTest.java
│           │               │   ├── TotpInfoTest.java
│           │               │   └── YandexInfoTest.java
│           │               ├── util/
│           │               │   └── UUIDMapTest.java
│           │               ├── vault/
│           │               │   ├── VaultTest.java
│           │               │   └── slots/
│           │               │       └── SlotTest.java
│           │               └── vectors/
│           │                   └── VaultEntries.java
│           └── resources/
│               └── com/
│                   └── beemdevelopment/
│                       └── aegis/
│                           ├── importers/
│                           │   ├── 2fas_authenticator.json
│                           │   ├── 2fas_authenticator_encrypted.2fas
│                           │   ├── 2fas_authenticator_encrypted_v3.2fas
│                           │   ├── 2fas_authenticator_encrypted_v4.2fas
│                           │   ├── 2fas_authenticator_plain.2fas
│                           │   ├── 2fas_authenticator_plain_v3.2fas
│                           │   ├── 2fas_authenticator_plain_v4.2fas
│                           │   ├── aegis_encrypted.json
│                           │   ├── aegis_plain.json
│                           │   ├── andotp_plain.json
│                           │   ├── authy_encrypted.xml
│                           │   ├── authy_plain.xml
│                           │   ├── battle_net_authenticator.xml
│                           │   ├── bitwarden.csv
│                           │   ├── bitwarden.json
│                           │   ├── duo.json
│                           │   ├── ente_auth.txt
│                           │   ├── freeotp.xml
│                           │   ├── freeotp_plus.json
│                           │   ├── freeotp_plus_internal.xml
│                           │   ├── freeotp_v2_api23.xml
│                           │   ├── freeotp_v2_api25.xml
│                           │   ├── freeotp_v2_api27.xml
│                           │   ├── freeotp_v2_api34.xml
│                           │   ├── freeotp_v2_null_algo.xml
│                           │   ├── plain.txt
│                           │   ├── proton_authenticator.json
│                           │   ├── steam.json
│                           │   ├── steam_old.json
│                           │   ├── stratum_plain.json
│                           │   └── totp_authenticator_internal.xml
│                           └── vault/
│                               └── aegis_plain_grouped_v2.json
├── build.gradle
├── crowdin.yml
├── docs/
│   ├── decrypt.py
│   ├── iconpacks.md
│   └── vault.md
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── metadata/
│   └── en-US/
│       ├── full_description.txt
│       ├── short_description.txt
│       └── title.txt
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
buy_me_a_coffee: beemdevelopment
custom:
  - "https://www.blockchain.com/btc/address/bc1q26kyxqjkc6tu477pzy0whagwhs4ypv93qls22n"
  - "https://nanocrawler.cc/explorer/account/nano_1aegisc559b1x4p3839egnu579jkd4htpidy14eo9e31gzqmwuafypnj4q94"


================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: Bug Report
description: Create a report to help us fix a bug
labels: ["bug"]
body:
  - type: markdown
    attributes:
      value: |
        Please read the [bug reports section of the contribution guidelines](https://github.com/beemdevelopment/Aegis/blob/master/CONTRIBUTING.md#bug-reports) before submitting an issue.
  - type: input
    id: version
    attributes:
      label: Version
      description: Which version of Aegis are you using?
      placeholder: "Example: v2.1"
    validations:
      required: true
  - type: dropdown
    id: source
    attributes:
      label: Source
      description: Where did you get Aegis from?
      options:
        - Google Play
        - F-Droid
        - GitHub
        - Other
    validations:
      required: true
  - type: dropdown
    id: encryption
    attributes:
      label: Vault encryption
      description: Do you have encryption enabled for your Aegis vault?
      options:
        - "Yes (with biometric unlock)"
        - "Yes"
        - "No"
    validations:
      required: true
  - type: input
    id: device
    attributes:
      label: Device
      description: Which device are you using Aegis on?
      placeholder: "Example: Pixel 5"
    validations:
      required: true
  - type: input
    id: android_version
    attributes:
      label: Android version
      description: Which Android version is running on your device?
      placeholder: "Example: Android 13"
    validations:
      required: true
  - type: input
    id: rom
    attributes:
      label: ROM
      description: Are you using a custom ROM? If so, which one and which version? If you're using the stock OS that came with your device, you can leave this field empty.
      placeholder: "Example: GrapheneOS"
    validations:
      required: false
  - type: textarea
    id: reproduction_steps
    attributes:
      label: Steps to reproduce
      description: A detailed list of reproduction steps.
    validations:
      required: true
  - type: textarea
    id: expectations
    attributes:
      label: What do you expect to happen?
    validations:
      required: true
  - type: textarea
    id: reality
    attributes:
      label: What happens instead?
    validations:
      required: true
  - type: textarea
    id: log
    attributes:
      label: Log
      description: If applicable, paste the debug log that you captured using ADB here.
    validations:
      required: false


================================================
FILE: .github/ISSUE_TEMPLATE/feature.md
================================================
---
name: "Feature request"
about: "Suggest a new feature for this project"
labels: proposal
---



================================================
FILE: .github/workflows/build-app-workflow.yaml
================================================
name: build
on: [pull_request, push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the code
        uses: actions/checkout@v4
      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2
      - uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: 'gradle'
      - name: Build the app
        run: ./gradlew build
      - uses: actions/upload-artifact@v4
        with:
          name: apk
          path: app/build/outputs/apk/debug/app-debug.apk
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: 'gradle'
      - name: Enable KVM group perms
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm
      - name: Tests
        uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d
        with:
          api-level: 31
          arch: x86_64
          profile: pixel_3a
          heap-size: 512M
          ram-size: 4096M
          emulator-options: -memory 4096 -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: true
          disk-size: 8G
          script: |
            mkdir -p artifacts/report
            adb logcat -c
            adb logcat -G 16M && adb logcat -g
            ./gradlew connectedCheck || touch tests_failing
            adb logcat -d > artifacts/logcat.txt
            cp -r app/build/reports/androidTests/connected/* artifacts/report/
            if adb shell '[ -e /sdcard/Pictures/screenshots ]'; then adb pull /sdcard/Pictures/screenshots artifacts/; fi
            test ! -f tests_failing
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: instrumented-test-report
          path: |
            artifacts/*
          if-no-files-found: ignore


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: codeql
on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]
  schedule:
    - cron: '25 16 * * 2'
jobs:
  analyze:
    name: analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
    if: github.event_name != 'schedule' || github.repository == 'beemdevelopment/Aegis'
    steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: Exclude paths
      # The importers are excluded from analysis, because some of the apps Aegis
      # can import from don't have such great crypto, which will cause false
      # positive security alerts.
      run: |
        find app/src/main/java/com/beemdevelopment/aegis/importers ! \( -name AegisImporter.java -o -name "DatabaseImporter*" \) -type f -exec rm -f {} +
        sed -i '/Importer.class/d' app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseImporter.java
    - uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'
        cache: 'gradle'
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: java
    - name: Build
      run: ./gradlew assembleDebug
    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        category: "/language:${{matrix.language}}"


================================================
FILE: .github/workflows/crowdin.yml
================================================
name: crowdin
on:
  push:
    branches:
      - master
# run sequentially (per branch)
concurrency: "crowdin-upload-${{ github.ref }}"
jobs:
  upload-sources:
    runs-on: ubuntu-latest
    if: github.repository == 'beemdevelopment/Aegis'
    steps:
      - uses: actions/checkout@v4
      - name: Install crowdin-cli
        run: |
          wget https://github.com/crowdin/crowdin-cli/releases/download/4.6.1/crowdin-cli.zip
          echo "7afd70de3a747ac631a5bad7866008163ae1d50c4606b5773f0b90a5481ffde2  crowdin-cli.zip" | sha256sum -c
          unzip crowdin-cli.zip -d crowdin-cli
      - name: Upload to Crowdin
        env:
          CROWDIN_PERSONAL_TOKEN: "${{ secrets.CROWDIN_TOKEN }}"
        run: |
          java -jar ./crowdin-cli/4.6.1/crowdin-cli.jar upload sources \
            --no-progress \
            --branch master


================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/

# Gradle files
.gradle/
build/
release/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# Intellij
*.iml
.idea/

# Keystore files
*.jks
crowdin.properties
.crowdin/config.yml


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

Looking to contribute to Aegis? That's great! There are a couple of ways to help
out. This document contains some general guidelines for each type of
contribution.

Please review [the FAQ](FAQ.md) before reporting a bug, asking a question or
requesting a feature.

## Translations

We use [Crowdin](https://crowdin.com/project/aegis-authenticator) to crowdsource
translations of Aegis for lots of different languages. __Pull requests that
add/update a translation are no longer accepted.__ Crowdin is our single source
of truth for translations, to keep things easy to maintain.

The top 30 languages are available for translation. It's possible that yours is
not in that list. If that's the case, feel free to send us an email and we'll
add it.

## Pull requests

If you're planning on adding a new feature or making other large changes, please
discuss it with us first through [a
proposal](https://github.com/beemdevelopment/Aegis/issues/new?labels=proposal&template=feature.md)
on GitHub. Discussing your idea with us first ensures that everyone is on the
same page before you start working on your change. We don't like rejecting pull
requests.

## Bug reports

We use GitHub's issue tracker to track bugs. To make bug reports easier to
follow up on for us, please fill out the form as accurately as possible. If a
bug report does not contain enough information, it will be closed. Duplicate bug
reports receive the same treatment.

Please consider trying to find the root cause yourself first and include your
analysis of the issue in your report. Perhaps even send us a patch that fixes
it! We're happy to help you if you get stuck along the way.

### Capturing a log with ADB

In some cases, we ask our users to obtain a debug log from their device. This is
typically only necessary if Aegis:
- Is unable to recover from an error and crashes.
- Only shows a generic error to the user, but writes a more detailed one to the
  log.

Capturing a log with the Android Debug Bridge (ADB) allows us to see the stack
trace and the exception that occurred.

#### Preparation

Before you can capture a log, you first need to go through a one-time setup
process on your Android device and computer.

##### Prerequisites

- Your Android device.
- A computer with Windows, Mac or Linux.
- A USB cable to connect your Android device to your computer.

##### Setup

__On your Android device__:

1. Navigate to ``Settings -> About``, scroll down and start tapping on the build
   number until developer options are enabled.
2. Navigate to ``Settings -> System -> Developer options`` and enable ``USB
   debugging``.

These navigation steps may differ slightly across Android versions and ROMs.

__On your computer__:

3. Download and extract the SDK platform tools for Android:
   https://developer.android.com/studio/releases/platform-tools.
4. Start your terminal emulator (If you're on Windows, start PowerShell) and
   navigate to the folder where platform-tools was extracted.
5. Execute ``adb devices``.

__On your Android device__:

6. A prompt will appear. Select "Always allow from this computer" and accept the
   connection.

#### Capturing a log

__On your Android device__:

1. Start Aegis.

__On your PC__:

2. Start your terminal emulator (If you're on Windows, start PowerShell) and
   navigate to the folder where platform-tools was extracted.
3. Start a log capture by executing the following commands.

    ```
    adb logcat -c
    adb logcat > debug.log
    ```

    The logcat command captures the full system log by default, which may expose
    some sensitive information. While this information can sometimes help with
    finding the root cause of the issue, it is not always necessary. To only
    capture the log output of Aegis, replace the last logcat command with the
    one below:

    ```sh
    adb logcat --pid=$(adb shell pidof -s com.beemdevelopment.aegis) > debug.log
    ```

    _If you are using a debug APK, replace ``com.beemdevelopment.aegis`` with
   ``com.beemdevelopment.aegis.debug``._

__On your Android device__:

4. Reproduce the issue.

__On your PC__:

5. Stop the log capture with Ctrl+C.
6. Attach the ``debug.log`` file to your issue on GitHub.


================================================
FILE: FAQ.md
================================================
# FAQ

## General

### How can I contribute?

There are lots of ways! Please refer to our [contributing
guide](https://github.com/beemdevelopment/Aegis/blob/master/CONTRIBUTING.md).

### Why is the latest version not on F-Droid yet?

We don't release new versions of Aegis on F-Droid ourselves. Once we've released
a new version on GitHub, F-Droid will usually kick off their automatic build
process a day later and publish the app to their repository a couple of days
afterwards. It can sometimes take up to a week for a new version to appear on
F-Droid.

### Can you port Aegis to iOS/Windows/MacOS/Browser Extension?

We don't have plans to port Aegis to other platforms.

### Can you add support for Autofill?

On Android, only one app can be active in the Autofill slot at a time, and since
this is typically occupied by the password manager, we don't see much value in
adding support for this feature in Aegis.

### What is the difference between exporting and backing up?

Exporting is done manually and backups are done automatically. The format of the
vault file is exactly the same for both.

## Security

### I can no longer use biometrics to unlock the app. What should I do?

If you could previously unlock Aegis with biometrics, but suddenly can't do so
anymore, this is probably caused by a change made to the security settings of
your device. The app will tell you when this happened in most cases. To resolve
this, unlock the app with your password, disable biometric unlock in the
settings of Aegis and re-enable it.

### Why does Aegis keep prompting me for my password, even though I have enabled biometric authentication?

You're probably encountering the password reminder. Try entering your password
to unlock the vault once. After that, Aegis will prompt for biometrics by
default again until it's time for another password reminder.

Since forgetting your password will result in loss of access to the contents of
the vault, __we do NOT recommend disabling the password reminder__.

### Aegis uses SHA1 for most/all of my tokens. Isn't that insecure?

The hash algorithm is imposed by the service you're setting up 2FA for (e.g.
Google, Facebook, GitHub, etc). There is nothing we can do about that. If we
were to change this on Aegis' end, the tokens would stop working. Furthermore,
when using SHA1 in an HMAC calculation, the currently known issues in SHA1 are
not of concern.

### Why doesn't Aegis support biometric unlock for my device, even though it works with other apps?

The reason for this is pretty technical. In short, since you're not entering
your password when using biometric unlock, Aegis needs some other way to decrypt
the vault. For this purpose, we generate and use a key in the Android Keystore,
telling it to only allow us to use that key if the user authenticates using
their biometrics first. Some devices have buggy implementations of this feature,
resulting in the error displayed to you by Aegis in an error dialog.

If biometrics works with other apps, but not with Aegis, that means those other
apps probably perform a weaker form of biometric authentication.

## Backups

### How can I back up my Aegis vault to the cloud automatically?

Aegis can only automatically back up to the cloud if the app of your cloud
provider is installed on your device and fully participates in the Android
Storage Access Framework. Aegis doesn't have access to the internet and we don't
have plans to change this, so adding support for specific cloud providers in the
app is not possible.

Cloud providers currently known to be supported:
- Nextcloud

Another common setup is to configure Aegis to back up to a folder on local
storage of your device and then have a separate app (like
[Syncthing](https://syncthing.net/)) sync that folder anywhere you want.

## Encrypted Backups

### Why do I not get prompted to enter an encryption password when exporting?

Aegis uses the same password you have configured to encrypt your vault as the
password which is used when exporting and importing your vault; so when prompted, 
you will enter that when importing your vault.

## Importing

### When importing from Authenticator Plus, an error is shown claiming that Accounts.txt is missing

Make sure you supply an Authenticator Plus export file obtained through
__Settings -> Backup & Restore -> Export as Text and HTML__. The ``.db`` format
is not supported.

If it still doesn't work, please report the issue to us. As a temporary
workaround, you can try extracting the ZIP archive on a computer, recreating it
without a password and then importing that into Aegis. Another option is
extracting the ZIP archive on a computer and importing the resulting
Accounts.txt file into Aegis with the "Plain text" import option.


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.


================================================
FILE: README.md
================================================
<img align="left" width="80" height="80" src="metadata/en-US/images/icon.png"
alt="App icon">

# Aegis Authenticator

<br>

[![Build](https://github.com/beemdevelopment/Aegis/actions/workflows/build-app-workflow.yaml/badge.svg)](https://github.com/beemdevelopment/Aegis/actions/workflows/build-app-workflow.yaml?query=branch%3Amaster) [![Crowdin](https://badges.crowdin.net/aegis-authenticator/localized.svg)](https://crowdin.com/project/aegis-authenticator) [![Donate](https://img.shields.io/badge/donate-buy%20us%20a%20beer-%23FF813F)](https://www.buymeacoffee.com/beemdevelopment) [![Matrix](https://img.shields.io/matrix/aegis:matrix.org?color=blue)](https://matrix.to/#/#aegis:matrix.org)

**Aegis Authenticator** is a free, secure and open source 2FA app for Android.
It aims to provide a secure authenticator for your online services, while also
including some features missing in existing authenticator apps, like proper
encryption and backups. Aegis supports HOTP and TOTP, making it compatible with
thousands of services.

For a list of frequently asked questions, please check out [the FAQ](FAQ.md).

The security design of the app and the vault format is described in detail in
[this document](docs/vault.md).

## Features

- Free and open source
- Secure
  - The vault is encrypted (AES-256-GCM), and can be unlocked with:
    - Password (scrypt)
    - Biometrics (Android Keystore)
  - Screen capture prevention
  - Tap to reveal
- Compatible with Google Authenticator
- Supports industry standard algorithms:
  [HOTP](https://tools.ietf.org/html/rfc4226) and
  [TOTP](https://tools.ietf.org/html/rfc6238)
- Lots of ways to add new entries
  - Scan a QR code or an image of one
  - Enter details manually
  - Import from other authenticator apps: 2FAS Authenticator, Authenticator
    Plus, Authy, andOTP, FreeOTP, FreeOTP+, Google Authenticator, Microsoft
    Authenticator, Plain text, Steam, TOTP Authenticator and WinAuth (root
    access is required for some of these)
- Organization
  - Alphabetic/custom sorting
  - Custom or automatically generated icons
  - Group entries together
  - Advanced entry editing
  - Search by name/issuer
- Material design with multiple themes: Light, Dark, AMOLED
- Export (plaintext or encrypted)
- Automatic backups of the vault to a location of your choosing

## Screenshots

[<img width=200 alt="Screenshot 1"
src="metadata/en-US/images/phoneScreenshots/screenshot1.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot1.png?raw=true)
[<img width=200 alt="Screenshot 2"
src="metadata/en-US/images/phoneScreenshots/screenshot2.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot2.png?raw=true)
[<img width=200 alt="Screenshot 3"
src="metadata/en-US/images/phoneScreenshots/screenshot3.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot3.png?raw=true)
[<img width=200 alt="Screenshot 4"
src="metadata/en-US/images/phoneScreenshots/screenshot4.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot4.png?raw=true)

[<img width=200 alt="Screenshot 5"
src="metadata/en-US/images/phoneScreenshots/screenshot5.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot5.png?raw=true)
[<img width=200 alt="Screenshot 6"
src="metadata/en-US/images/phoneScreenshots/screenshot6.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot6.png?raw=true)
[<img width=200 alt="Screenshot 7"
src="metadata/en-US/images/phoneScreenshots/screenshot7.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot7.png?raw=true)
[<img width=200 alt="Screenshot 8"
src="metadata/en-US/images/phoneScreenshots/screenshot8.png?raw=true">](metadata/en-US/images/phoneScreenshots/screenshot8.png?raw=true)

## Downloads

Aegis is available on the Google Play Store and on F-Droid.

[<img height=80 alt="Get it on Google Play"
src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png"
/>](http://play.google.com/store/apps/details?id=com.beemdevelopment.aegis)
[<img height="80" alt="Get it on F-Droid"
src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
/>](https://f-droid.org/app/com.beemdevelopment.aegis)

### Verification

APK releases on Google Play and GitHub are signed using the same key. They can
be verified using
[apksigner](https://developer.android.com/studio/command-line/apksigner.html#options-verify):

```
apksigner verify --print-certs --verbose aegis.apk
```

The output should look like:

```
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
```

The certificate fingerprints should correspond to the ones listed below:

```
Owner: CN=Beem Development
Issuer: CN=Beem Development
Serial number: 172380c
Valid from: Sat Feb 09 14:05:49 CET 2019 until: Wed Feb 03 14:05:49 CET 2044
Certificate fingerprints:
   MD5:  AA:EE:86:DB:C7:B8:88:9F:1F:C9:D0:7A:EC:37:36:32
   SHA1: 59:FB:63:B7:1F:CE:95:74:6C:EB:1E:1A:CB:2C:2E:45:E5:FF:13:50
   SHA256: C6:DB:80:A8:E1:4E:52:30:C1:DE:84:15:EF:82:0D:13:DC:90:1D:8F:E3:3C:F3:AC:B5:7B:68:62:D8:58:A8:23
```

### Icon packs

Aegis supports icon packs to make it easier to assign icons to the entries in
your vault. There are no official icon packs, but the community maintains a
number of third-party icon packs you may want to check out. To learn how to
create your own Aegis-compatible icon pack, see [the
documentation](docs/iconpacks.md).

- [aegis-icons](https://github.com/aegis-icons/aegis-icons)

  Unofficial monochrome-styled 2FA icons.

  [<img width=500 alt="aegis-icons preview"
  src="metadata/en-US/images/iconPacks/aegis-icons.png">](https://github.com/aegis-icons/aegis-icons)

- [delta-aegis-icons](https://github.com/Delta-Icons/aegis-icons)

  Delta version of the unofficial monochrome-styled 2FA icon pack aegis-icons.

  [<img width=500 alt="delta-icons preview"
  src="metadata/en-US/images/iconPacks/delta-icons.png">](https://github.com/Delta-Icons/aegis-icons)

- [aegis-simple-icons](https://github.com/alexbakker/aegis-simple-icons) \*

  This project periodically generates an icon pack for Aegis based on [Simple
  Icons](https://simpleicons.org/).

  [<img width=500 alt="aegis-simple-icons preview"
  src="metadata/en-US/images/iconPacks/aegis-simple-icons.png">](https://github.com/alexbakker/aegis-simple-icons)

- [aegis-simple-icons-outlined](https://github.com/michaelschattgen/aegis-simple-icons-outlined) \*

  This is a variant on the aegis-simple-icons pack where the icons contain no solid background and just the outlines are being used.

  [<img width=500 alt="aegis-simple-icons-outlined preview"
  src="metadata/en-US/images/iconPacks/aegis-simple-icons-outlined.png">](https://github.com/michaelschattgen/aegis-simple-icons-outlined)

\* The icons are automatically generated, so
not all of them are as high quality as the ones you'll find in
[aegis-icons](https://github.com/aegis-icons/aegis-icons).

## Contributing

Looking to contribute to Aegis? That's great! There are a couple of ways to help
out. Translations, bug reports and pull requests are all greatly appreciated.
Please refer to our [contributing guidelines](CONTRIBUTING.md) to get started.

Swing by our Matrix room to interact with other contributors:
[#aegis:matrix.org](https://matrix.to/#/#aegis:matrix.org).

## License

This project is licensed under the GNU General Public License v3.0. See the
[LICENSE](LICENSE) file for details.

A couple of libraries vendored in Aegis' repository are licensed under a
different license:

- [TextDrawable](app/src/main/java/com/amulyakhare/textdrawable)
- [TrustedIntents](app/src/main/java/info/guardianproject/trustedintents)


================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'

def getCmdOutput = { cmd ->
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine cmd
        standardOutput = stdout
    }
    return stdout.toString().trim()
}

def getGitHash = { -> return getCmdOutput(["git", "rev-parse", "--short", "HEAD"]) }
def getGitBranch = { -> return getCmdOutput(["git", "rev-parse", "--abbrev-ref", "HEAD"]) }

def packageName = "com.beemdevelopment.aegis"
def fileProviderAuthority = "${packageName}.fileprovider"
def fileProviderAuthorityDebug = "${packageName}.debug.fileprovider"

android {
    compileSdk 35

    namespace packageName

    defaultConfig {
        applicationId "${packageName}"
        minSdkVersion 23
        targetSdkVersion 35
        versionCode 81
        versionName "3.4.2"
        multiDexEnabled true
        buildConfigField "String", "GIT_HASH", "\"${getGitHash()}\""
        buildConfigField "String", "GIT_BRANCH", "\"${getGitBranch()}\""
        buildConfigField "java.util.concurrent.atomic.AtomicBoolean", "TEST", "new java.util.concurrent.atomic.AtomicBoolean(false)"

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas"]
            }
        }

        testInstrumentationRunner "com.beemdevelopment.aegis.AegisTestRunner"
        testInstrumentationRunnerArguments clearPackageData: 'true'
    }

    testOptions {
        execution 'ANDROIDX_TEST_ORCHESTRATOR'

        unitTests {
            all {
                maxHeapSize "3g"

                ignoreFailures false
                testLogging {
                    events "passed", "skipped", "failed", "standardOut", "standardError"

                    showExceptions true
                    exceptionFormat "full"
                    showCauses true
                    showStackTraces true
                }
            }

            includeAndroidResources true
        }
    }

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            manifestPlaceholders = [
                title: "AegisDev",
                iconName: "ic_launcher_debug",
                fileProviderAuthority: "${fileProviderAuthorityDebug}"
            ]
            buildConfigField("String", "FILE_PROVIDER_AUTHORITY", "\"${fileProviderAuthorityDebug}\"")
            resValue "bool", "pref_secure_screen_default", "false"
        }
        release {
            manifestPlaceholders = [
                title: "Aegis",
                iconName: "ic_launcher",
                fileProviderAuthority: "${fileProviderAuthority}"
            ]
            buildConfigField("String", "FILE_PROVIDER_AUTHORITY", "\"${fileProviderAuthority}\"")
            resValue "bool", "pref_secure_screen_default", "true"

            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // Required to make the APK reproducible
    aaptOptions {
        cruncherEnabled = false
    }
    defaultConfig {
        vectorDrawables.generatedDensities = []
    }

    packagingOptions {
        // R8 doesn't remove these resources, so exclude them manually. This reduces APK size by 4MB.
        resources {
            excludes += [
                    '/org/bouncycastle/pqc/**/*.properties',
                    'META-INF/versions/9/OSGI-INF/MANIFEST.MF'
            ]
        }
    }

    compileOptions {
        targetCompatibility JavaVersion.VERSION_17
        sourceCompatibility JavaVersion.VERSION_17
        coreLibraryDesugaringEnabled true
    }
    lint {
        abortOnError true
        checkDependencies true
    }
    buildFeatures {
        buildConfig true
    }
}

protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.25.1'
    }
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                java {
                    option "lite"
                }
            }
        }
    }
}

aboutLibraries {
    // Tasks for aboutLibraries are not run automatically to keep the build reproducible
    // To update manually: ./gradlew app:exportLibraryDefinitions -PaboutLibraries.exportPath=src/main/res/raw
    prettyPrint = true
    configPath = "app/config"
    fetchRemoteFunding = false
    registerAndroidTasks = false
    exclusionPatterns = [~"javax.annotation.*"]
    duplicationMode = com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE
}

dependencies {
    def cameraxVersion = '1.4.2'
    def glideVersion = '4.16.0'
    def guavaVersion = '33.4.8'
    def hiltVersion = '2.56.2'
    def junitVersion = '4.13.2'
    def libsuVersion = '6.0.0'
    def roomVersion = '2.7.1'

    annotationProcessor 'androidx.annotation:annotation:1.9.1'
    annotationProcessor "androidx.room:room-compiler:$roomVersion"
    annotationProcessor "com.google.dagger:hilt-compiler:$hiltVersion"
    annotationProcessor "com.github.bumptech.glide:compiler:${glideVersion}"

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.activity:activity:1.10.1'
    implementation 'androidx.appcompat:appcompat:1.7.0'
    implementation "androidx.biometric:biometric:1.1.0"
    implementation "androidx.camera:camera-camera2:$cameraxVersion"
    implementation "androidx.camera:camera-lifecycle:$cameraxVersion"
    implementation "androidx.camera:camera-view:$cameraxVersion"
    implementation 'androidx.core:core:1.16.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
    implementation 'androidx.documentfile:documentfile:1.1.0'
    implementation 'androidx.lifecycle:lifecycle-process:2.9.0'
    implementation "androidx.preference:preference:1.2.1"
    implementation 'androidx.recyclerview:recyclerview:1.4.0'
    implementation "androidx.room:room-runtime:$roomVersion"
    implementation 'androidx.viewpager2:viewpager2:1.1.0'
    implementation 'com.caverock:androidsvg-aar:1.4'
    implementation "com.google.dagger:hilt-android:$hiltVersion"
    implementation 'com.github.avito-tech:krop:0.52'
    implementation "com.github.bumptech.glide:annotations:${glideVersion}"
    implementation "com.github.bumptech.glide:glide:${glideVersion}"
    implementation("com.github.bumptech.glide:recyclerview-integration:${glideVersion}") {
        transitive = false
    }
    implementation "com.github.topjohnwu.libsu:core:${libsuVersion}"
    implementation "com.github.topjohnwu.libsu:io:${libsuVersion}"
    implementation "com.google.guava:guava:${guavaVersion}-android"
    implementation 'com.google.android.material:material:1.12.0'
    implementation 'com.google.protobuf:protobuf-javalite:4.31.0'
    implementation 'com.google.zxing:core:3.5.3'
    implementation('com.mikepenz:aboutlibraries:11.2.3') {
        exclude group: 'com.mikepenz', module: 'aboutlibraries-core'
    }
    implementation 'com.mikepenz:aboutlibraries-core-android:11.2.3'
    implementation 'com.nulab-inc:zxcvbn:1.9.0'
    implementation 'net.lingala.zip4j:zip4j:2.11.5'
    implementation 'org.bouncycastle:bcprov-jdk18on:1.80'
    implementation 'org.simpleflatmapper:sfm-csv:8.2.3'

    androidTestAnnotationProcessor "com.google.dagger:hilt-android-compiler:$hiltVersion"
    androidTestImplementation "com.google.dagger:hilt-android-testing:$hiltVersion"
    androidTestImplementation 'androidx.test:core:1.6.1'
    androidTestImplementation 'androidx.test:runner:1.6.2'
    androidTestImplementation 'androidx.test:rules:1.6.1'
    androidTestImplementation 'androidx.test.ext:junit:1.2.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1'
    androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'
    androidTestImplementation "junit:junit:${junitVersion}"
    androidTestUtil 'androidx.test:orchestrator:1.5.1'

    testImplementation 'androidx.test:core:1.6.1'
    testImplementation "com.google.guava:guava:${guavaVersion}-jre"
    testImplementation "junit:junit:${junitVersion}"
    testImplementation 'org.json:json:20250517'
    testImplementation 'org.robolectric:robolectric:4.14.1'

    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
}


================================================
FILE: app/config/libraries/krop.json
================================================
{
    "uniqueId": "com.github.avito-tech:krop",
    "licenses": [
        "MIT"
    ]
}

================================================
FILE: app/config/libraries/libsu.json
================================================
{
    "uniqueId": "com.github.topjohnwu.libsu:.*::regex",
    "licenses": [
        "Apache-2.0"
    ]
}

================================================
FILE: app/config/libraries/textdrawable.json
================================================
{
    "uniqueId": "com.amulyakhare:com.amulyakhare.textdrawable",
    "funding": [
        
    ],
    "developers": [
        
    ],
    "artifactVersion": "1.0.1",
    "description": "This light-weight library provides images with letter/text like the Gmail app. It extends the Drawable class thus can be used with existing/custom/network ImageView classes. Also included is a fluent interface for creating drawables and a customizable ColorGenerator.",
    "name": "textdrawable",
    "licenses": [
        "MIT"
    ]
}

================================================
FILE: app/config/libraries/trustedintents.json
================================================
{
    "uniqueId": "info.guardianproject.trustedintents:trustedintents",
    "funding": [
        
    ],
    "developers": [
        {
            "name": "Guardian Project"
        }
    ],
    "artifactVersion": "0.2",
    "description": "TrustedIntents is a library for flexible trusted interactions between Android apps.  It is modeled after Android's `signature` protection level for permissions.  The key difference is that the framework allows the trusted signature to be set, rather than requiring to match the current app's signature.",
    "scm": {
        "connection": "scm:https://github.com/guardianproject/TrustedIntents.git",
        "url": "scm:https://github.com/guardianproject/TrustedIntents",
        "developerConnection": "scm:git@github.com:guardianproject/TrustedIntents.git"
    },
    "name": "TrustedIntents",
    "website": "https://guardianproject.info/code/trustedintents",
    "licenses": [
        "3ca920d1875f7ad7ab04a2a331958577"
    ]
}

================================================
FILE: app/config/licenses/3ca920d1875f7ad7ab04a2a331958577.json
================================================
{
    "hash": "3ca920d1875f7ad7ab04a2a331958577",
    "url": "https://github.com/guardianproject/TrustedIntents/blob/master/LICENSE.txt",
    "name": "LGPLv2.1"
}

================================================
FILE: app/lint.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="MissingTranslation" severity="ignore" />
    <issue id="MissingQuantity" severity="ignore" />
    <issue id="InvalidPackage">
        <ignore regexp="X509LDAPCertStoreSpi" />
    </issue>
    <issue id="NotificationPermission">
        <ignore regexp="com.bumptech.glide.request.target.NotificationTarget" />
    </issue>
    <issue id="UnusedResources" severity="error">
        <ignore path="res/raw/aboutlibraries.json" />
        <ignore regexp="res/mipmap.*/ic_launcher_debug.*.png" />
    </issue>
</lint>


================================================
FILE: app/proguard-rules.pro
================================================
-keepattributes LineNumberTable,SourceFile
-renamesourcefileattribute SourceFile
-dontobfuscate

-keepclasseswithmembers public class androidx.recyclerview.widget.RecyclerView { *; }
-keep class com.beemdevelopment.aegis.ui.fragments.preferences.*
-keep class com.beemdevelopment.aegis.importers.** { *; }
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }

-dontwarn javax.naming.**


================================================
FILE: app/schemas/com.beemdevelopment.aegis.database.AppDatabase/1.json
================================================
{
  "formatVersion": 1,
  "database": {
    "version": 1,
    "identityHash": "392278bdb797d013cb2ada67a3b1cc60",
    "entities": [
      {
        "tableName": "audit_logs",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `event_type` TEXT NOT NULL, `reference` TEXT, `timestamp` INTEGER NOT NULL)",
        "fields": [
          {
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "_eventType",
            "columnName": "event_type",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "_reference",
            "columnName": "reference",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "_timestamp",
            "columnName": "timestamp",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "autoGenerate": true,
          "columnNames": [
            "id"
          ]
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '392278bdb797d013cb2ada67a3b1cc60')"
    ]
  }
}

================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java
================================================
package com.beemdevelopment.aegis;

import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.matcher.BoundedMatcher;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.GrantPermissionRule;

import com.beemdevelopment.aegis.crypto.CryptoUtils;
import com.beemdevelopment.aegis.crypto.SCryptParameters;
import com.beemdevelopment.aegis.otp.OtpInfo;
import com.beemdevelopment.aegis.ui.views.EntryHolder;
import com.beemdevelopment.aegis.vault.VaultEntry;
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
import com.beemdevelopment.aegis.vault.VaultManager;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.VaultRepositoryException;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import com.beemdevelopment.aegis.vault.slots.SlotException;
import com.beemdevelopment.aegis.vectors.VaultEntries;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;

import java.lang.reflect.InvocationTargetException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.inject.Inject;

import dagger.hilt.android.testing.HiltAndroidRule;

public abstract class AegisTest {
    public static final String VAULT_PASSWORD = "test";
    public static final String VAULT_PASSWORD_CHANGED = "test2";
    public static final String VAULT_BACKUP_PASSWORD = "something";
    public static final String VAULT_BACKUP_PASSWORD_CHANGED = "something2";

    @Rule
    public HiltAndroidRule hiltRule = new HiltAndroidRule(this);

    @Rule
    public final GrantPermissionRule permRule = getGrantPermissionRule();

    @Inject
    protected VaultManager _vaultManager;

    @Inject
    protected Preferences _prefs;

    @Before
    public void init() {
        hiltRule.inject();
    }

    private static GrantPermissionRule getGrantPermissionRule() {
        List<String> perms = new ArrayList<>();
        // NOTE: Disabled for now. See issue: #1047
        /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            perms.add(Manifest.permission.POST_NOTIFICATIONS);
        }*/
        return GrantPermissionRule.grant(perms.toArray(new String[0]));
    }

    protected AegisApplicationBase getApp() {
        return (AegisApplicationBase) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
    }

    protected VaultRepository initEncryptedVault() {
        VaultFileCredentials creds = generateCredentials();
        return initVault(creds, VaultEntries.get());
    }

    protected VaultRepository initEmptyEncryptedVault() {
        VaultFileCredentials creds = generateCredentials();
        return initVault(creds, null);
    }

    protected VaultRepository initPlainVault() {
        return initVault(null, VaultEntries.get());
    }

    protected VaultRepository initEmptyPlainVault() {
        return initVault(null, null);
    }

    private VaultRepository initVault(@Nullable VaultFileCredentials creds, @Nullable List<VaultEntry> entries) {
        VaultRepository vault;
        try {
            vault = _vaultManager.initNew(creds);
        } catch (VaultRepositoryException e) {
            throw new RuntimeException(e);
        }

        if (entries != null) {
            for (VaultEntry entry : entries) {
                _vaultManager.getVault().addEntry(entry);
            }
        }

        try {
            _vaultManager.save();
        } catch (VaultRepositoryException e) {
            throw new RuntimeException(e);
        }

        _prefs.setIntroDone(true);
        return vault;
    }

    protected VaultFileCredentials generateCredentials() {
        PasswordSlot slot = new PasswordSlot();
        byte[] salt = CryptoUtils.generateSalt();
        SCryptParameters scryptParams = new SCryptParameters(
                CryptoUtils.CRYPTO_SCRYPT_N,
                CryptoUtils.CRYPTO_SCRYPT_r,
                CryptoUtils.CRYPTO_SCRYPT_p,
                salt
        );

        VaultFileCredentials creds = new VaultFileCredentials();
        try {
            SecretKey key = slot.deriveKey(VAULT_PASSWORD.toCharArray(), scryptParams);
            slot.setKey(creds.getKey(), CryptoUtils.createEncryptCipher(key));
        } catch (NoSuchAlgorithmException
                | InvalidKeyException
                | InvalidAlgorithmParameterException
                | NoSuchPaddingException
                | SlotException e) {
            throw new RuntimeException(e);
        }

        creds.getSlots().add(slot);
        return creds;
    }

    protected static <T extends OtpInfo> VaultEntry generateEntry(Class<T> type, String name, String issuer) {
        return generateEntry(type, name, issuer, 20);
    }

    protected static <T extends OtpInfo> VaultEntry generateEntry(Class<T> type, String name, String issuer, int secretLength) {
        byte[] secret = CryptoUtils.generateRandomBytes(secretLength);

        OtpInfo info;
        try {
            info = type.getConstructor(byte[].class).newInstance(secret);
        } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        return new VaultEntry(info, name, issuer);
    }

    // source: https://stackoverflow.com/a/30338665
    protected static ViewAction clickChildViewWithId(final int id) {
        return new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return null;
            }

            @Override
            public String getDescription() {
                return "Click on a child view with specified id.";
            }

            @Override
            public void perform(UiController uiController, View view) {
                View v = view.findViewById(id);
                v.performClick();
            }
        };
    }

    @NonNull
    protected static Matcher<RecyclerView.ViewHolder> withOtpType(Class<? extends OtpInfo> otpClass) {
        return new BoundedMatcher<RecyclerView.ViewHolder, EntryHolder>(EntryHolder.class) {
            @Override
            public boolean matchesSafely(EntryHolder holder) {
                return holder != null
                        && holder.getEntry() != null
                        && holder.getEntry().getInfo().getClass().equals(otpClass);
            }

            @Override
            public void describeTo(Description description) {
                description.appendText(String.format("with otp type '%s'", otpClass.getSimpleName()));
            }
        };
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestApplication.java
================================================
package com.beemdevelopment.aegis;

import dagger.hilt.android.testing.CustomTestApplication;

@CustomTestApplication(AegisApplicationBase.class)
public interface AegisTestApplication {
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestRunner.java
================================================
package com.beemdevelopment.aegis;

import android.app.Application;
import android.app.Instrumentation;
import android.content.Context;

import androidx.preference.PreferenceManager;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.runner.AndroidJUnitRunner;

import com.beemdevelopment.aegis.util.IOUtils;

public class AegisTestRunner extends AndroidJUnitRunner {
    static {
        BuildConfig.TEST.set(true);
    }

    @Override
    public Application newApplication(ClassLoader cl, String name, Context context)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        return Instrumentation.newApplication(AegisTestApplication_Application.class, context);
    }

    @Override
    public void callApplicationOnCreate(Application app) {
        Context context = app.getApplicationContext();

        // clear internal storage so that there is no vault file
        IOUtils.clearDirectory(context.getFilesDir(), false);

        // clear preferences so that the intro is started from MainActivity
        ApplicationProvider.getApplicationContext().getFilesDir();
        PreferenceManager.getDefaultSharedPreferences(context)
                .edit()
                .clear()
                .apply();

        super.callApplicationOnCreate(app);
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java
================================================
package com.beemdevelopment.aegis;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.pressBack;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.intent.Intents.intending;
import static androidx.test.espresso.intent.matcher.IntentMatchers.isInternal;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.net.Uri;

import androidx.annotation.Nullable;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.intent.Intents;
import androidx.test.espresso.matcher.RootMatchers;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.beemdevelopment.aegis.crypto.CryptoUtils;
import com.beemdevelopment.aegis.crypto.MasterKey;
import com.beemdevelopment.aegis.encoding.Hex;
import com.beemdevelopment.aegis.importers.DatabaseImporter;
import com.beemdevelopment.aegis.importers.DatabaseImporterException;
import com.beemdevelopment.aegis.importers.GoogleAuthUriImporter;
import com.beemdevelopment.aegis.otp.OtpInfoException;
import com.beemdevelopment.aegis.rules.ScreenshotTestRule;
import com.beemdevelopment.aegis.ui.PreferencesActivity;
import com.beemdevelopment.aegis.util.IOUtils;
import com.beemdevelopment.aegis.vault.VaultBackupManager;
import com.beemdevelopment.aegis.vault.VaultEntry;
import com.beemdevelopment.aegis.vault.VaultFile;
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
import com.beemdevelopment.aegis.vault.VaultFileException;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.VaultRepositoryException;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import com.beemdevelopment.aegis.vault.slots.SlotException;
import com.beemdevelopment.aegis.vault.slots.SlotIntegrityException;
import com.beemdevelopment.aegis.vault.slots.SlotList;
import com.beemdevelopment.aegis.vectors.VaultEntries;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;

import dagger.hilt.android.testing.HiltAndroidTest;

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@SmallTest
public class BackupExportTest extends AegisTest {
    private final ActivityScenarioRule<PreferencesActivity> _activityRule = new ActivityScenarioRule<>(PreferencesActivity.class);

    @Rule
    public final TestRule testRule = RuleChain.outerRule(_activityRule).around(new ScreenshotTestRule());

    @Before
    public void setUp() {
        Intents.init();
    }

    @After
    public void tearDown() {
        Intents.release();
    }

    @Test
    public void testPlainVaultExportPlainJson() {
        initPlainVault();

        openExportDialog();
        onView(withId(R.id.checkbox_export_encrypt)).perform(click());
        onView(withId(android.R.id.button1)).perform(click());
        onView(withId(R.id.checkbox_accept)).perform(click());
        File file = doExport();

        readVault(file, null);
    }

    @Test
    public void testPlainVaultExportPlainTxt() {
        initPlainVault();

        openExportDialog();
        onView(withId(R.id.checkbox_export_encrypt)).perform(click());
        onView(withId(R.id.dropdown_export_format)).perform(click());
        onView(withText(R.string.export_format_google_auth_uri)).inRoot(RootMatchers.isPlatformPopup()).perform(click());
        onView(withId(android.R.id.button1)).perform(click());
        onView(withId(R.id.checkbox_accept)).perform(click());
        File file = doExport();

        readTxtExport(file);
    }

    @Test
    public void testPlainVaultExportEncryptedJson() {
        initPlainVault();

        openExportDialog();
        File file = doExport();

        onView(withId(R.id.text_password)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(android.R.id.button1)).perform(click());

        readVault(file, VAULT_PASSWORD);
    }

    @Test
    public void testEncryptedVaultExportPlainJson() {
        initEncryptedVault();

        openExportDialog();
        onView(withId(R.id.checkbox_export_encrypt)).perform(click());
        onView(withId(android.R.id.button1)).perform(click());
        onView(withId(R.id.checkbox_accept)).perform(click());
        File file = doExport();

        readVault(file, null);
    }

    @Test
    public void testEncryptedVaultExportPlainTxt() {
        initEncryptedVault();

        openExportDialog();
        onView(withId(R.id.checkbox_export_encrypt)).perform(click());
        onView(withId(R.id.dropdown_export_format)).perform(click());
        onView(withText(R.string.export_format_google_auth_uri)).inRoot(RootMatchers.isPlatformPopup()).perform(click());
        onView(withId(android.R.id.button1)).perform(click());
        onView(withId(R.id.checkbox_accept)).perform(click());
        File file = doExport();

        readTxtExport(file);
    }

    @Test
    public void testEncryptedVaultExportEncryptedJson() {
        initEncryptedVault();

        openExportDialog();
        File file = doExport();

        readVault(file, VAULT_PASSWORD);
    }

    @Test
    public void testPlainVaultExportHtml() {
        initPlainVault();

        openExportDialog();
        onView(withId(R.id.checkbox_export_encrypt)).perform(click());
        onView(withId(R.id.dropdown_export_format)).perform(click());
        onView(withText(R.string.export_format_html)).inRoot(RootMatchers.isPlatformPopup()).perform(click());
        onView(withId(android.R.id.button1)).perform(click());
        onView(withId(R.id.checkbox_accept)).perform(click());
        File file = doExport();

        checkHtmlExport(file);
    }

    @Test
    public void testEncryptedVaultExportHtml() {
        initEncryptedVault();

        openExportDialog();
        onView(withId(R.id.checkbox_export_encrypt)).perform(click());
        onView(withId(R.id.dropdown_export_format)).perform(click());
        onView(withText(R.string.export_format_html)).inRoot(RootMatchers.isPlatformPopup()).perform(click());
        onView(withId(android.R.id.button1)).perform(click());
        onView(withId(R.id.checkbox_accept)).perform(click());
        File file = doExport();

        checkHtmlExport(file);
    }

    @Test
    public void testSeparateExportPassword() {
        initEncryptedVault();
        setSeparateBackupExportPassword();

        openExportDialog();
        File file = doExport();

        readVault(file, VAULT_BACKUP_PASSWORD);
    }

    @Test
    public void testChangeBackupPassword() throws SlotIntegrityException {
        initEncryptedVault();
        setSeparateBackupExportPassword();

        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_section_security_title)), click()));
        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_backup_password_change_title)), click()));
        onView(withId(R.id.text_password)).perform(typeText(VAULT_BACKUP_PASSWORD_CHANGED), closeSoftKeyboard());
        onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_BACKUP_PASSWORD_CHANGED), closeSoftKeyboard());
        onView(withId(android.R.id.button1)).perform(click());
        onView(isRoot()).perform(pressBack());

        VaultFileCredentials creds = _vaultManager.getVault().getCredentials();
        assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1);
        assertEquals(creds.getSlots().findBackupPasswordSlots().size(), 1);

        for (PasswordSlot slot : creds.getSlots().findBackupPasswordSlots()) {
            verifyPasswordSlotChange(creds, slot, VAULT_BACKUP_PASSWORD, VAULT_BACKUP_PASSWORD_CHANGED);
        }

        for (PasswordSlot slot : creds.getSlots().findRegularPasswordSlots()) {
            decryptPasswordSlot(slot, VAULT_PASSWORD);
        }

        openExportDialog();
        File file = doExport();
        readVault(file, VAULT_BACKUP_PASSWORD_CHANGED);
    }

    @Test
    public void testChangePasswordHavingBackupPassword() throws SlotIntegrityException {
        initEncryptedVault();
        setSeparateBackupExportPassword();

        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_section_security_title)), click()));
        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_set_password_title)), click()));
        onView(withId(R.id.text_password)).perform(typeText(VAULT_PASSWORD_CHANGED), closeSoftKeyboard());
        onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_PASSWORD_CHANGED), closeSoftKeyboard());
        onView(withId(android.R.id.button1)).perform(click());
        onView(isRoot()).perform(pressBack());

        VaultFileCredentials creds = _vaultManager.getVault().getCredentials();
        assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1);
        assertEquals(creds.getSlots().findBackupPasswordSlots().size(), 1);

        for (PasswordSlot slot : creds.getSlots().findRegularPasswordSlots()) {
            verifyPasswordSlotChange(creds, slot, VAULT_PASSWORD, VAULT_PASSWORD_CHANGED);
        }

        for (PasswordSlot slot : creds.getSlots().findBackupPasswordSlots()) {
            decryptPasswordSlot(slot, VAULT_BACKUP_PASSWORD);
        }

        openExportDialog();
        File file = doExport();
        readVault(file, VAULT_BACKUP_PASSWORD);
    }

    private void setSeparateBackupExportPassword() {
        VaultFileCredentials creds = _vaultManager.getVault().getCredentials();
        assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1);
        assertEquals(creds.getSlots().findBackupPasswordSlots().size(), 0);

        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_section_security_title)), click()));
        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_backup_password_title)), click()));
        onView(withId(R.id.text_password)).perform(typeText(VAULT_BACKUP_PASSWORD), closeSoftKeyboard());
        onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_BACKUP_PASSWORD), closeSoftKeyboard());
        onView(withId(android.R.id.button1)).perform(click());
        onView(isRoot()).perform(pressBack());

        creds = _vaultManager.getVault().getCredentials();
        assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1);
        assertEquals(creds.getSlots().findBackupPasswordSlots().size(), 1);
        for (PasswordSlot slot : creds.getSlots().findBackupPasswordSlots()) {
            verifyPasswordSlotChange(creds, slot, VAULT_PASSWORD, VAULT_BACKUP_PASSWORD);
        }
    }

    private void verifyPasswordSlotChange(VaultFileCredentials creds, PasswordSlot slot, String oldPassword, String newPassword) {
        assertThrows(SlotIntegrityException.class, () -> decryptPasswordSlot(slot, oldPassword));
        MasterKey masterKey;
        try {
            masterKey = decryptPasswordSlot(slot, newPassword);
        } catch (SlotIntegrityException e) {
            throw new RuntimeException("Unable to decrypt password slot", e);
        }

        assertArrayEquals(creds.getKey().getBytes(), masterKey.getBytes());
    }

    private File doExport() {
        File file = getExportFileUri();
        Intent resultData = new Intent();
        resultData.setData(Uri.fromFile(file));

        Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
        intending(not(isInternal())).respondWith(result);

        onView(withId(android.R.id.button1)).perform(click());
        return file;
    }

    private void openExportDialog() {
        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_section_import_export_title)), click()));
        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_export_title)), click()));
    }

    private MasterKey decryptPasswordSlot(PasswordSlot slot, String password) throws SlotIntegrityException {
        SecretKey derivedKey = slot.deriveKey(password.toCharArray());
        try {
            Cipher cipher = slot.createDecryptCipher(derivedKey);
            return slot.getKey(cipher);
        } catch (SlotException e) {
            throw new RuntimeException("Unable to decrypt password slot", e);
        }
    }

    private File getExportFileUri() {
        String dirName = Hex.encode(CryptoUtils.generateRandomBytes(8));
        File dir = new File(getInstrumentation().getTargetContext().getExternalCacheDir(), String.format("export-%s", dirName));
        if (!dir.mkdirs()) {
            throw new RuntimeException(String.format("Unable to create export directory: %s", dir));
        }

        VaultBackupManager.FileInfo fileInfo = new VaultBackupManager.FileInfo(VaultRepository.FILENAME_PREFIX_EXPORT);
        return new File(dir, fileInfo.toString());
    }

    private VaultRepository readVault(File file, @Nullable String password) {
        VaultRepository repo;
        try (InputStream inStream = new FileInputStream(file)) {
            byte[] bytes = IOUtils.readAll(inStream);
            VaultFile vaultFile = VaultFile.fromBytes(bytes);

            VaultFileCredentials creds = null;
            if (password != null) {
                SlotList slots = vaultFile.getHeader().getSlots();
                for (PasswordSlot slot : slots.findAll(PasswordSlot.class)) {
                    SecretKey derivedKey = slot.deriveKey(password.toCharArray());
                    Cipher cipher = slot.createDecryptCipher(derivedKey);
                    MasterKey masterKey = slot.getKey(cipher);
                    creds = new VaultFileCredentials(masterKey, slots);
                    break;
                }
            }

            repo = VaultRepository.fromFile(getInstrumentation().getContext(), vaultFile, creds);
        } catch (SlotException | SlotIntegrityException | VaultRepositoryException | VaultFileException | IOException e) {
            throw new RuntimeException("Unable to read back vault file", e);
        }

        checkReadEntries(repo.getEntries());
        return repo;
    }

    private void readTxtExport(File file) {
        GoogleAuthUriImporter importer = new GoogleAuthUriImporter(getInstrumentation().getContext());

        Collection<VaultEntry> entries;
        try (InputStream inStream = new FileInputStream(file)) {
            DatabaseImporter.State state = importer.read(inStream);
            DatabaseImporter.Result result = state.convert();
            entries = result.getEntries().getValues();
        } catch (DatabaseImporterException | IOException e) {
            throw new RuntimeException("Unable to read txt export file", e);
        }

        checkReadEntries(entries);
    }

    private void checkHtmlExport(File file) {
        try (InputStream inStream = new FileInputStream(file)) {
            Reader inReader = new InputStreamReader(inStream, StandardCharsets.UTF_8);
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser parser = factory.newPullParser();
            parser.setInput(inReader);
            while (parser.getEventType() != XmlPullParser.START_TAG) {
                parser.next();
            }
            if (!parser.getName().toLowerCase(Locale.ROOT).equals("html")) {
                throw new RuntimeException("not an html document!");
            }
            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                parser.next();
            }
        } catch (IOException | XmlPullParserException e) {
            throw new RuntimeException("Unable to read html export file", e);
        }
    }

    private void checkReadEntries(Collection<VaultEntry> entries) {
        List<VaultEntry> vectors = VaultEntries.get();
        assertEquals(vectors.size(), entries.size());

        int i = 0;
        for (VaultEntry entry : entries) {
            VaultEntry vector = vectors.get(i);
            String message = String.format("Entries are not equivalent: (%s) (%s)", vector.toJson().toString(), entry.toJson().toString());
            assertTrue(message, vector.equivalates(entry));
            try {
                assertEquals(message, vector.getInfo().getOtp(), entry.getInfo().getOtp());
            } catch (OtpInfoException e) {
                throw new RuntimeException("Unable to generate OTP", e);
            }
            i++;
        }
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/DeepLinkTest.java
================================================
package com.beemdevelopment.aegis;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static junit.framework.TestCase.assertTrue;

import android.content.Intent;
import android.net.Uri;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;

import com.beemdevelopment.aegis.otp.GoogleAuthInfo;
import com.beemdevelopment.aegis.otp.TotpInfo;
import com.beemdevelopment.aegis.ui.MainActivity;
import com.beemdevelopment.aegis.vault.VaultEntry;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import dagger.hilt.android.testing.HiltAndroidTest;

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@LargeTest
public class DeepLinkTest extends AegisTest {
    @Before
    public void before() {
        initEmptyEncryptedVault();
    }

    @Test
    public void testDeepLinkIntent() {
        VaultEntry entry = generateEntry(TotpInfo.class, "Bob", "Google");
        GoogleAuthInfo info = new GoogleAuthInfo(entry.getInfo(), entry.getName(), entry.getIssuer());
        launch(info.getUri());

        onView(withId(R.id.action_save)).perform(click());

        VaultEntry createdEntry = (VaultEntry) _vaultManager.getVault().getEntries().toArray()[0];
        assertTrue(createdEntry.equivalates(entry));
    }

    @Test
    public void testDeepLinkIntent_Empty() {
        launch(null);
    }

    @Test
    public void testDeepLinkIntent_Bad() {
        launch(Uri.parse("otpauth://bad"));
        onView(withId(android.R.id.button1)).perform(click());
    }

    @SuppressWarnings("deprecation")
    private void launch(Uri uri) {
        Intent intent = new Intent(getApp(), MainActivity.class);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(uri);

        // we need to use the deprecated ActivityTestRule class because of https://github.com/android/android-test/issues/143
        ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class);
        rule.launchActivity(intent);
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/EmptySecretTest.java
================================================
package com.beemdevelopment.aegis;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import androidx.test.core.app.ActivityScenario;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.beemdevelopment.aegis.otp.OtpInfoException;
import com.beemdevelopment.aegis.otp.TotpInfo;
import com.beemdevelopment.aegis.rules.ScreenshotTestRule;
import com.beemdevelopment.aegis.ui.MainActivity;
import com.beemdevelopment.aegis.vault.VaultEntry;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

import dagger.hilt.android.testing.HiltAndroidTest;

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@SmallTest
public class EmptySecretTest extends AegisTest {
    private ActivityScenario<MainActivity> _scenario;

    @Before
    public void before() throws OtpInfoException {
        initEmptyPlainVault();
        _vaultManager.getVault().addEntry(new VaultEntry(new TotpInfo(new byte[0])));

        _scenario = ActivityScenario.launch(MainActivity.class);
    }

    @After
    public void after() {
        _scenario.close();
    }

    @Test
    public void testVaultEntryEmptySecret() {
        onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.error_all_caps)), click()));
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/IntroTest.java
================================================
package com.beemdevelopment.aegis;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.intent.Intents.intending;
import static androidx.test.espresso.intent.matcher.IntentMatchers.isInternal;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.not;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.net.Uri;

import androidx.test.espresso.IdlingRegistry;
import androidx.test.espresso.IdlingResource;
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.intent.Intents;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.viewpager2.widget.ViewPager2;

import com.beemdevelopment.aegis.rules.ScreenshotTestRule;
import com.beemdevelopment.aegis.ui.IntroActivity;
import com.beemdevelopment.aegis.util.IOUtils;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.slots.BiometricSlot;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import com.beemdevelopment.aegis.vault.slots.SlotList;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import dagger.hilt.android.testing.HiltAndroidTest;

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@LargeTest
public class IntroTest extends AegisTest {
    private final ActivityScenarioRule<IntroActivity> _activityRule = new ActivityScenarioRule<>(IntroActivity.class);

    private ViewPager2IdlingResource _viewPager2IdlingResource;

    @Rule
    public final TestRule testRule = RuleChain.outerRule(_activityRule).around(new ScreenshotTestRule());

    @Before
    public void setUp() {
        Intents.init();

        _activityRule.getScenario().onActivity(activity -> {
            _viewPager2IdlingResource = new ViewPager2IdlingResource(activity.findViewById(R.id.pager), "viewPagerIdlingResource");
            IdlingRegistry.getInstance().register(_viewPager2IdlingResource);
        });
    }

    @After
    public void tearDown() {
        Intents.release();
        IdlingRegistry.getInstance().unregister(_viewPager2IdlingResource);
    }

    @Test
    public void testIntro_None() {
        assertFalse(_prefs.isIntroDone());
        ViewInteraction next = onView(withId(R.id.btnNext));
        ViewInteraction prev = onView(withId(R.id.btnPrevious));

        prev.check(matches(not(isDisplayed())));
        next.perform(click());
        onView(withId(R.id.rb_none)).perform(click());
        prev.perform(click());
        prev.check(matches(not(isDisplayed())));
        next.perform(click());
        next.perform(click());
        prev.check(matches(not(isDisplayed())));
        next.perform(click());

        VaultRepository vault = _vaultManager.getVault();
        assertFalse(vault.isEncryptionEnabled());
        assertNull(vault.getCredentials());
        assertTrue(_prefs.isIntroDone());
    }

    @Test
    public void testIntro_Password() {
        assertFalse(_prefs.isIntroDone());
        ViewInteraction next = onView(withId(R.id.btnNext));
        ViewInteraction prev = onView(withId(R.id.btnPrevious));

        prev.check(matches(not(isDisplayed())));
        next.perform(click());
        onView(withId(R.id.rb_password)).perform(click());
        prev.perform(click());
        prev.check(matches(not(isDisplayed())));
        next.perform(click());
        next.perform(click());
        onView(withId(R.id.text_password)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_PASSWORD + "1"), closeSoftKeyboard());
        next.perform(click());
        onView(withId(R.id.text_password_confirm)).perform(replaceText(VAULT_PASSWORD), closeSoftKeyboard());
        prev.perform(click());
        prev.perform(click());
        prev.check(matches(not(isDisplayed())));
        next.perform(click());
        next.perform(click());
        next.perform(click());
        next.perform(click());

        VaultRepository vault = _vaultManager.getVault();
        SlotList slots = vault.getCredentials().getSlots();
        assertTrue(vault.isEncryptionEnabled());
        assertTrue(slots.has(PasswordSlot.class));
        assertFalse(slots.has(BiometricSlot.class));
        assertTrue(_prefs.isIntroDone());
    }

    @Test
    public void testIntro_Import_Plain() {
        assertFalse(_prefs.isIntroDone());
        Uri uri = getResourceUri("aegis_plain.json");
        Intent resultData = new Intent();
        resultData.setData(uri);

        Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
        intending(not(isInternal())).respondWith(result);

        ViewInteraction next = onView(withId(R.id.btnNext));
        onView(withId(R.id.btnImport)).perform(click());
        next.perform(click());

        VaultRepository vault = _vaultManager.getVault();
        assertFalse(vault.isEncryptionEnabled());
        assertNull(vault.getCredentials());
        assertTrue(_prefs.isIntroDone());
    }

    @Test
    public void testIntro_Import_Encrypted() {
        assertFalse(_prefs.isIntroDone());
        Uri uri = getResourceUri("aegis_encrypted.json");
        Intent resultData = new Intent();
        resultData.setData(uri);

        Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
        intending(not(isInternal())).respondWith(result);

        ViewInteraction next = onView(withId(R.id.btnNext));
        onView(withId(R.id.btnImport)).perform(click());
        onView(withId(R.id.text_input)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(android.R.id.button1)).perform(click());
        next.perform(click());

        VaultRepository vault = _vaultManager.getVault();
        SlotList slots = vault.getCredentials().getSlots();
        assertTrue(vault.isEncryptionEnabled());
        assertTrue(slots.has(PasswordSlot.class));
        assertFalse(slots.has(BiometricSlot.class));
        assertTrue(_prefs.isIntroDone());
    }

    private Uri getResourceUri(String resourceName) {
        File targetFile = new File(getInstrumentation().getTargetContext().getExternalCacheDir(), resourceName);
        try (InputStream inStream = getClass().getResourceAsStream(resourceName);
             FileOutputStream outStream = new FileOutputStream(targetFile)) {
            IOUtils.copy(inStream, outStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return Uri.fromFile(targetFile);
    }

    // Source: https://stackoverflow.com/a/32763454/12972657
    private static class ViewPager2IdlingResource implements IdlingResource {
        private final String _resName;
        private boolean _isIdle = true;
        private IdlingResource.ResourceCallback _resourceCallback = null;

        public ViewPager2IdlingResource(ViewPager2 viewPager, String resName) {
            viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
                @Override
                public void onPageScrollStateChanged(int state) {
                    _isIdle = (state == ViewPager2.SCROLL_STATE_IDLE || state == ViewPager2.SCROLL_STATE_DRAGGING);
                    if (_isIdle && _resourceCallback != null) {
                        _resourceCallback.onTransitionToIdle();
                    }
                }
            });
            _resName = resName;
        }

        @Override
        public String getName() {
            return _resName;
        }

        @Override
        public boolean isIdleNow() {
            return _isIdle;
        }

        @Override
        public void registerIdleTransitionCallback(IdlingResource.ResourceCallback resourceCallback) {
            _resourceCallback = resourceCallback;
        }
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java
================================================
package com.beemdevelopment.aegis;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.Espresso.openContextualActionModeOverflowMenu;
import static androidx.test.espresso.action.ViewActions.clearText;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.longClick;
import static androidx.test.espresso.action.ViewActions.pressBack;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;

import androidx.annotation.IdRes;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.matcher.RootMatchers;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;

import com.beemdevelopment.aegis.encoding.Base32;
import com.beemdevelopment.aegis.encoding.Hex;
import com.beemdevelopment.aegis.otp.HotpInfo;
import com.beemdevelopment.aegis.otp.MotpInfo;
import com.beemdevelopment.aegis.otp.SteamInfo;
import com.beemdevelopment.aegis.otp.TotpInfo;
import com.beemdevelopment.aegis.otp.YandexInfo;
import com.beemdevelopment.aegis.rules.ScreenshotTestRule;
import com.beemdevelopment.aegis.ui.MainActivity;
import com.beemdevelopment.aegis.ui.views.EntryAdapter;
import com.beemdevelopment.aegis.vault.VaultEntry;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

import dagger.hilt.android.testing.HiltAndroidTest;

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@LargeTest
public class OverallTest extends AegisTest {
    private static final String _groupName = "Test";

    private final ActivityScenarioRule<MainActivity> _activityRule = new ActivityScenarioRule<>(MainActivity.class);

    @Rule
    public final TestRule testRule = RuleChain.outerRule(_activityRule).around(new ScreenshotTestRule());

    @Test
    public void testOverall() {
        ViewInteraction next = onView(withId(R.id.btnNext));
        next.perform(click());
        onView(withId(R.id.rb_password)).perform(click());
        next.perform(click());
        onView(withId(R.id.text_password)).perform(click()).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        next.perform(click());
        onView(withId(R.id.btnNext)).perform(click());

        VaultRepository vault = _vaultManager.getVault();
        assertTrue(vault.isEncryptionEnabled());
        assertTrue(vault.getCredentials().getSlots().has(PasswordSlot.class));
        assertTrue(_prefs.isIntroDone());

        List<VaultEntry> entries = Arrays.asList(
                generateEntry(TotpInfo.class, "Frank", "Google"),
                generateEntry(HotpInfo.class, "John", "GitHub"),
                generateEntry(TotpInfo.class, "Alice", "Office 365"),
                generateEntry(SteamInfo.class, "Gaben", "Steam"),
                generateEntry(YandexInfo.class, "Ivan", "Yandex", 16),
                generateEntry(MotpInfo.class, "Jimmy McGill", "PfSense", 16)
        );
        for (VaultEntry entry : entries) {
            addEntry(entry);
        }

        List<VaultEntry> realEntries = new ArrayList<>(vault.getEntries());
        for (int i = 0; i < realEntries.size(); i++) {
            String message = String.format("%s != %s", realEntries.get(i).toJson().toString(), entries.get(i).toJson().toString());
            assertTrue(message, realEntries.get(i).equivalates(entries.get(i)));
        }

        for (int i = 0; i < 10; i++) {
            onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnHolderItem(withOtpType(HotpInfo.class), clickChildViewWithId(R.id.buttonRefresh)));
        }

        AtomicBoolean isErrorCardShown = new AtomicBoolean(false);
        _activityRule.getScenario().onActivity(activity -> {
            isErrorCardShown.set(((EntryAdapter)((RecyclerView) activity.findViewById(R.id.rvKeyProfiles)).getAdapter()).isErrorCardShown());
        });

        int entryPosOffset = isErrorCardShown.get() ? 1 : 0;
        onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 0, longClick()));
        onView(withId(R.id.action_copy)).perform(click());

        onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 1, longClick()));
        onView(withId(R.id.action_edit)).perform(click());
        onView(withId(R.id.text_name)).perform(clearText(), typeText("Bob"), closeSoftKeyboard());
        onView(withId(R.id.text_group)).perform(click());
        onView(withId(R.id.addGroup)).inRoot(RootMatchers.isDialog()).perform(click());
        onView(withId(R.id.text_input)).perform(typeText(_groupName), closeSoftKeyboard());
        onView(withId(android.R.id.button1)).perform(click());
        onView(withText(R.string.save)).perform(click());
        onView(isRoot()).perform(pressBack());
        onView(withId(android.R.id.button1)).perform(click());

        changeSort(R.string.sort_alphabetically_name);
        changeSort(R.string.sort_alphabetically_name_reverse);
        changeSort(R.string.sort_alphabetically);
        changeSort(R.string.sort_alphabetically_reverse);
        changeSort(R.string.sort_custom);

        changeGroupFilter(_groupName);
        changeGroupFilter(null);

        onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 2, longClick()));
        onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 3, click()));
        onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 4, click()));
        onView(withId(R.id.action_share_qr)).perform(click());
        onView(withId(R.id.btnNext)).perform(click()).perform(click()).perform(click());

        onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 0, longClick()));
        onView(allOf(isDescendantOfA(withClassName(containsString("ActionBarContextView"))), withClassName(containsString("OverflowMenuButton")))).perform(click());
        onView(withText(R.string.action_delete)).perform(click());
        onView(withId(android.R.id.button1)).perform(click());

        openContextualActionModeOverflowMenu();
        onView(withText(R.string.lock)).perform(click());
        onView(withId(R.id.text_password)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(R.id.button_decrypt)).perform(click());
        vault = _vaultManager.getVault();

        openContextualActionModeOverflowMenu();
        onView(withText(R.string.action_settings)).perform(click());
        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_section_security_title)), click()));
        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItemAtPosition(1, click()));
        onView(withId(android.R.id.button1)).perform(click());

        assertFalse(vault.isEncryptionEnabled());
        assertNull(vault.getCredentials());

        onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItemAtPosition(1, click()));
        onView(withId(R.id.text_password)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
        onView(withId(android.R.id.button1)).perform(click());

        assertTrue(vault.isEncryptionEnabled());
        assertTrue(vault.getCredentials().getSlots().has(PasswordSlot.class));
    }

    private void changeSort(@IdRes int resId) {
        onView(withId(R.id.action_sort)).perform(click());
        onView(withText(resId)).perform(click());
    }

    private void changeGroupFilter(String text) {
        if (text == null) {
            onView(allOf(withText(R.string.no_group), isDescendantOfA(withId(R.id.groupChipGroup)))).perform(click());
        } else {
            onView(allOf(withText(text), isDescendantOfA(withId(R.id.groupChipGroup)))).perform(click());
        }
    }

    private void addEntry(VaultEntry entry) {
        onView(withId(R.id.fab)).perform(click());
        onView(withId(R.id.fab_menu_item_enter)).perform(click());

        onView(withId(R.id.accordian_header)).perform(scrollTo(), click());
        onView(withId(R.id.text_name)).perform(typeText(entry.getName()), closeSoftKeyboard());
        onView(withId(R.id.text_issuer)).perform(typeText(entry.getIssuer()), closeSoftKeyboard());

        if (entry.getInfo().getClass() != TotpInfo.class) {
            String otpType;
            if (entry.getInfo() instanceof HotpInfo) {
                otpType = "HOTP";
            } else if (entry.getInfo() instanceof SteamInfo) {
                otpType = "Steam";
            } else if (entry.getInfo() instanceof YandexInfo) {
                otpType = "Yandex";
            } else if (entry.getInfo() instanceof MotpInfo) {
                otpType = "MOTP";
            } else if (entry.getInfo() instanceof TotpInfo) {
                otpType = "TOTP";
            } else {
                throw new RuntimeException(String.format("Unexpected entry type: %s", entry.getInfo().getClass().getSimpleName()));
            }

            onView(withId(R.id.dropdown_type)).perform(scrollTo(), click());
            onView(withText(otpType)).inRoot(RootMatchers.isPlatformPopup()).perform(click());
        }

        String secret;
        if (Objects.equals(entry.getInfo().getTypeId(), MotpInfo.ID)) {
            secret = Hex.encode(entry.getInfo().getSecret());
        } else {
            secret = Base32.encode(entry.getInfo().getSecret());
        }

        onView(withId(R.id.text_secret)).perform(typeText(secret), closeSoftKeyboard());

        if (entry.getInfo() instanceof YandexInfo) {
            String pin = "123456";
            ((YandexInfo) entry.getInfo()).setPin(pin);
            onView(withId(R.id.text_pin)).perform(typeText(pin), closeSoftKeyboard());
        } else if (entry.getInfo() instanceof MotpInfo) {
            String pin = "1234";
            ((MotpInfo) entry.getInfo()).setPin(pin);
            onView(withId(R.id.text_pin)).perform(typeText(pin), closeSoftKeyboard());
        }

        onView(withId(R.id.action_save)).perform(click());
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/PanicTriggerTest.java
================================================
package com.beemdevelopment.aegis;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import android.content.Intent;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ActivityTestRule;

import com.beemdevelopment.aegis.ui.PanicResponderActivity;
import com.beemdevelopment.aegis.vault.VaultRepository;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import dagger.hilt.android.testing.HiltAndroidTest;

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@SmallTest
public class PanicTriggerTest extends AegisTest {
    @Before
    public void before() {
        initEncryptedVault();
    }

    @Test
    public void testPanicTriggerDisabled() {
        assertFalse(_prefs.isPanicTriggerEnabled());
        assertTrue(_vaultManager.isVaultLoaded());
        launchPanic();
        assertTrue(_vaultManager.isVaultLoaded());
        _vaultManager.getVault();
        assertTrue(VaultRepository.fileExists(getApp()));
    }

    @Test
    public void testPanicTriggerEnabled() {
        _prefs.setIsPanicTriggerEnabled(true);
        assertTrue(_prefs.isPanicTriggerEnabled());
        assertTrue(_vaultManager.isVaultLoaded());
        launchPanic();
        assertFalse(_vaultManager.isVaultLoaded());
        assertThrows(IllegalStateException.class, () -> _vaultManager.getVault());
        assertFalse(VaultRepository.fileExists(getApp()));
    }

    private void launchPanic() {
        Intent intent = new Intent(PanicResponderActivity.PANIC_TRIGGER_ACTION);
        // we need to use the deprecated ActivityTestRule class because of https://github.com/android/android-test/issues/143
        ActivityTestRule<PanicResponderActivity> rule = new ActivityTestRule<>(PanicResponderActivity.class);
        rule.launchActivity(intent);
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/rules/ScreenshotTestRule.java
================================================
package com.beemdevelopment.aegis.rules;

import android.graphics.Bitmap;

import androidx.test.runner.screenshot.BasicScreenCaptureProcessor;
import androidx.test.runner.screenshot.ScreenCapture;
import androidx.test.runner.screenshot.ScreenCaptureProcessor;
import androidx.test.runner.screenshot.Screenshot;

import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

import java.io.IOException;
import java.util.HashSet;

public class ScreenshotTestRule extends TestWatcher {
    @Override
    protected void failed(Throwable e, Description description) {
        super.failed(e, description);

        String filename = description.getTestClass().getSimpleName() + "-" + description.getMethodName();

        ScreenCapture capture = Screenshot.capture();
        capture.setName(filename);
        capture.setFormat(Bitmap.CompressFormat.PNG);

        HashSet<ScreenCaptureProcessor> processors = new HashSet<>();
        processors.add(new BasicScreenCaptureProcessor());

        try {
            capture.process(processors);
        } catch (IOException e2) {
            e.printStackTrace();
        }
    }
}


================================================
FILE: app/src/androidTest/java/com/beemdevelopment/aegis/vault/VaultRepositoryTest.java
================================================
package com.beemdevelopment.aegis.vault;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.beemdevelopment.aegis.AegisTest;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import dagger.hilt.android.testing.HiltAndroidTest;

@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@SmallTest
public class VaultRepositoryTest extends AegisTest {
    @Before
    public void before() {
        initEncryptedVault();
    }

    @Test
    public void testToggleEncryption() throws VaultRepositoryException {
        VaultRepository vault = _vaultManager.getVault();
        _vaultManager.disableEncryption();
        assertFalse(vault.isEncryptionEnabled());
        assertNull(vault.getCredentials());

        VaultFileCredentials creds = generateCredentials();
        _vaultManager.enableEncryption(creds);
        assertTrue(vault.isEncryptionEnabled());
        assertNotNull(vault.getCredentials());
        assertEquals(vault.getCredentials().getSlots().findAll(PasswordSlot.class).size(), 1);
    }
}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.USE_BIOMETRIC" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <!-- NOTE: Disabled for now. See issue: #1047
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    -->

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false" />

    <application
        android:name=".AegisApplication"
        android:allowBackup="true"
        android:fullBackupOnly="true"
        android:fullBackupContent="@xml/backup_rules_old"
        android:dataExtractionRules="@xml/backup_rules"
        android:backupAgent=".AegisBackupAgent"
        android:enableOnBackInvokedCallback="true"
        android:icon="@mipmap/${iconName}"
        android:label="Aegis"
        android:supportsRtl="true"
        android:largeHeap="true"
        android:theme="@style/Theme.Aegis.Launch"
        tools:targetApi="tiramisu">
        <activity android:name=".ui.TransferEntriesActivity"
            android:label="@string/title_activity_transfer" />
        <activity
            android:name=".ui.AboutActivity"
            android:label="@string/title_activity_about" />
        <activity
            android:name=".ui.ImportEntriesActivity"
            android:label="@string/title_activity_import_entries" />
        <activity
            android:name=".ui.MainActivity"
            android:exported="true"
            android:label="${title}">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="otpauth" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ui.ScannerActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:label="@string/title_activity_scan_qr"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.EditEntryActivity"
            android:label="@string/title_activity_edit_entry" />
        <activity
            android:name=".ui.IntroActivity"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.AuthActivity" />
        <activity
            android:name=".ui.PreferencesActivity"
            android:label="@string/title_activity_preferences" />
        <activity
            android:name=".ui.GroupManagerActivity"
            android:label="@string/title_activity_manage_groups" />
        <activity android:name=".ui.AssignIconsActivity"
            android:label="@string/title_activity_assign_icons"/>
        <activity android:name=".ui.LicensesActivity"
            android:label="@string/title_activity_licenses"/>
        <activity
            android:name=".ui.PanicResponderActivity"
            android:exported="true"
            android:launchMode="singleInstance"
            android:noHistory="true"
            android:theme="@android:style/Theme.NoDisplay">
            <intent-filter>
                <action android:name="info.guardianproject.panic.action.TRIGGER" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name=".ui.ExitActivity" />

        <!-- NOTE: Disabled for now. See issue: #1047
        <service android:name=".services.NotificationService" />
        -->

        <service
            android:name=".services.LaunchAppTileService"
            android:label="@string/tile_open_vault"
            android:icon="@drawable/ic_aegis_quicksettings"
            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
            android:exported="true">
            <intent-filter>
                <action android:name="android.service.quicksettings.action.QS_TILE" />
            </intent-filter>
            <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
                android:value="true" />
        </service>

        <service
            android:name=".services.LaunchScannerTileService"
            android:label="@string/tile_open_scanner"
            android:icon="@drawable/ic_aegis_quicksettings"
            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
            android:exported="true">
            <intent-filter>
                <action android:name="android.service.quicksettings.action.QS_TILE" />
            </intent-filter>
            <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
                android:value="true" />
        </service>

        <receiver android:name=".receivers.VaultLockReceiver" android:exported="false">
            <intent-filter>
                <action android:name="${applicationId}.LOCK_VAULT" />
            </intent-filter>
        </receiver>

        <receiver
            android:name=".receivers.QsTileRefreshReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_UNLOCKED" />
            </intent-filter>
        </receiver>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${fileProviderAuthority}"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths">
            </meta-data>
        </provider>

        <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" />
    </application>

    <queries>
        <package android:name="com.stratumauth.app" />
        <package android:name="com.authy.authy" />
        <package android:name="org.fedorahosted.freeotp" />
        <package android:name="org.liberty.android.freeotpplus" />
        <package android:name="com.google.android.apps.authenticator2" />
        <package android:name="com.azure.authenticator" />
        <package android:name="com.valvesoftware.android.steam.community" />
        <package android:name="com.authenticator.authservice2" />
        <package android:name="com.duosecurity.duomobile" />
        <package android:name="com.blizzard.messenger" />
    </queries>

</manifest>


================================================
FILE: app/src/main/assets/changelog.html
================================================
<html>
    <head>
        <style type="text/css">
            * {
            word-wrap: break-word;
            }
            body {
                background-color: %1$s;
                color: %2$s;
            }
            ul {
                list-style-position: inside;
                padding: 0;
                padding-left: 5px;
                margin-bottom: 5px;
            }
            li {
                padding-bottom: 8px;
                list-style-position: outside;
                margin-left: 1em;
            }
            h4 {
                margin-top: 0px;
                margin-bottom: 0px;
            }
            h3 {
                margin-bottom: 7px;
                padding-top: 7px;
            }
        </style>
    </head>
    <body>
        <div></div>
        <h3>Version 3.4.2</h3>
        <p>
            This version fixes the quick settings tile staying inactive permanently after upgrading to Android 16.
        </p>
        <h4>New</h4>
        <ul>
            <li>Redesigned FAB menu</li>
            <li>Ability to import otpauth uri from clipboard</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Fix quick settings tile state</li>
            <li>Disable autofill services in 'Edit Entry' screen to avoid accidental overwriting master password</li>
            <li>Inverted positions of buttons in 'Select Group' dialog</li>
            <li>Remove redundant padding in tiles view</li>
        </ul>
        <h3>Version 3.4.1</h3>
        <h4>New</h4>
        <ul>
            <li>Support for importing from Proton Authenticator</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>The autofill service would show a prompt to save the PIN as a password</li>
        </ul>
        <h3>Version 3.4</h3>
        <h4>New</h4>
        <ul>
            <li>Haptic feedback when an entry is about to expire</li>
            <li>Brightness increase is now toggleable in the entry transfer view</li>
            <li>Filter on multiple groups simultaneously</li>
            <li>Color contrast on hidden codes has been improved</li>
            <li>Prompt before the user is about to save an entry with a duplicate name/issuer combination</li>
            <li>New languages: Estonian, Korean, Malayalam, Norwegian (Bokmål) and Serbian</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>A crash could occur if an entry with period 7 exists and code expiry indication is enabled</li>
            <li>The Portuguese (Brazilian) locale was used even if Portuguese was configured</li>
            <li>FreeOTP import would fail if the algorithm or digits field was not specified for an entry</li>
            <li>The divider between entries would be missing in certain filter configurations</li>
            <li>The snackbar in try entry importing view could obstruct the name of an entry</li>
        </ul>
        <h4>Miscellaneous</h4>
        <ul>
            <li>Android 6 or newer is now required the run the app</li>
        </ul>
        <h3>Version 3.3.4</h3>
        <h4>Fixes</h4>
        <ul>
            <li>Icons are now resized to 512x512 to reduce the size of the vault file and to reduce the chance of encountering out of memory conditions</li>
        </ul>
        <h3>Version 3.3.3</h3>
        <h4>Fixes</h4>
        <ul>
            <li>Some users ran into out of memory conditions due to large icons in their vault file. We've introduced a temporary measure that should help in most cases, but we'll follow up with a more comprehensive fix soon.</li>
            <li>Window insets were not always applied correctly, causing parts of the UI to appear off-screen</li>
            <li>The 2FAS importer did not tolerate spaces for secrets and was not always able to extract the issuer</li>
        </ul>
        <h3>Version 3.3.2</h3>
        <h4>New</h4>
        <ul>
            <li>Find entries by searching in multiple fields simultaneously</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Entries would not actually be added to the Aegis vault in some cases when importing from Google Authenticator export QR codes</li>
            <li>The lock button was sometimes shown for unencrypted vaults</li>
            <li>The sort category menu item did not always reflect the current sorting</li>
            <li>The next code was not always easy to read because its color had low contrast with the background</li>
            <li>Entry selection was not cancelled when changing the group filter</li>
        </ul>
        <h3>Version 3.3.1</h3>
        <h4>Fixes</h4>
        <ul>
            <li>Codes were not shown in case the tiles view mode was combined with hidden account names</li>
        </ul>
        <h3>Version 3.3</h3>
        <h4>New</h4>
        <ul>
            <li>Significant improvements to group filtering
                <ul>
                    <li>Groups can now be filtered on straight from the main view instead of through a dialog</li>
                    <li>Ability to assign multiple entries to a group in one go</li>
                    <li>Support for reordering groups</li>
                </ul>
            </li>
            <li>Codes now change color when they're about to expire</li>
            <li>Option to show the next code ahead of time</li>
            <li>Support for backing up to a single file (This enables support for more cloud providers, such as Google Drive)</li>
            <li>Various minor improvements to make QR code exports easier to scan</li>
            <li>Support for importing from Ente Auth</li>
            <li>Support for importing FreeOTP 2 backups</li>
            <li>Updated translations</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>QR codes exported for Google Authenticator could not be scanned on iOS</li>
            <li>The code would be copied after a single tap in case "Tap to reveal" and "Copy tokens to the clipboard" were enabled simultaneously</li>
            <li>Various other minor UI, stability and performance improvements</li>
        </ul>
        <h3>Version 3.2</h3>
        <h4>New</h4>
        <ul>
            <li>The ability to add a single entry to multiple groups</li>
            <li>Option to keep an infinite number of backups</li>
            <li>Option to customize which fields to search for in entries</li>
            <li>Allow hiding entry names in the tiled view mode</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>With "Tap to reveal" enabled, the size of the shown dots would not be consistent with the size of the code digits, on some devices</li>
            <li>After importing a backup, the UI would in some cases incorrectly claim that biometric unlock is enabled</li>
            <li>The export dialog was not fully visible on some devices</li>
            <li>Various other minor UI, stability and performance improvements</li>
        </ul>
        <h3>Version 3.1.1</h3>
        <h4>Fixes</h4>
        <p>
            A recent Android Pixel update introduced a bug causing Aegis to sometimes show a black screen after unlocking the vault.
            We have reported this issue to the Google Issue Tracker (<a href="https://issuetracker.google.com/issues/352963108">link</a>) and
            are awaiting a response from Google. In the meantime, we have implemented a workaround that eliminates this bug.
        </p>
        <ul>
            <li>Group filter now gets applied properly upon unlocking the vault</li>
            <li>Advanced entry settings now gets shown correctly</li>
            <li>Keyboard when searching for entries now gets hidden when the user starts scrolling through the list</li>
        </ul>
        <h3>Version 3.1</h3>
        <h4>New</h4>
        <ul>
            <li>A new audit log has been added to check all important events that occurred in your vault</li>
            <li>Added the ability to rename groups</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Group selection will now be remembered again upon launch</li>
            <li>Various UI improvements</li>
            <li>Stability fixes</li>
        </ul>
        <h3>Version 3.0.1</h3>
        <h4>New</h4>
        <ul>
            <li>Support for importing from the new Battle.net app</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Visual glitches when AMOLED theme was used on old Android versions</li>
            <li>Minor UI improvements</li>
        </ul>
        <h3>Version 3.0</h3>
        <h4>New</h4>
        <ul>
            <li>Material 3 (and Material You)</li>
            <li>Automatic assignment of icons to entries</li>
            <li>Ability to select all entries in one go</li>
            <li>Support for importing 2FAS schema v4 backups</li>
            <li>Sort entries based on the last time they were used</li>
            <li>Some clarifications related to importing and backup permission errors</li>
            <li>Preparations for the ability to assign a single entry to multiple groups</li>
            <li>Performance improvements when scrolling through an entry list with lots of icons</li>
            <li>A new look for the third-party licenses list</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Directly importing from Authy using root would fail</li>
            <li>Minor glitches related to animation duration scale settings</li>
            <li>Various stability improvements</li>
        </ul>
        <h3>Version 2.2.2</h3>
        <h4>New</h4>
        <ul>
            <li>An optional name field for icon packs to bypass filename character restrictions</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>The Authenticator Pro importer only supported the legacy backup format</li>
            <li>A crash could occur in the tile service</li>
        </ul>
        <h3>Version 2.2.1</h3>
        <h4>New</h4>
        <ul>
            <li>Ability to automatically skip potential duplicates when importing entries</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Biometrics button on the unlock screen was unresponsive</li>
        </ul>
        <h3>Version 2.2</h3>
        <h4>New</h4>
        <ul>
            <li>Authenticator Pro encrypted import support</li>
            <li>Ability to change account name position</li>
            <li>A new dialog explaining how our password reminder works</li>
            <li>Ability to change copy behavior</li>
            <li>Ability to only show account names when necessary</li>
            <li>New view mode: Tiles/Grid</li>
            <li>Added translation: Dutch (Frysian)</li>
            <li>Updated translations</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Deleting an entry while a search filter is active now shows the correct state</li>
            <li>Aegis now fully respects system animation settings</li>
        </ul>
        <h3>Version 2.1.3</h3>
        <h4>New</h4>
        <ul>
            <li>Option to disable the backup reminder</li>
            <li>Improved group selection dropdown during vault export</li>
            <li>New translation: Hebrew</li>
            <li>Updated translations</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>A crash could occur because a Toast was incorrectly created</li>
        </ul>
        <h3>Version 2.1.2</h3>
        <h4>Fixes</h4>
        <ul>
            <li>A crash could occur when changing an entry in such a way that it is filtered out from the entry list</li>
        </ul>
        <h3>Version 2.1.1</h3>
        <h4>New</h4>
        <ul>
            <li>An option to export the vault as an HTML file</li>
            <li>Support for importing from Battle.net Authenticator (root required)</li>
            <li>An option to hide entry icons</li>
            <li>An option to only include certain groups in an export</li>
            <li>Copying a token now takes a second tap if tap to reveal is enabled</li>
            <li>The ability to copy the URI when transferring entries through QR codes</li>
            <li>Updated translations</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>The lock notification would remain after locking the vault in certain cases. For now, we've disabled the notification entirely.</li>
            <li>Making changes to an entry while having one or more favorited entries in the vault could result in buggy ordering</li>
            <li>Tapping to the reveal a token could increase the height of the entry in certain view modes on recent Android versions</li>
            <li>The backup reminder was unclear about when the last successful backup took place</li>
            <li>Users could accidentally select MD5 as the hash algorithm for non-mOTP entry types, causing crashes at seemingly random intervals. Any users who have gotten themselves into this situation will see these bad entries get reset to SHA1.</li>
            <li>Importing from certain apps would cause a crash if an empty password was entered</li>
            <li>The andOTP importer could hang indefinitely if the user accidentally selected a non-andOTP file.</li>
            <li>Various other stability improvements</li>
        </ul>
        <h3>Version 2.1</h3>
        <h4>New</h4>
        <ul>
            <li>Support for mOTP</li>
            <li>Support for Yandex OTP (Experimental)</li>
            <li>An Adaptive Icon for Material You</li>
            <li>Ability to favorite certain entries and pin them to the top of the entry list</li>
            <li>Ability to filter by entries that are not in a group</li>
            <li>Ability to set a separate password that is used for encrypting backups and exports</li>
            <li>Support for predictive back gesture</li>
            <li>Improved overview of backup status in preferences</li>
            <li>Additional options for code digit grouping</li>
            <li>Support for importing from Duo</li>
            <li>Support for importing from Bitwarden</li>
            <li>Support for importing multiple QR code images in one go</li>
            <li>Support for scanning Google Authenticator export QR codes from image files</li>
            <li>Display some extra information in the dialog displayed when deleting an entry</li>
            <li>An option to export through Google Authenticator export QR code images</li>
            <li>An option to import an existing vault file from the first page in the intro</li>
            <li>An option to minimize the app after copying a token</li>
            <li>A count of the total number of entries is displayed at the bottom of the entry list</li>
            <li>A backup reminder is shown if changes were made to the vault, but no backup or export has been created yet since then</li>
            <li>A warning is shown after a plaintext export has been made</li>
            <li>An option to focus search immediately after the app starts</li>
            <li>Allow customization of the frequency of the password reminder</li>
            <li>Allow sharing text to Aegis in the format of a Google Authenticator URI to add as a new entry</li>
            <li>Always allow D2D (device-to-device) Android backups regardless of backup settings</li>
            <li>Mark clipboard data as sensitive when copying tokens so that Android will mask them in the UI</li>
            <li>Updated translations for almost all languages</li>
            <li>New languages: Asturian, Catalan, Galician</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Various reliability improvements for the QR code scanner</li>
            <li>The floating action button was glitchy when making small entry list scroll movements</li>
            <li>The vault unlocked notification was never shown and was still using the old app icon</li>
            <li>The automatically generated entry icon was broken if the entry name/issuer is a multi-codepoint character (certain emoji's, for example)</li>
            <li>The PIN keyboard was not disabled after enabling encryption</li>
            <li>The password prompt message was unclear when importing from a file</li>
            <li>The entry list was not sorted correctly if a change to an entry caused its location to change</li>
            <li>Quickly double-tapping on the copy button would cause a crash</li>
            <li>Importing an entry with an empty secret would cause a crash loop</li>
            <li>On certain devices, it was not possible to import icon packs because the .ZIP files would be grayed out</li>
            <li>An unclear error message was shown when trying to import from Steam and Google Authenticator</li>
            <li>Various other minor UI and stability improvements</li>
        </ul>
        <h3>Version 2.0.3</h3>
        <h4>New</h4>
        <ul>
            <li>Support for importing 2FAS Authenticator's new backup format</li>
        </ul>
        <h3>Version 2.0.2</h3>
        <h4>New</h4>
        <ul>
            <li>Add a note field to entries</li>
            <li>An option to pause code updating of highlighted entries</li>
            <li>New translation: Lithuanian</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Minor UI and stability improvements</li>
            <li>The Microsoft Authenticator importer did not accept spaces and dashes in secrets</li>
        </ul>
        <h3>Version 2.0.1</h3>
        <h4>New</h4>
        <ul>
            <li>Support for sorting on most used tokens</li>
            <li>Some minor UX and stability improvements</li>
            <li>New translation: Vietnamese</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>QR code information was decoded incorrectly in some cases if the app was set to a certain language (Turkish, for example)</li>
        </ul>
        <h3>Version 2.0</h3>
        <h4>New</h4>
        <ul>
            <li>Support for icon packs</li>
            <li>Support for participation in Android's backup system (Google Drive, Seedvault)</li>
            <li>UI refresh (switched to the Material Components theme)</li>
            <li>Bottom sheet with chips to filter on groups</li>
            <li>Support for importing from 2FAS Authenticator</li>
            <li>Search in account names by default (and remove the setting)</li>
            <li>Replaced the FAB with a bottom sheet dialog</li>
            <li>Reorganization of settings into separate categories</li>
            <li>Ability to 'share' images of QR codes to scan in Aegis</li>
            <li>Option to save the current group filter</li>
            <li>New translations for Bulgarian, Danish, Latvian, Swedish and Ukranian</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>The QR code scanner had trouble detecting QR codes on some devices due to low resolution image capture</li>
            <li>The app would vanish from the recent apps list after locking</li>
            <li>When importing from Nextcloud, Aegis would report that the file could not be found.</li>
            <li>The biometrics prompt would not appear on some devices</li>
            <li>The app would lock when selecting a file/icon on certain devices and configurations</li>
            <li>There were multiple layout issues on small screen devices</li>
            <li>Various other usability, performance and stability improvements</li>
        </ul>
        <h3>Version 1.4.2</h3>
        <h4>Fixes</h4>
        <ul>
            <li>The app would crash if DocumentsUI is not present on the device</li>
            <li>The app would close when selecting an icon if auto lock on minimize was enabled</li>
            <li>Importing from Authy was flaky for entries that have an icon</li>
            <li>The dark theme was not properly applied to the QR code scanner view</li>
            <li>The app would crash on plain text export on some devices</li>
            <li>Importing from Authenticator Plus stopped working</li>
        </ul>
        <h3>Version 1.4.1</h3>
        <h4>Fixes</h4>
        <ul>
            <li>Scanning QR codes stopped working on certain devices (primarily OnePlus)</li>
        </ul>
        <h3>Version 1.4</h3>
        <h4>New</h4>
        <ul>
            <li>Optionally delete the vault if a panic trigger is received from Ripple</li>
            <li>More customizable auto-lock</li>
            <li>More flexible export options
                <ul>
                    <li>Share mechanism</li>
                    <li>Offer to encrypt even if this feature is disabled in the app</li>
                    <li>Export to a Google Authenticator URI file</li>
                </ul>
            </li>
            <li>Perform exports/backups on a background thread (automatic backups now work with Nextcloud)</li>
            <li>Color improvements to the dark theme (slightly darker)</li>
            <li>Offer more locations to select an image/icon from</li>
            <li>Display some helpful information when importing from a different app</li>
            <li>Minimum tap to reveal timeout changed to 1 second</li>
            <li>After an entry is added, scroll to it and highlight it</li>
            <li>Updated translations, and new translations for: Basque, Chinese Traditional, Hindi, Indonesian, Japanese, Persian, Romanian, Slovak</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Scanning large images for QR codes would fail</li>
            <li>The FAB would remain hidden under certain circumstances</li>
            <li>The app would crash if an entry was added to the vault twice due to an IO error</li>
            <li>The app would crash if the device was rotated while a progress dialog was shown</li>
            <li>The PIN keyboard would show even if a new non-digit password was set</li>
            <li>The password reminder popup would be occluded by the autofill popup</li>
            <li>Importing from other apps on Android 11 was broken due to some permission issues</li>
        </ul>
        <h3>Version 1.3</h3>
        <h4>New</h4>
        <ul>
            <li>Completely rewritten intro/onboarding</li>
            <li>Option to show a PIN keyboard when unlocking Aegis</li>
            <li>A password strength meter when setting up encryption (based on zxcvbn)</li>
            <li>RTL support</li>
            <li>Arabic and Portuguese translations</li>
            <li>Updates to existing translations</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Better lifecycle handling of the biometric authentication prompt</li>
            <li>The filename of exported vaults had a double .json extension</li>
            <li>The navigation bar color was incorrect on devices pre API 27</li>
            <li>QR code scanner performance and stability improvements</li>
            <li>Various other small usability and stability improvements</li>
        </ul>
        <h3>Version 1.2.1</h3>
        <h4>Fixes</h4>
        <ul>
            <li>Fix a rare issue where the intro could end up in a bad state</li>
        </ul>
        <h3>Version 1.2</h3>
        <h4>New</h4>
        <ul>
            <li>Add navigation bar color to themes</li>
            <li>Add support for importing from TOTP Authenticator</li>
            <li>Add support for importing from Microsoft Authenticator</li>
            <li>Add support for importing from Authenticator Plus</li>
            <li>Add support for importing a plain text Google Authenticator URI file</li>
            <li>Add support for importing from the new Google Authenticator export QR codes</li>
            <li>Add support for otpauth://steam URI's</li>
            <li>Add an option to copy tokens on tap (and disable it by default)</li>
            <li>Improve method to notify users on copy</li>
            <li>Add support for backups</li>
            <li>Improve multiselect flow</li>
            <li>Automatically adapt to system theme</li>
            <li>Add setting to change from 3 digit group size to 2 digit group size</li>
            <li>Use most frequent period to show progress</li>
            <li>Append a timestamp to the filename of exported vaults</li>
            <li>Add Hungarian translation</li>
            <li>Add Turkish translation</li>
            <li>Display a warning if automatic time sync is not enabled</li>
            <li>Minor card entry layout overhaul</li>
            <li>Ability to transfer tokens with qr codes</li>
            <li>Lockscreen overhaul</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Improve overall exception handling and error feedback to the user</li>
            <li>Improve icon editing flow</li>
            <li>Protect writes of the vault file against corruption with AtomicFile</li>
            <li>Make the parsing logic of the QR code URI more robust</li>
            <li>Importing from Authy now asks for password if needed</li>
            <li>Update Russian localization</li>
            <li>Increase password reminder period to 30 days</li>
            <li>Fix importing andOTP backups with more than 10000 PBKDF iterations</li>
            <li>Respect the global animator duration scale setting</li>
        </ul>
        <p>Various other minor improvements</p>
        <h3>Version 1.1.4</h3>
        <h4>Fixes</h4>
        <ul>
            <li>The export filename was missing the ".json" extension in some cases</li>
        </ul>
        <h3>Version 1.1.3</h3>
        <h4>New</h4>
        <ul>
            <li>Password reminder for users who use biometric unlock</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Tokens would not refresh in some rare cases</li>
        </ul>
        <h3>Version 1.1.2</h3>
        <h4>New</h4>
        <ul>
            <li>Ability to select multiple entries</li>
            <li>Ability to select a file location when exporting the vault (including cloud providers like Google Drive)</li>
            <li>Explanation and warning for the security options</li>
            <li>Removed external storage permissions</li>
        </ul>
        <h3>Version 1.1.1</h3>
        <h4>Fixes</h4>
        <ul>
            <li>Exporting the vault did not work on Android 10</li>
        </ul>
        <h3>Version 1.1</h3>
        <h4>New</h4>
        <ul>
            <li>Support for other types of biometric authentication (i.e. Pixel 4 face unlock)</li>
            <li>Support for importing from WinAuth</li>
            <li>Support for Chromebooks</li>
            <li>Option to highlight entries when tapped</li>
            <li>Filter for ungrouped tokens</li>
            <li>Ability to search for token account names</li>
            <li>Simplified Chinese translation (thanks RunningMelos!)</li>
            <li>Updated translations (thanks to all Crowdin contributers!)</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>The behavior of highlighting and revealing entries was inconsistent</li>
            <li>The changelog dialog didn't work</li>
            <li>The persistent notification was shown even after the app was killed</li>
        </ul>
        <h3>Version 1.0.3</h3>
        <h4>New</h4>
        <ul>
            <li>Support for andOTP's new backup file format</li>
        </ul>
        <h3>Version 1.0.2</h3>
        <h4>Fixes</h4>
        <ul>
            <li>Search feature on Huawei devices</li>
        </ul>
        <h4>Notes</h4>
        <ul>
            <li>Disabled automatic backups through the Google Play Store</li>
        </ul>
        <h3>Version 1.0.1</h3>
        <h4>Notes</h4>
        <ul>
            <li>Temporarily disabled search feature on Huawei devices</li>
        </ul>
        <h3>Version 1.0</h3>
        <h4>New</h4>
        <ul>
            <li>New icon</li>
            <li>Overhaul of interaction with the entry list</li>
            <li>Persistent notification while the vault is unlocked</li>
            <li>Language override option</li>
            <li>Support for importing from FreeOTP+</li>
            <li>Ability to toggle password visibility during unlock</li>
            <li>Support for deeplinking otpauth URIs</li>
        </ul>
        <h4>Fixes</h4>
        <ul>
            <li>Bad overall performance and high battery usage</li>
            <li>Codes with an uneven number of digits are displayed incorrectly</li>
            <li>Crash when entering a large value for OTP period</li>
        </ul>
    </body>
</html>

================================================
FILE: app/src/main/assets/license.html
================================================
<html>
    <head>
        <style type="text/css">
            body {
                background-color: %2$s;
                color: %3$s;
                font-size: 0.8em;
            }
        </style>
    </head>
    <body>
        <pre>%1$s</pre>
    </body>
</html>


================================================
FILE: app/src/main/java/com/amulyakhare/textdrawable/LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2014 Amulya Khare

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: app/src/main/java/com/amulyakhare/textdrawable/TextDrawable.java
================================================
package com.amulyakhare.textdrawable;

import android.graphics.*;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.graphics.drawable.shapes.RectShape;
import android.graphics.drawable.shapes.RoundRectShape;

/**
 * @author amulya
 * @datetime 14 Oct 2014, 3:53 PM
 */
public class TextDrawable extends ShapeDrawable {

    private final Paint textPaint;
    private final Paint borderPaint;
    private static final float SHADE_FACTOR = 0.9f;
    private final String text;
    private final int color;
    private final RectShape shape;
    private final int height;
    private final int width;
    private final int fontSize;
    private final float radius;
    private final int borderThickness;

    private TextDrawable(Builder builder) {
        super(builder.shape);

        // shape properties
        shape = builder.shape;
        height = builder.height;
        width = builder.width;
        radius = builder.radius;

        // text and color
        text = builder.toUpperCase ? builder.text.toUpperCase() : builder.text;
        color = builder.color;

        // text paint settings
        fontSize = builder.fontSize;
        textPaint = new Paint();
        textPaint.setColor(builder.textColor);
        textPaint.setAntiAlias(true);
        textPaint.setFakeBoldText(builder.isBold);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTypeface(builder.font);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setStrokeWidth(builder.borderThickness);

        // border paint settings
        borderThickness = builder.borderThickness;
        borderPaint = new Paint();
        borderPaint.setColor(getDarkerShade(color));
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(borderThickness);

        // drawable paint color
        Paint paint = getPaint();
        paint.setColor(color);

    }

    private int getDarkerShade(int color) {
        return Color.rgb((int)(SHADE_FACTOR * Color.red(color)),
                (int)(SHADE_FACTOR * Color.green(color)),
                (int)(SHADE_FACTOR * Color.blue(color)));
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        Rect r = getBounds();


        // draw border
        if (borderThickness > 0) {
            drawBorder(canvas);
        }

        int count = canvas.save();
        canvas.translate(r.left, r.top);

        // draw text
        int width = this.width < 0 ? r.width() : this.width;
        int height = this.height < 0 ? r.height() : this.height;
        int fontSize = this.fontSize < 0 ? (Math.min(width, height) / 2) : this.fontSize;
        textPaint.setTextSize(fontSize);
        canvas.drawText(text, width / 2, height / 2 - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);

        canvas.restoreToCount(count);

    }

    private void drawBorder(Canvas canvas) {
        RectF rect = new RectF(getBounds());
        rect.inset(borderThickness/2, borderThickness/2);

        if (shape instanceof OvalShape) {
            canvas.drawOval(rect, borderPaint);
        }
        else if (shape instanceof RoundRectShape) {
            canvas.drawRoundRect(rect, radius, radius, borderPaint);
        }
        else {
            canvas.drawRect(rect, borderPaint);
        }
    }

    @Override
    public void setAlpha(int alpha) {
        textPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        textPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public int getIntrinsicWidth() {
        return width;
    }

    @Override
    public int getIntrinsicHeight() {
        return height;
    }

    public static IShapeBuilder builder() {
        return new Builder();
    }

    public static class Builder implements IConfigBuilder, IShapeBuilder, IBuilder {

        private String text;

        private int color;

        private int borderThickness;

        private int width;

        private int height;

        private Typeface font;

        private RectShape shape;

        public int textColor;

        private int fontSize;

        private boolean isBold;

        private boolean toUpperCase;

        public float radius;

        private Builder() {
            text = "";
            color = Color.GRAY;
            textColor = Color.WHITE;
            borderThickness = 0;
            width = -1;
            height = -1;
            shape = new RectShape();
            font = Typeface.create("sans-serif-light", Typeface.NORMAL);
            fontSize = -1;
            isBold = false;
            toUpperCase = false;
        }

        public IConfigBuilder width(int width) {
            this.width = width;
            return this;
        }

        public IConfigBuilder height(int height) {
            this.height = height;
            return this;
        }

        public IConfigBuilder textColor(int color) {
            this.textColor = color;
            return this;
        }

        public IConfigBuilder withBorder(int thickness) {
            this.borderThickness = thickness;
            return this;
        }

        public IConfigBuilder useFont(Typeface font) {
            this.font = font;
            return this;
        }

        public IConfigBuilder fontSize(int size) {
            this.fontSize = size;
            return this;
        }

        public IConfigBuilder bold() {
            this.isBold = true;
            return this;
        }

        public IConfigBuilder toUpperCase() {
            this.toUpperCase = true;
            return this;
        }

        @Override
        public IConfigBuilder beginConfig() {
            return this;
        }

        @Override
        public IShapeBuilder endConfig() {
            return this;
        }

        @Override
        public IBuilder rect() {
            this.shape = new RectShape();
            return this;
        }

        @Override
        public IBuilder round() {
            this.shape = new OvalShape();
            return this;
        }

        @Override
        public IBuilder roundRect(int radius) {
            this.radius = radius;
            float[] radii = {radius, radius, radius, radius, radius, radius, radius, radius};
            this.shape = new RoundRectShape(radii, null, null);
            return this;
        }

        @Override
        public TextDrawable buildRect(String text, int color) {
            rect();
            return build(text, color);
        }

        @Override
        public TextDrawable buildRoundRect(String text, int color, int radius) {
            roundRect(radius);
            return build(text, color);
        }

        @Override
        public TextDrawable buildRound(String text, int color) {
            round();
            return build(text, color);
        }

        @Override
        public TextDrawable build(String text, int color) {
            this.color = color;
            this.text = text;
            return new TextDrawable(this);
        }
    }

    public interface IConfigBuilder {
        public IConfigBuilder width(int width);

        public IConfigBuilder height(int height);

        public IConfigBuilder textColor(int color);

        public IConfigBuilder withBorder(int thickness);

        public IConfigBuilder useFont(Typeface font);

        public IConfigBuilder fontSize(int size);

        public IConfigBuilder bold();

        public IConfigBuilder toUpperCase();

        public IShapeBuilder endConfig();
    }

    public static interface IBuilder {

        public TextDrawable build(String text, int color);
    }

    public static interface IShapeBuilder {

        public IConfigBuilder beginConfig();

        public IBuilder rect();

        public IBuilder round();

        public IBuilder roundRect(int radius);

        public TextDrawable buildRect(String text, int color);

        public TextDrawable buildRoundRect(String text, int color, int radius);

        public TextDrawable buildRound(String text, int color);
    }
}


================================================
FILE: app/src/main/java/com/amulyakhare/textdrawable/util/ColorGenerator.java
================================================
package com.amulyakhare.textdrawable.util;

import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * @author amulya
 * @datetime 14 Oct 2014, 5:20 PM
 */
public class ColorGenerator {

    public static ColorGenerator DEFAULT;

    public static ColorGenerator MATERIAL;

    static {
        DEFAULT = create(Arrays.asList(
                0xfff16364,
                0xfff58559,
                0xfff9a43e,
                0xffe4c62e,
                0xff67bf74,
                0xff59a2be,
                0xff2093cd,
                0xffad62a7,
                0xff805781
        ));
        MATERIAL = create(Arrays.asList(
                0xffe57373,
                0xfff06292,
                0xffba68c8,
                0xff9575cd,
                0xff7986cb,
                0xff64b5f6,
                0xff4fc3f7,
                0xff4dd0e1,
                0xff4db6ac,
                0xff81c784,
                0xffaed581,
                0xffff8a65,
                0xffd4e157,
                0xffffd54f,
                0xffffb74d,
                0xffa1887f,
                0xff90a4ae
        ));
    }

    private final List<Integer> mColors;
    private final Random mRandom;

    public static ColorGenerator create(List<Integer> colorList) {
        return new ColorGenerator(colorList);
    }

    private ColorGenerator(List<Integer> colorList) {
        mColors = colorList;
        mRandom = new Random(System.currentTimeMillis());
    }

    public int getRandomColor() {
        return mColors.get(mRandom.nextInt(mColors.size()));
    }

    public int getColor(Object key) {
        return mColors.get(Math.abs(key.hashCode()) % mColors.size());
    }
}

================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/AccountNamePosition.java
================================================
package com.beemdevelopment.aegis;

public enum AccountNamePosition {
    HIDDEN,
    END,
    BELOW;

    private static AccountNamePosition[] _values;

    static {
        _values = values();
    }

    public static AccountNamePosition fromInteger(int x) {
        return _values[x];
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java
================================================
package com.beemdevelopment.aegis;

import dagger.hilt.android.HiltAndroidApp;

@HiltAndroidApp
public class AegisApplication extends AegisApplicationBase {

}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/AegisApplicationBase.java
================================================
package com.beemdevelopment.aegis;

import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.drawable.Icon;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;

import com.beemdevelopment.aegis.receivers.VaultLockReceiver;
import com.beemdevelopment.aegis.ui.MainActivity;
import com.beemdevelopment.aegis.util.IOUtils;
import com.beemdevelopment.aegis.vault.VaultManager;
import com.topjohnwu.superuser.Shell;

import java.util.Collections;

import dagger.hilt.InstallIn;
import dagger.hilt.android.EarlyEntryPoint;
import dagger.hilt.android.EarlyEntryPoints;
import dagger.hilt.components.SingletonComponent;

public abstract class AegisApplicationBase extends Application {
    private static final String CODE_LOCK_STATUS_ID = "lock_status_channel";

    private VaultManager _vaultManager;

    static {
        // Enable verbose libsu logging in debug builds
        Shell.enableVerboseLogging = BuildConfig.DEBUG;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        _vaultManager = EarlyEntryPoints.get(this, EntryPoint.class).getVaultManager();

        VaultLockReceiver lockReceiver = new VaultLockReceiver();
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
        ContextCompat.registerReceiver(this, lockReceiver, intentFilter, ContextCompat.RECEIVER_NOT_EXPORTED);

        // lock the app if the user moves the application to the background
        ProcessLifecycleOwner.get().getLifecycle().addObserver(new AppLifecycleObserver());

        // clear the cache directory on startup, to make sure no temporary vault export files remain
        IOUtils.clearDirectory(getCacheDir(), false);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            initAppShortcuts();
        }

        // NOTE: Disabled for now. See issue: #1047
        /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            initNotificationChannels();
        }*/
    }

    @RequiresApi(api = Build.VERSION_CODES.N_MR1)
    private void initAppShortcuts() {
        ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
        if (shortcutManager == null) {
            return;
        }

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("action", "scan");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.setAction(Intent.ACTION_MAIN);

        ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "shortcut_new")
                .setShortLabel(getString(R.string.new_entry))
                .setLongLabel(getString(R.string.add_new_entry))
                .setIcon(Icon.createWithResource(this, R.drawable.ic_qr_code))
                .setIntent(intent)
                .build();

        shortcutManager.setDynamicShortcuts(Collections.singletonList(shortcut));
    }

    private void initNotificationChannels() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.channel_name_lock_status);
            String description = getString(R.string.channel_description_lock_status);
            int importance = NotificationManager.IMPORTANCE_LOW;

            NotificationChannel channel = new NotificationChannel(CODE_LOCK_STATUS_ID, name, importance);
            channel.setDescription(description);

            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

    private class AppLifecycleObserver implements LifecycleEventObserver {
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            if (event == Lifecycle.Event.ON_STOP
                    && _vaultManager.isAutoLockEnabled(Preferences.AUTO_LOCK_ON_MINIMIZE)
                    && !_vaultManager.isAutoLockBlocked()) {
                _vaultManager.lock(false);
            }
        }
    }

    @EarlyEntryPoint
    @InstallIn(SingletonComponent.class)
    interface EntryPoint {
        VaultManager getVaultManager();
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/AegisBackupAgent.java
================================================
package com.beemdevelopment.aegis;

import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.FullBackupDataOutput;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.util.Log;

import com.beemdevelopment.aegis.database.AppDatabase;
import com.beemdevelopment.aegis.database.AuditLogRepository;
import com.beemdevelopment.aegis.util.IOUtils;
import com.beemdevelopment.aegis.vault.VaultFile;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.VaultRepositoryException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class AegisBackupAgent extends BackupAgent {
    private static final String TAG = AegisBackupAgent.class.getSimpleName();

    private Preferences _prefs;

    private AuditLogRepository _auditLogRepository;

    @Override
    public void onCreate() {
        super.onCreate();

        // Cannot use injection with Dagger Hilt here, because the app is launched in a restricted mode on restore
        _prefs = new Preferences(this);
        AppDatabase appDatabase = AegisModule.provideAppDatabase(this);
        _auditLogRepository = AegisModule.provideAuditLogRepository(appDatabase);
    }

    @Override
    public synchronized void onFullBackup(FullBackupDataOutput data) throws IOException {
        Log.i(TAG, String.format("onFullBackup() called: flags=%d, quota=%d",
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? data.getTransportFlags() : -1,
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? data.getQuota() : -1));

        boolean isD2D = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
                && (data.getTransportFlags() & FLAG_DEVICE_TO_DEVICE_TRANSFER) == FLAG_DEVICE_TO_DEVICE_TRANSFER;

        if (isD2D) {
            Log.i(TAG, "onFullBackup(): allowing D2D transfer");
        } else if (!_prefs.isAndroidBackupsEnabled()) {
            Log.i(TAG, "onFullBackup() skipped: Android backups disabled in preferences");
            return;
        }

        // We perform a catch of any Exception here to make sure we also
        // report any runtime exceptions, in addition to the expected IOExceptions.
        try {
            fullBackup(data);
            _auditLogRepository.addAndroidBackupCreatedEvent();
            _prefs.setAndroidBackupResult(new Preferences.BackupResult(null));
        } catch (Exception e) {
            Log.e(TAG, String.format("onFullBackup() failed: %s", e));
            _prefs.setAndroidBackupResult(new Preferences.BackupResult(e));
            throw e;
        }

        Log.i(TAG, "onFullBackup() finished");
    }

    private void fullBackup(FullBackupDataOutput data) throws IOException {
        // First copy the vault to the files/backup directory
        createBackupDir();
        File vaultBackupFile = getVaultBackupFile();
        try (OutputStream outputStream = new FileOutputStream(vaultBackupFile)) {
            VaultFile vaultFile = VaultRepository.readVaultFile(this);
            byte[] bytes = vaultFile.exportable().toBytes();
            outputStream.write(bytes);
        } catch (VaultRepositoryException | IOException e) {
            deleteBackupDir();
            throw new IOException(e);
        }

        // Then call the original implementation so that fullBackupContent specified in AndroidManifest is read
        try {
            super.onFullBackup(data);
        } finally {
            deleteBackupDir();
        }
    }

    @Override
    public synchronized void onRestoreFile(ParcelFileDescriptor data, long size, File destination, int type, long mode, long mtime) throws IOException {
        Log.i(TAG, String.format("onRestoreFile() called: dest=%s", destination));
        super.onRestoreFile(data, size, destination, type, mode, mtime);

        File vaultBackupFile = getVaultBackupFile();
        if (destination.getCanonicalFile().equals(vaultBackupFile.getCanonicalFile())) {
            try (InputStream inStream = new FileInputStream(vaultBackupFile)) {
                VaultRepository.writeToFile(this, inStream);
            } catch (IOException e) {
                Log.e(TAG, String.format("onRestoreFile() failed: dest=%s, error=%s", destination, e));
                throw e;
            } finally {
                deleteBackupDir();
            }
        }

        Log.i(TAG, String.format("onRestoreFile() finished: dest=%s", destination));
    }

    @Override
    public synchronized void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
        super.onQuotaExceeded(backupDataBytes, quotaBytes);
        Log.e(TAG, String.format("onQuotaExceeded() called: backupDataBytes=%d, quotaBytes=%d", backupDataBytes, quotaBytes));
    }

    @Override
    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException {

    }

    @Override
    public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException {

    }

    private void createBackupDir() throws IOException {
        File dir = getVaultBackupFile().getParentFile();
        if (dir == null || (!dir.exists() && !dir.mkdir())) {
            throw new IOException(String.format("Unable to create backup directory: %s", dir));
        }
    }

    private void deleteBackupDir() {
        File dir = getVaultBackupFile().getParentFile();
        if (dir != null) {
            IOUtils.clearDirectory(dir, true);
        }
    }

    private File getVaultBackupFile() {
        return new File(new File(getFilesDir(), "backup"), VaultRepository.FILENAME);
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/AegisModule.java
================================================
package com.beemdevelopment.aegis;

import android.content.Context;

import androidx.room.Room;

import com.beemdevelopment.aegis.database.AppDatabase;
import com.beemdevelopment.aegis.database.AuditLogDao;
import com.beemdevelopment.aegis.database.AuditLogRepository;
import com.beemdevelopment.aegis.icons.IconPackManager;
import com.beemdevelopment.aegis.vault.VaultManager;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.android.qualifiers.ApplicationContext;
import dagger.hilt.components.SingletonComponent;

@Module
@InstallIn(SingletonComponent.class)
public class AegisModule {
    @Provides
    @Singleton
    public static IconPackManager provideIconPackManager(@ApplicationContext Context context) {
        return new IconPackManager(context);
    }

    @Provides
    @Singleton
    public static AuditLogRepository provideAuditLogRepository(AppDatabase appDatabase) {
        AuditLogDao auditLogDao = appDatabase.auditLogDao();
        return new AuditLogRepository(auditLogDao);
    }

    @Provides
    @Singleton
    public static VaultManager provideVaultManager(@ApplicationContext Context context, AuditLogRepository auditLogRepository) {
        return new VaultManager(context, auditLogRepository);
    }

    @Provides
    public static Preferences providePreferences(@ApplicationContext Context context) {
        return new Preferences(context);
    }

    @Provides
    @Singleton
    public static AppDatabase provideAppDatabase(@ApplicationContext Context context) {
        return Room.databaseBuilder(context.getApplicationContext(),
                        AppDatabase.class, "aegis-db")
                .build();
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/BackupsVersioningStrategy.java
================================================
package com.beemdevelopment.aegis;

public enum BackupsVersioningStrategy {
    UNDEFINED,
    MULTIPLE_BACKUPS,
    SINGLE_BACKUP
}

================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/CopyBehavior.java
================================================
package com.beemdevelopment.aegis;

public enum CopyBehavior {
    NEVER,
    SINGLETAP,
    DOUBLETAP;

    private static CopyBehavior[] _values;

    static {
        _values = values();
    }

    public static CopyBehavior fromInteger(int x) {
        return _values[x];
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/EventType.java
================================================
package com.beemdevelopment.aegis;

public enum EventType {

    VAULT_UNLOCKED,
    VAULT_BACKUP_CREATED,
    VAULT_ANDROID_BACKUP_CREATED,
    VAULT_EXPORTED,
    ENTRY_SHARED,
    VAULT_UNLOCK_FAILED_PASSWORD,
    VAULT_UNLOCK_FAILED_BIOMETRICS;
    private static EventType[] _values;

    static {
        _values = values();
    }

    public static EventType fromInteger(int x) {
        return _values[x];
    }

    public static int getEventTitleRes(EventType eventType) {
        switch (eventType) {
            case VAULT_UNLOCKED:
                return R.string.event_title_vault_unlocked;
            case VAULT_BACKUP_CREATED:
                return R.string.event_title_backup_created;
            case VAULT_ANDROID_BACKUP_CREATED:
                return R.string.event_title_android_backup_created;
            case VAULT_EXPORTED:
                return R.string.event_title_vault_exported;
            case ENTRY_SHARED:
                return R.string.event_title_entry_shared;
            case VAULT_UNLOCK_FAILED_PASSWORD:
                return R.string.event_title_vault_unlock_failed_password;
            case VAULT_UNLOCK_FAILED_BIOMETRICS:
                return R.string.event_title_vault_unlock_failed_biometrics;
            default:
                return R.string.event_unknown;
        }
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/GroupPlaceholderType.java
================================================
package com.beemdevelopment.aegis;

public enum GroupPlaceholderType {
    ALL,
    NEW_GROUP,
    NO_GROUP;

    public int getStringRes() {
        switch (this) {
            case ALL:
                return R.string.all;
            case NEW_GROUP:
                return R.string.new_group;
            case NO_GROUP:
                return R.string.no_group;
            default:
                throw new IllegalArgumentException("Unexpected placeholder type: " + this);
        }
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/PassReminderFreq.java
================================================
package com.beemdevelopment.aegis;

import androidx.annotation.StringRes;

import java.util.concurrent.TimeUnit;

public enum PassReminderFreq {
    NEVER,
    WEEKLY,
    BIWEEKLY,
    MONTHLY,
    QUARTERLY;

    public long getDurationMillis() {
        long weeks;
        switch (this) {
            case WEEKLY:
                weeks = 1;
                break;
            case BIWEEKLY:
                weeks = 2;
                break;
            case MONTHLY:
                weeks = 4;
                break;
            case QUARTERLY:
                weeks = 13;
                break;
            default:
                weeks = 0;
                break;
        }

        return TimeUnit.MILLISECONDS.convert(weeks * 7L, TimeUnit.DAYS);
    }

    @StringRes
    public int getStringRes() {
        switch (this) {
            case WEEKLY:
                return R.string.password_reminder_freq_weekly;
            case BIWEEKLY:
                return R.string.password_reminder_freq_biweekly;
            case MONTHLY:
                return R.string.password_reminder_freq_monthly;
            case QUARTERLY:
                return R.string.password_reminder_freq_quarterly;
            default:
                return R.string.password_reminder_freq_never;
        }
    }

    public static PassReminderFreq fromInteger(int i) {
        return PassReminderFreq.values()[i];
    }
}


================================================
FILE: app/src/main/java/com/beemdevelopment/aegis/Preferences.java
================================================
package com.beemdevelopment.aegis;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.provider.Documen
Download .txt
gitextract_rgq5wf8x/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   └── feature.md
│   └── workflows/
│       ├── build-app-workflow.yaml
│       ├── codeql-analysis.yml
│       └── crowdin.yml
├── .gitignore
├── CONTRIBUTING.md
├── FAQ.md
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── config/
│   │   ├── libraries/
│   │   │   ├── krop.json
│   │   │   ├── libsu.json
│   │   │   ├── textdrawable.json
│   │   │   └── trustedintents.json
│   │   └── licenses/
│   │       └── 3ca920d1875f7ad7ab04a2a331958577.json
│   ├── lint.xml
│   ├── proguard-rules.pro
│   ├── schemas/
│   │   └── com.beemdevelopment.aegis.database.AppDatabase/
│   │       └── 1.json
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── beemdevelopment/
│       │               └── aegis/
│       │                   ├── AegisTest.java
│       │                   ├── AegisTestApplication.java
│       │                   ├── AegisTestRunner.java
│       │                   ├── BackupExportTest.java
│       │                   ├── DeepLinkTest.java
│       │                   ├── EmptySecretTest.java
│       │                   ├── IntroTest.java
│       │                   ├── OverallTest.java
│       │                   ├── PanicTriggerTest.java
│       │                   ├── rules/
│       │                   │   └── ScreenshotTestRule.java
│       │                   └── vault/
│       │                       └── VaultRepositoryTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── assets/
│       │   │   ├── changelog.html
│       │   │   └── license.html
│       │   ├── java/
│       │   │   ├── com/
│       │   │   │   ├── amulyakhare/
│       │   │   │   │   └── textdrawable/
│       │   │   │   │       ├── LICENSE
│       │   │   │   │       ├── TextDrawable.java
│       │   │   │   │       └── util/
│       │   │   │   │           └── ColorGenerator.java
│       │   │   │   └── beemdevelopment/
│       │   │   │       └── aegis/
│       │   │   │           ├── AccountNamePosition.java
│       │   │   │           ├── AegisApplication.java
│       │   │   │           ├── AegisApplicationBase.java
│       │   │   │           ├── AegisBackupAgent.java
│       │   │   │           ├── AegisModule.java
│       │   │   │           ├── BackupsVersioningStrategy.java
│       │   │   │           ├── CopyBehavior.java
│       │   │   │           ├── EventType.java
│       │   │   │           ├── GroupPlaceholderType.java
│       │   │   │           ├── PassReminderFreq.java
│       │   │   │           ├── Preferences.java
│       │   │   │           ├── SortCategory.java
│       │   │   │           ├── Theme.java
│       │   │   │           ├── ThemeMap.java
│       │   │   │           ├── VibrationPatterns.java
│       │   │   │           ├── ViewMode.java
│       │   │   │           ├── crypto/
│       │   │   │           │   ├── CryptParameters.java
│       │   │   │           │   ├── CryptResult.java
│       │   │   │           │   ├── CryptoUtils.java
│       │   │   │           │   ├── KeyStoreHandle.java
│       │   │   │           │   ├── KeyStoreHandleException.java
│       │   │   │           │   ├── MasterKey.java
│       │   │   │           │   ├── MasterKeyException.java
│       │   │   │           │   ├── SCryptParameters.java
│       │   │   │           │   ├── bc/
│       │   │   │           │   │   ├── SCrypt.java
│       │   │   │           │   │   └── Salsa20Engine.java
│       │   │   │           │   ├── otp/
│       │   │   │           │   │   ├── HOTP.java
│       │   │   │           │   │   ├── MOTP.java
│       │   │   │           │   │   ├── OTP.java
│       │   │   │           │   │   ├── TOTP.java
│       │   │   │           │   │   └── YAOTP.java
│       │   │   │           │   └── pins/
│       │   │   │           │       └── GuardianProjectFDroidRSA2048.java
│       │   │   │           ├── database/
│       │   │   │           │   ├── AppDatabase.java
│       │   │   │           │   ├── AuditLogDao.java
│       │   │   │           │   ├── AuditLogEntry.java
│       │   │   │           │   └── AuditLogRepository.java
│       │   │   │           ├── encoding/
│       │   │   │           │   ├── Base32.java
│       │   │   │           │   ├── Base64.java
│       │   │   │           │   ├── EncodingException.java
│       │   │   │           │   └── Hex.java
│       │   │   │           ├── helpers/
│       │   │   │           │   ├── AnimationsHelper.java
│       │   │   │           │   ├── BiometricSlotInitializer.java
│       │   │   │           │   ├── BiometricsHelper.java
│       │   │   │           │   ├── BitmapHelper.java
│       │   │   │           │   ├── CenterVerticalSpan.java
│       │   │   │           │   ├── ContextHelper.java
│       │   │   │           │   ├── DropdownHelper.java
│       │   │   │           │   ├── EditTextHelper.java
│       │   │   │           │   ├── FabMenuHelper.java
│       │   │   │           │   ├── FabScrollHelper.java
│       │   │   │           │   ├── ItemTouchHelperAdapter.java
│       │   │   │           │   ├── MetricsHelper.java
│       │   │   │           │   ├── PasswordStrengthHelper.java
│       │   │   │           │   ├── PermissionHelper.java
│       │   │   │           │   ├── QrCodeAnalyzer.java
│       │   │   │           │   ├── QrCodeHelper.java
│       │   │   │           │   ├── SafHelper.java
│       │   │   │           │   ├── SimpleAnimationEndListener.java
│       │   │   │           │   ├── SimpleItemTouchHelperCallback.java
│       │   │   │           │   ├── SimpleTextWatcher.java
│       │   │   │           │   ├── TextDrawableHelper.java
│       │   │   │           │   ├── ThemeHelper.java
│       │   │   │           │   ├── UiRefresher.java
│       │   │   │           │   ├── UiThreadExecutor.java
│       │   │   │           │   ├── VibrationHelper.java
│       │   │   │           │   ├── ViewHelper.java
│       │   │   │           │   └── comparators/
│       │   │   │           │       ├── AccountNameComparator.java
│       │   │   │           │       ├── FavoriteComparator.java
│       │   │   │           │       ├── IssuerNameComparator.java
│       │   │   │           │       ├── LastUsedComparator.java
│       │   │   │           │       └── UsageCountComparator.java
│       │   │   │           ├── icons/
│       │   │   │           │   ├── IconPack.java
│       │   │   │           │   ├── IconPackException.java
│       │   │   │           │   ├── IconPackExistsException.java
│       │   │   │           │   ├── IconPackManager.java
│       │   │   │           │   └── IconType.java
│       │   │   │           ├── importers/
│       │   │   │           │   ├── AegisImporter.java
│       │   │   │           │   ├── AndOtpImporter.java
│       │   │   │           │   ├── AuthenticatorPlusImporter.java
│       │   │   │           │   ├── AuthyImporter.java
│       │   │   │           │   ├── BattleNetImporter.java
│       │   │   │           │   ├── BitwardenImporter.java
│       │   │   │           │   ├── DatabaseImporter.java
│       │   │   │           │   ├── DatabaseImporterEntryException.java
│       │   │   │           │   ├── DatabaseImporterException.java
│       │   │   │           │   ├── DuoImporter.java
│       │   │   │           │   ├── EnteAuthImporter.java
│       │   │   │           │   ├── FreeOtpImporter.java
│       │   │   │           │   ├── FreeOtpPlusImporter.java
│       │   │   │           │   ├── GoogleAuthImporter.java
│       │   │   │           │   ├── GoogleAuthUriImporter.java
│       │   │   │           │   ├── MicrosoftAuthImporter.java
│       │   │   │           │   ├── ProtonAuthenticatorImporter.java
│       │   │   │           │   ├── SqlImporterHelper.java
│       │   │   │           │   ├── SteamImporter.java
│       │   │   │           │   ├── StratumImporter.java
│       │   │   │           │   ├── TotpAuthenticatorImporter.java
│       │   │   │           │   ├── TwoFASImporter.java
│       │   │   │           │   └── WinAuthImporter.java
│       │   │   │           ├── otp/
│       │   │   │           │   ├── GoogleAuthInfo.java
│       │   │   │           │   ├── GoogleAuthInfoException.java
│       │   │   │           │   ├── HotpInfo.java
│       │   │   │           │   ├── MotpInfo.java
│       │   │   │           │   ├── OtpInfo.java
│       │   │   │           │   ├── OtpInfoException.java
│       │   │   │           │   ├── SteamInfo.java
│       │   │   │           │   ├── TotpInfo.java
│       │   │   │           │   ├── Transferable.java
│       │   │   │           │   └── YandexInfo.java
│       │   │   │           ├── receivers/
│       │   │   │           │   ├── QsTileRefreshReceiver.java
│       │   │   │           │   └── VaultLockReceiver.java
│       │   │   │           ├── services/
│       │   │   │           │   ├── LaunchAppTileService.java
│       │   │   │           │   ├── LaunchScannerTileService.java
│       │   │   │           │   └── NotificationService.java
│       │   │   │           ├── ui/
│       │   │   │           │   ├── AboutActivity.java
│       │   │   │           │   ├── AegisActivity.java
│       │   │   │           │   ├── AssignIconsActivity.java
│       │   │   │           │   ├── AuthActivity.java
│       │   │   │           │   ├── EditEntryActivity.java
│       │   │   │           │   ├── ExitActivity.java
│       │   │   │           │   ├── GroupManagerActivity.java
│       │   │   │           │   ├── ImportEntriesActivity.java
│       │   │   │           │   ├── IntroActivity.java
│       │   │   │           │   ├── LicensesActivity.java
│       │   │   │           │   ├── MainActivity.java
│       │   │   │           │   ├── PanicResponderActivity.java
│       │   │   │           │   ├── PreferencesActivity.java
│       │   │   │           │   ├── ScannerActivity.java
│       │   │   │           │   ├── TransferEntriesActivity.java
│       │   │   │           │   ├── components/
│       │   │   │           │   │   ├── DropdownCheckBoxes.java
│       │   │   │           │   │   └── NoAutofillEditText.java
│       │   │   │           │   ├── dialogs/
│       │   │   │           │   │   ├── ChangelogDialog.java
│       │   │   │           │   │   ├── Dialogs.java
│       │   │   │           │   │   ├── IconPickerDialog.java
│       │   │   │           │   │   ├── LicenseDialog.java
│       │   │   │           │   │   └── SimpleWebViewDialog.java
│       │   │   │           │   ├── fragments/
│       │   │   │           │   │   └── preferences/
│       │   │   │           │   │       ├── AppearancePreferencesFragment.java
│       │   │   │           │   │       ├── AuditLogPreferencesFragment.java
│       │   │   │           │   │       ├── BackupsPreferencesFragment.java
│       │   │   │           │   │       ├── BehaviorPreferencesFragment.java
│       │   │   │           │   │       ├── IconPacksManagerFragment.java
│       │   │   │           │   │       ├── ImportExportPreferencesFragment.java
│       │   │   │           │   │       ├── MainPreferencesFragment.java
│       │   │   │           │   │       ├── PreferencesFragment.java
│       │   │   │           │   │       └── SecurityPreferencesFragment.java
│       │   │   │           │   ├── glide/
│       │   │   │           │   │   ├── AegisGlideModule.java
│       │   │   │           │   │   ├── GlideHelper.java
│       │   │   │           │   │   ├── SvgBytesDecoder.java
│       │   │   │           │   │   ├── SvgDecoder.java
│       │   │   │           │   │   ├── SvgDrawableTranscoder.java
│       │   │   │           │   │   ├── VaultEntryIconKey.java
│       │   │   │           │   │   └── VaultEntryIconLoader.java
│       │   │   │           │   ├── intro/
│       │   │   │           │   │   ├── IntroActivityInterface.java
│       │   │   │           │   │   ├── IntroBaseActivity.java
│       │   │   │           │   │   ├── SlideFragment.java
│       │   │   │           │   │   └── SlideIndicator.java
│       │   │   │           │   ├── models/
│       │   │   │           │   │   ├── AssignIconEntry.java
│       │   │   │           │   │   ├── AuditLogEntryModel.java
│       │   │   │           │   │   ├── ErrorCardInfo.java
│       │   │   │           │   │   ├── ImportEntry.java
│       │   │   │           │   │   └── VaultGroupModel.java
│       │   │   │           │   ├── preferences/
│       │   │   │           │   │   └── SwitchPreference.java
│       │   │   │           │   ├── slides/
│       │   │   │           │   │   ├── DoneSlide.java
│       │   │   │           │   │   ├── SecurityPickerSlide.java
│       │   │   │           │   │   ├── SecuritySetupSlide.java
│       │   │   │           │   │   └── WelcomeSlide.java
│       │   │   │           │   ├── tasks/
│       │   │   │           │   │   ├── Argon2Task.java
│       │   │   │           │   │   ├── ExportTask.java
│       │   │   │           │   │   ├── IconOptimizationTask.java
│       │   │   │           │   │   ├── ImportFileTask.java
│       │   │   │           │   │   ├── ImportIconPackTask.java
│       │   │   │           │   │   ├── KeyDerivationTask.java
│       │   │   │           │   │   ├── PBKDFTask.java
│       │   │   │           │   │   ├── PasswordSlotDecryptTask.java
│       │   │   │           │   │   ├── ProgressDialogTask.java
│       │   │   │           │   │   ├── QrDecodeTask.java
│       │   │   │           │   │   └── RootShellTask.java
│       │   │   │           │   └── views/
│       │   │   │           │       ├── AssignIconAdapter.java
│       │   │   │           │       ├── AssignIconHolder.java
│       │   │   │           │       ├── AuditLogAdapter.java
│       │   │   │           │       ├── AuditLogHolder.java
│       │   │   │           │       ├── EntryAdapter.java
│       │   │   │           │       ├── EntryHolder.java
│       │   │   │           │       ├── EntryListView.java
│       │   │   │           │       ├── ErrorCardHolder.java
│       │   │   │           │       ├── GroupAdapter.java
│       │   │   │           │       ├── GroupHolder.java
│       │   │   │           │       ├── IconAdapter.java
│       │   │   │           │       ├── IconCategoryHolder.java
│       │   │   │           │       ├── IconHolder.java
│       │   │   │           │       ├── IconPackAdapter.java
│       │   │   │           │       ├── IconPackHolder.java
│       │   │   │           │       ├── IconRecyclerView.java
│       │   │   │           │       ├── ImportEntriesAdapter.java
│       │   │   │           │       ├── ImportEntryHolder.java
│       │   │   │           │       └── TotpProgressBar.java
│       │   │   │           ├── util/
│       │   │   │           │   ├── ClipboardUtils.java
│       │   │   │           │   ├── Cloner.java
│       │   │   │           │   ├── CollectionUtils.java
│       │   │   │           │   ├── IOUtils.java
│       │   │   │           │   ├── JsonUtils.java
│       │   │   │           │   ├── PreferenceParser.java
│       │   │   │           │   ├── TimeUtils.java
│       │   │   │           │   └── UUIDMap.java
│       │   │   │           └── vault/
│       │   │   │               ├── Vault.java
│       │   │   │               ├── VaultBackupManager.java
│       │   │   │               ├── VaultBackupPermissionException.java
│       │   │   │               ├── VaultEntry.java
│       │   │   │               ├── VaultEntryException.java
│       │   │   │               ├── VaultEntryIcon.java
│       │   │   │               ├── VaultEntryIconException.java
│       │   │   │               ├── VaultException.java
│       │   │   │               ├── VaultFile.java
│       │   │   │               ├── VaultFileCredentials.java
│       │   │   │               ├── VaultFileException.java
│       │   │   │               ├── VaultGroup.java
│       │   │   │               ├── VaultHtmlExporter.java
│       │   │   │               ├── VaultManager.java
│       │   │   │               ├── VaultRepository.java
│       │   │   │               ├── VaultRepositoryException.java
│       │   │   │               └── slots/
│       │   │   │                   ├── BiometricSlot.java
│       │   │   │                   ├── PasswordSlot.java
│       │   │   │                   ├── RawSlot.java
│       │   │   │                   ├── Slot.java
│       │   │   │                   ├── SlotException.java
│       │   │   │                   ├── SlotIntegrityException.java
│       │   │   │                   ├── SlotList.java
│       │   │   │                   └── SlotListException.java
│       │   │   └── info/
│       │   │       └── guardianproject/
│       │   │           ├── GuardianProjectRSA4096.java
│       │   │           └── trustedintents/
│       │   │               ├── ApkSignaturePin.java
│       │   │               ├── LICENSE.txt
│       │   │               └── TrustedIntents.java
│       │   ├── proto/
│       │   │   └── google_auth.proto
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── fade_in.xml
│       │       │   ├── fade_out.xml
│       │       │   ├── item_animation_fall_down.xml
│       │       │   ├── item_scale_in.xml
│       │       │   ├── item_scale_out.xml
│       │       │   ├── layout_animation_fall_down.xml
│       │       │   ├── slide_down_fade_in.xml
│       │       │   ├── slide_down_fade_out.xml
│       │       │   ├── slide_in_left.xml
│       │       │   ├── slide_in_right.xml
│       │       │   ├── slide_out_left.xml
│       │       │   └── slide_out_right.xml
│       │       ├── drawable/
│       │       │   ├── baseline_arrow_right_24.xml
│       │       │   ├── favorite_indicator.xml
│       │       │   ├── ic_aegis_notification.xml
│       │       │   ├── ic_aegis_quicksettings.xml
│       │       │   ├── ic_counter_black_24.xml
│       │       │   ├── ic_export_notes.xml
│       │       │   ├── ic_filled_star_24.xml
│       │       │   ├── ic_folder_zip.xml
│       │       │   ├── ic_lock.xml
│       │       │   ├── ic_lock_open.xml
│       │       │   ├── ic_outline_add_24.xml
│       │       │   ├── ic_outline_add_photo_alternate_24.xml
│       │       │   ├── ic_outline_android_24.xml
│       │       │   ├── ic_outline_arrow_left_alt_24.xml
│       │       │   ├── ic_outline_arrow_right_alt_24.xml
│       │       │   ├── ic_outline_brush_24.xml
│       │       │   ├── ic_outline_camera_front_24.xml
│       │       │   ├── ic_outline_camera_rear_24.xml
│       │       │   ├── ic_outline_check_24.xml
│       │       │   ├── ic_outline_close_24.xml
│       │       │   ├── ic_outline_cloud_upload_24.xml
│       │       │   ├── ic_outline_code_24.xml
│       │       │   ├── ic_outline_construction_24.xml
│       │       │   ├── ic_outline_content_copy_24.xml
│       │       │   ├── ic_outline_delete_24.xml
│       │       │   ├── ic_outline_description_24.xml
│       │       │   ├── ic_outline_done_all_24.xml
│       │       │   ├── ic_outline_edit_24.xml
│       │       │   ├── ic_outline_error_24.xml
│       │       │   ├── ic_outline_expand_more_24.xml
│       │       │   ├── ic_outline_fiber_pin_24.xml
│       │       │   ├── ic_outline_group_24.xml
│       │       │   ├── ic_outline_history_24.xml
│       │       │   ├── ic_outline_info_24.xml
│       │       │   ├── ic_outline_key_24.xml
│       │       │   ├── ic_outline_layers_24.xml
│       │       │   ├── ic_outline_lock_24.xml
│       │       │   ├── ic_outline_mail_24.xml
│       │       │   ├── ic_outline_menu_24.xml
│       │       │   ├── ic_outline_more_vert_24.xml
│       │       │   ├── ic_outline_notes_24.xml
│       │       │   ├── ic_outline_package_variant_24.xml
│       │       │   ├── ic_outline_person_24.xml
│       │       │   ├── ic_outline_public_24.xml
│       │       │   ├── ic_outline_qr_code_2_24.xml
│       │       │   ├── ic_outline_refresh_24.xml
│       │       │   ├── ic_outline_reset_image_24.xml
│       │       │   ├── ic_outline_sort_24.xml
│       │       │   ├── ic_outline_star_24.xml
│       │       │   ├── ic_outline_touch_app_24.xml
│       │       │   ├── ic_outline_warning_24.xml
│       │       │   ├── ic_qrcode_scan.xml
│       │       │   ├── ic_share.xml
│       │       │   ├── ic_tag_24.xml
│       │       │   ├── ic_timeline_24.xml
│       │       │   ├── ic_unselected.xml
│       │       │   ├── item_selected.xml
│       │       │   ├── progress_horizontal.xml
│       │       │   └── rounded_popup.xml
│       │       ├── layout/
│       │       │   ├── activity_about.xml
│       │       │   ├── activity_assign_icons.xml
│       │       │   ├── activity_auth.xml
│       │       │   ├── activity_edit_entry.xml
│       │       │   ├── activity_groups.xml
│       │       │   ├── activity_import_entries.xml
│       │       │   ├── activity_intro.xml
│       │       │   ├── activity_main.xml
│       │       │   ├── activity_preferences.xml
│       │       │   ├── activity_scanner.xml
│       │       │   ├── activity_share_entry.xml
│       │       │   ├── card_assign_icon_entry.xml
│       │       │   ├── card_audit_log.xml
│       │       │   ├── card_entry.xml
│       │       │   ├── card_entry_compact.xml
│       │       │   ├── card_entry_small.xml
│       │       │   ├── card_entry_tile.xml
│       │       │   ├── card_error.xml
│       │       │   ├── card_footer.xml
│       │       │   ├── card_group.xml
│       │       │   ├── card_icon.xml
│       │       │   ├── card_icon_category.xml
│       │       │   ├── card_icon_pack.xml
│       │       │   ├── card_import_entry.xml
│       │       │   ├── card_importer.xml
│       │       │   ├── chip_group_filter.xml
│       │       │   ├── content_about.xml
│       │       │   ├── dialog_add_entry.xml
│       │       │   ├── dialog_backups_versioning_strategy.xml
│       │       │   ├── dialog_checkbox.xml
│       │       │   ├── dialog_delete_entry.xml
│       │       │   ├── dialog_duplicate_entry.xml
│       │       │   ├── dialog_error.xml
│       │       │   ├── dialog_export.xml
│       │       │   ├── dialog_icon_picker.xml
│       │       │   ├── dialog_importers.xml
│       │       │   ├── dialog_number_picker.xml
│       │       │   ├── dialog_password.xml
│       │       │   ├── dialog_plaintext_warning.xml
│       │       │   ├── dialog_progress.xml
│       │       │   ├── dialog_select_group.xml
│       │       │   ├── dialog_select_groups.xml
│       │       │   ├── dialog_text_input.xml
│       │       │   ├── dialog_time_sync.xml
│       │       │   ├── dialog_web_view.xml
│       │       │   ├── dropdown_checkbox.xml
│       │       │   ├── dropdown_list_item.xml
│       │       │   ├── fab_menu.xml
│       │       │   ├── fragment_audit_log.xml
│       │       │   ├── fragment_done_slide.xml
│       │       │   ├── fragment_entry_list_view.xml
│       │       │   ├── fragment_icon_packs.xml
│       │       │   ├── fragment_security_picker_slide.xml
│       │       │   ├── fragment_security_setup_slide.xml
│       │       │   ├── fragment_welcome_slide.xml
│       │       │   ├── popup_password.xml
│       │       │   ├── scrim_layout.xml
│       │       │   └── view_preference_switch.xml
│       │       ├── menu/
│       │       │   ├── menu_action_mode.xml
│       │       │   ├── menu_assign_icons.xml
│       │       │   ├── menu_edit.xml
│       │       │   ├── menu_groups.xml
│       │       │   ├── menu_import_entries.xml
│       │       │   ├── menu_main.xml
│       │       │   └── menu_scanner.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   ├── ic_launcher_debug.xml
│       │       │   └── ic_launcher_debug_round.xml
│       │       ├── mipmap-anydpi-v33/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_debug.xml
│       │       ├── raw/
│       │       │   ├── aboutlibraries.json
│       │       │   └── keep.xml
│       │       ├── values/
│       │       │   ├── arrays.xml
│       │       │   ├── attrs.xml
│       │       │   ├── colors.xml
│       │       │   ├── dimens.xml
│       │       │   ├── strings.xml
│       │       │   └── themes.xml
│       │       ├── values-ar-rSA/
│       │       │   └── strings.xml
│       │       ├── values-ar-rSA-v29/
│       │       │   └── strings.xml
│       │       ├── values-ast-rES/
│       │       │   └── strings.xml
│       │       ├── values-ast-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-bg-rBG/
│       │       │   └── strings.xml
│       │       ├── values-bg-rBG-v29/
│       │       │   └── strings.xml
│       │       ├── values-ca-rES/
│       │       │   └── strings.xml
│       │       ├── values-ca-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-cs-rCZ/
│       │       │   └── strings.xml
│       │       ├── values-cs-rCZ-v29/
│       │       │   └── strings.xml
│       │       ├── values-da-rDK/
│       │       │   └── strings.xml
│       │       ├── values-da-rDK-v29/
│       │       │   └── strings.xml
│       │       ├── values-de-rDE/
│       │       │   └── strings.xml
│       │       ├── values-de-rDE-v29/
│       │       │   └── strings.xml
│       │       ├── values-el-rGR/
│       │       │   └── strings.xml
│       │       ├── values-el-rGR-v29/
│       │       │   └── strings.xml
│       │       ├── values-es-rES/
│       │       │   └── strings.xml
│       │       ├── values-es-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-et-rEE/
│       │       │   └── strings.xml
│       │       ├── values-et-rEE-v29/
│       │       │   └── strings.xml
│       │       ├── values-eu-rES/
│       │       │   └── strings.xml
│       │       ├── values-eu-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-fa-rIR/
│       │       │   └── strings.xml
│       │       ├── values-fa-rIR-v29/
│       │       │   └── strings.xml
│       │       ├── values-fi-rFI/
│       │       │   └── strings.xml
│       │       ├── values-fi-rFI-v29/
│       │       │   └── strings.xml
│       │       ├── values-fr-rFR/
│       │       │   └── strings.xml
│       │       ├── values-fr-rFR-v29/
│       │       │   └── strings.xml
│       │       ├── values-fy-rNL/
│       │       │   └── strings.xml
│       │       ├── values-fy-rNL-v29/
│       │       │   └── strings.xml
│       │       ├── values-gl-rES/
│       │       │   └── strings.xml
│       │       ├── values-gl-rES-v29/
│       │       │   └── strings.xml
│       │       ├── values-hi-rIN/
│       │       │   └── strings.xml
│       │       ├── values-hi-rIN-v29/
│       │       │   └── strings.xml
│       │       ├── values-hu-rHU/
│       │       │   └── strings.xml
│       │       ├── values-hu-rHU-v29/
│       │       │   └── strings.xml
│       │       ├── values-in-rID/
│       │       │   └── strings.xml
│       │       ├── values-in-rID-v29/
│       │       │   └── strings.xml
│       │       ├── values-it-rIT/
│       │       │   └── strings.xml
│       │       ├── values-it-rIT-v29/
│       │       │   └── strings.xml
│       │       ├── values-iw-rIL/
│       │       │   └── strings.xml
│       │       ├── values-iw-rIL-v29/
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP/
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP-v29/
│       │       │   └── strings.xml
│       │       ├── values-kn-rIN/
│       │       │   └── strings.xml
│       │       ├── values-kn-rIN-v29/
│       │       │   └── strings.xml
│       │       ├── values-ko-rKR/
│       │       │   └── strings.xml
│       │       ├── values-ko-rKR-v29/
│       │       │   └── strings.xml
│       │       ├── values-lt-rLT/
│       │       │   └── strings.xml
│       │       ├── values-lt-rLT-v29/
│       │       │   └── strings.xml
│       │       ├── values-lv-rLV/
│       │       │   └── strings.xml
│       │       ├── values-lv-rLV-v29/
│       │       │   └── strings.xml
│       │       ├── values-ml-rIN/
│       │       │   └── strings.xml
│       │       ├── values-ml-rIN-v29/
│       │       │   └── strings.xml
│       │       ├── values-nb-rNO/
│       │       │   └── strings.xml
│       │       ├── values-nb-rNO-v29/
│       │       │   └── strings.xml
│       │       ├── values-nl-rNL/
│       │       │   └── strings.xml
│       │       ├── values-nl-rNL-v29/
│       │       │   └── strings.xml
│       │       ├── values-pl-rPL/
│       │       │   └── strings.xml
│       │       ├── values-pl-rPL-v29/
│       │       │   └── strings.xml
│       │       ├── values-pt-rBR/
│       │       │   └── strings.xml
│       │       ├── values-pt-rBR-v29/
│       │       │   └── strings.xml
│       │       ├── values-pt-rPT/
│       │       │   └── strings.xml
│       │       ├── values-pt-rPT-v29/
│       │       │   └── strings.xml
│       │       ├── values-ro-rRO/
│       │       │   └── strings.xml
│       │       ├── values-ro-rRO-v29/
│       │       │   └── strings.xml
│       │       ├── values-ru-rRU/
│       │       │   └── strings.xml
│       │       ├── values-ru-rRU-v29/
│       │       │   └── strings.xml
│       │       ├── values-sk-rSK/
│       │       │   └── strings.xml
│       │       ├── values-sk-rSK-v29/
│       │       │   └── strings.xml
│       │       ├── values-sr-rSP/
│       │       │   └── strings.xml
│       │       ├── values-sr-rSP-v29/
│       │       │   └── strings.xml
│       │       ├── values-sv-rSE/
│       │       │   └── strings.xml
│       │       ├── values-sv-rSE-v29/
│       │       │   └── strings.xml
│       │       ├── values-tr-rTR/
│       │       │   └── strings.xml
│       │       ├── values-tr-rTR-v29/
│       │       │   └── strings.xml
│       │       ├── values-uk-rUA/
│       │       │   └── strings.xml
│       │       ├── values-uk-rUA-v29/
│       │       │   └── strings.xml
│       │       ├── values-v27/
│       │       │   └── themes.xml
│       │       ├── values-v29/
│       │       │   └── strings.xml
│       │       ├── values-vi-rVN/
│       │       │   └── strings.xml
│       │       ├── values-vi-rVN-v29/
│       │       │   └── strings.xml
│       │       ├── values-w820dp/
│       │       │   └── dimens.xml
│       │       ├── values-zh-rCN/
│       │       │   └── strings.xml
│       │       ├── values-zh-rCN-v29/
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW/
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW-v29/
│       │       │   └── strings.xml
│       │       └── xml/
│       │           ├── backup_rules.xml
│       │           ├── backup_rules_old.xml
│       │           ├── file_paths.xml
│       │           ├── preferences.xml
│       │           ├── preferences_appearance.xml
│       │           ├── preferences_backups.xml
│       │           ├── preferences_behavior.xml
│       │           ├── preferences_import_export.xml
│       │           └── preferences_security.xml
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── beemdevelopment/
│           │           └── aegis/
│           │               ├── PreferencesTest.java
│           │               ├── crypto/
│           │               │   ├── SCryptTest.java
│           │               │   └── otp/
│           │               │       ├── HOTPTest.java
│           │               │       ├── MOTPTest.java
│           │               │       ├── TOTPTest.java
│           │               │       └── YAOTPTest.java
│           │               ├── helpers/
│           │               │   └── QrCodeAnalyzerTest.java
│           │               ├── importers/
│           │               │   └── DatabaseImporterTest.java
│           │               ├── otp/
│           │               │   ├── GoogleAuthInfoTest.java
│           │               │   ├── HotpInfoTest.java
│           │               │   ├── MotpInfoTest.java
│           │               │   ├── TotpInfoTest.java
│           │               │   └── YandexInfoTest.java
│           │               ├── util/
│           │               │   └── UUIDMapTest.java
│           │               ├── vault/
│           │               │   ├── VaultTest.java
│           │               │   └── slots/
│           │               │       └── SlotTest.java
│           │               └── vectors/
│           │                   └── VaultEntries.java
│           └── resources/
│               └── com/
│                   └── beemdevelopment/
│                       └── aegis/
│                           ├── importers/
│                           │   ├── 2fas_authenticator.json
│                           │   ├── 2fas_authenticator_encrypted.2fas
│                           │   ├── 2fas_authenticator_encrypted_v3.2fas
│                           │   ├── 2fas_authenticator_encrypted_v4.2fas
│                           │   ├── 2fas_authenticator_plain.2fas
│                           │   ├── 2fas_authenticator_plain_v3.2fas
│                           │   ├── 2fas_authenticator_plain_v4.2fas
│                           │   ├── aegis_encrypted.json
│                           │   ├── aegis_plain.json
│                           │   ├── andotp_plain.json
│                           │   ├── authy_encrypted.xml
│                           │   ├── authy_plain.xml
│                           │   ├── battle_net_authenticator.xml
│                           │   ├── bitwarden.csv
│                           │   ├── bitwarden.json
│                           │   ├── duo.json
│                           │   ├── ente_auth.txt
│                           │   ├── freeotp.xml
│                           │   ├── freeotp_plus.json
│                           │   ├── freeotp_plus_internal.xml
│                           │   ├── freeotp_v2_api23.xml
│                           │   ├── freeotp_v2_api25.xml
│                           │   ├── freeotp_v2_api27.xml
│                           │   ├── freeotp_v2_api34.xml
│                           │   ├── freeotp_v2_null_algo.xml
│                           │   ├── plain.txt
│                           │   ├── proton_authenticator.json
│                           │   ├── steam.json
│                           │   ├── steam_old.json
│                           │   ├── stratum_plain.json
│                           │   └── totp_authenticator_internal.xml
│                           └── vault/
│                               └── aegis_plain_grouped_v2.json
├── build.gradle
├── crowdin.yml
├── docs/
│   ├── decrypt.py
│   ├── iconpacks.md
│   └── vault.md
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── metadata/
│   └── en-US/
│       ├── full_description.txt
│       ├── short_description.txt
│       └── title.txt
└── settings.gradle
Download .txt
Showing preview only (227K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2633 symbols across 262 files)

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java
  class AegisTest (line 45) | public abstract class AegisTest {
    method init (line 63) | @Before
    method getGrantPermissionRule (line 68) | private static GrantPermissionRule getGrantPermissionRule() {
    method getApp (line 77) | protected AegisApplicationBase getApp() {
    method initEncryptedVault (line 81) | protected VaultRepository initEncryptedVault() {
    method initEmptyEncryptedVault (line 86) | protected VaultRepository initEmptyEncryptedVault() {
    method initPlainVault (line 91) | protected VaultRepository initPlainVault() {
    method initEmptyPlainVault (line 95) | protected VaultRepository initEmptyPlainVault() {
    method initVault (line 99) | private VaultRepository initVault(@Nullable VaultFileCredentials creds...
    method generateCredentials (line 123) | protected VaultFileCredentials generateCredentials() {
    method generateEntry (line 149) | protected static <T extends OtpInfo> VaultEntry generateEntry(Class<T>...
    method generateEntry (line 153) | protected static <T extends OtpInfo> VaultEntry generateEntry(Class<T>...
    method clickChildViewWithId (line 167) | protected static ViewAction clickChildViewWithId(final int id) {
    method withOtpType (line 187) | @NonNull

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestApplication.java
  type AegisTestApplication (line 5) | @CustomTestApplication(AegisApplicationBase.class)

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestRunner.java
  class AegisTestRunner (line 13) | public class AegisTestRunner extends AndroidJUnitRunner {
    method newApplication (line 18) | @Override
    method callApplicationOnCreate (line 24) | @Override

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java
  class BackupExportTest (line 84) | @RunWith(AndroidJUnit4.class)
    method setUp (line 93) | @Before
    method tearDown (line 98) | @After
    method testPlainVaultExportPlainJson (line 103) | @Test
    method testPlainVaultExportPlainTxt (line 116) | @Test
    method testPlainVaultExportEncryptedJson (line 131) | @Test
    method testEncryptedVaultExportPlainJson (line 145) | @Test
    method testEncryptedVaultExportPlainTxt (line 158) | @Test
    method testEncryptedVaultExportEncryptedJson (line 173) | @Test
    method testPlainVaultExportHtml (line 183) | @Test
    method testEncryptedVaultExportHtml (line 198) | @Test
    method testSeparateExportPassword (line 213) | @Test
    method testChangeBackupPassword (line 224) | @Test
    method testChangePasswordHavingBackupPassword (line 253) | @Test
    method setSeparateBackupExportPassword (line 282) | private void setSeparateBackupExportPassword() {
    method verifyPasswordSlotChange (line 302) | private void verifyPasswordSlotChange(VaultFileCredentials creds, Pass...
    method doExport (line 314) | private File doExport() {
    method openExportDialog (line 326) | private void openExportDialog() {
    method decryptPasswordSlot (line 331) | private MasterKey decryptPasswordSlot(PasswordSlot slot, String passwo...
    method getExportFileUri (line 341) | private File getExportFileUri() {
    method readVault (line 352) | private VaultRepository readVault(File file, @Nullable String password) {
    method readTxtExport (line 379) | private void readTxtExport(File file) {
    method checkHtmlExport (line 394) | private void checkHtmlExport(File file) {
    method checkReadEntries (line 414) | private void checkReadEntries(Collection<VaultEntry> entries) {

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/DeepLinkTest.java
  class DeepLinkTest (line 26) | @RunWith(AndroidJUnit4.class)
    method before (line 30) | @Before
    method testDeepLinkIntent (line 35) | @Test
    method testDeepLinkIntent_Empty (line 47) | @Test
    method testDeepLinkIntent_Bad (line 52) | @Test
    method launch (line 58) | @SuppressWarnings("deprecation")

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/EmptySecretTest.java
  class EmptySecretTest (line 31) | @RunWith(AndroidJUnit4.class)
    method before (line 37) | @Before
    method after (line 45) | @After
    method testVaultEntryEmptySecret (line 50) | @Test

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/IntroTest.java
  class IntroTest (line 56) | @RunWith(AndroidJUnit4.class)
    method setUp (line 67) | @Before
    method tearDown (line 77) | @After
    method testIntro_None (line 83) | @Test
    method testIntro_Password (line 105) | @Test
    method testIntro_Import_Plain (line 138) | @Test
    method testIntro_Import_Encrypted (line 158) | @Test
    method getResourceUri (line 182) | private Uri getResourceUri(String resourceName) {
    class ViewPager2IdlingResource (line 195) | private static class ViewPager2IdlingResource implements IdlingResource {
      method ViewPager2IdlingResource (line 200) | public ViewPager2IdlingResource(ViewPager2 viewPager, String resName) {
      method getName (line 213) | @Override
      method isIdleNow (line 218) | @Override
      method registerIdleTransitionCallback (line 223) | @Override

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java
  class OverallTest (line 61) | @RunWith(AndroidJUnit4.class)
    method testOverall (line 72) | @Test
    method changeSort (line 174) | private void changeSort(@IdRes int resId) {
    method changeGroupFilter (line 179) | private void changeGroupFilter(String text) {
    method addEntry (line 187) | private void addEntry(VaultEntry entry) {

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/PanicTriggerTest.java
  class PanicTriggerTest (line 22) | @RunWith(AndroidJUnit4.class)
    method before (line 26) | @Before
    method testPanicTriggerDisabled (line 31) | @Test
    method testPanicTriggerEnabled (line 41) | @Test
    method launchPanic (line 52) | private void launchPanic() {

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/rules/ScreenshotTestRule.java
  class ScreenshotTestRule (line 16) | public class ScreenshotTestRule extends TestWatcher {
    method failed (line 17) | @Override

FILE: app/src/androidTest/java/com/beemdevelopment/aegis/vault/VaultRepositoryTest.java
  class VaultRepositoryTest (line 21) | @RunWith(AndroidJUnit4.class)
    method before (line 25) | @Before
    method testToggleEncryption (line 30) | @Test

FILE: app/src/main/java/com/amulyakhare/textdrawable/TextDrawable.java
  class TextDrawable (line 13) | public class TextDrawable extends ShapeDrawable {
    method TextDrawable (line 27) | private TextDrawable(Builder builder) {
    method getDarkerShade (line 64) | private int getDarkerShade(int color) {
    method draw (line 70) | @Override
    method drawBorder (line 95) | private void drawBorder(Canvas canvas) {
    method setAlpha (line 110) | @Override
    method setColorFilter (line 115) | @Override
    method getOpacity (line 120) | @Override
    method getIntrinsicWidth (line 125) | @Override
    method getIntrinsicHeight (line 130) | @Override
    method builder (line 135) | public static IShapeBuilder builder() {
    class Builder (line 139) | public static class Builder implements IConfigBuilder, IShapeBuilder, ...
      method Builder (line 165) | private Builder() {
      method width (line 179) | public IConfigBuilder width(int width) {
      method height (line 184) | public IConfigBuilder height(int height) {
      method textColor (line 189) | public IConfigBuilder textColor(int color) {
      method withBorder (line 194) | public IConfigBuilder withBorder(int thickness) {
      method useFont (line 199) | public IConfigBuilder useFont(Typeface font) {
      method fontSize (line 204) | public IConfigBuilder fontSize(int size) {
      method bold (line 209) | public IConfigBuilder bold() {
      method toUpperCase (line 214) | public IConfigBuilder toUpperCase() {
      method beginConfig (line 219) | @Override
      method endConfig (line 224) | @Override
      method rect (line 229) | @Override
      method round (line 235) | @Override
      method roundRect (line 241) | @Override
      method buildRect (line 249) | @Override
      method buildRoundRect (line 255) | @Override
      method buildRound (line 261) | @Override
      method build (line 267) | @Override
    type IConfigBuilder (line 275) | public interface IConfigBuilder {
      method width (line 276) | public IConfigBuilder width(int width);
      method height (line 278) | public IConfigBuilder height(int height);
      method textColor (line 280) | public IConfigBuilder textColor(int color);
      method withBorder (line 282) | public IConfigBuilder withBorder(int thickness);
      method useFont (line 284) | public IConfigBuilder useFont(Typeface font);
      method fontSize (line 286) | public IConfigBuilder fontSize(int size);
      method bold (line 288) | public IConfigBuilder bold();
      method toUpperCase (line 290) | public IConfigBuilder toUpperCase();
      method endConfig (line 292) | public IShapeBuilder endConfig();
    type IBuilder (line 295) | public static interface IBuilder {
      method build (line 297) | public TextDrawable build(String text, int color);
    type IShapeBuilder (line 300) | public static interface IShapeBuilder {
      method beginConfig (line 302) | public IConfigBuilder beginConfig();
      method rect (line 304) | public IBuilder rect();
      method round (line 306) | public IBuilder round();
      method roundRect (line 308) | public IBuilder roundRect(int radius);
      method buildRect (line 310) | public TextDrawable buildRect(String text, int color);
      method buildRoundRect (line 312) | public TextDrawable buildRoundRect(String text, int color, int radius);
      method buildRound (line 314) | public TextDrawable buildRound(String text, int color);

FILE: app/src/main/java/com/amulyakhare/textdrawable/util/ColorGenerator.java
  class ColorGenerator (line 11) | public class ColorGenerator {
    method create (line 53) | public static ColorGenerator create(List<Integer> colorList) {
    method ColorGenerator (line 57) | private ColorGenerator(List<Integer> colorList) {
    method getRandomColor (line 62) | public int getRandomColor() {
    method getColor (line 66) | public int getColor(Object key) {

FILE: app/src/main/java/com/beemdevelopment/aegis/AccountNamePosition.java
  type AccountNamePosition (line 3) | public enum AccountNamePosition {
    method fromInteger (line 14) | public static AccountNamePosition fromInteger(int x) {

FILE: app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java
  class AegisApplication (line 5) | @HiltAndroidApp

FILE: app/src/main/java/com/beemdevelopment/aegis/AegisApplicationBase.java
  class AegisApplicationBase (line 34) | public abstract class AegisApplicationBase extends Application {
    method onCreate (line 44) | @Override
    method initAppShortcuts (line 69) | @RequiresApi(api = Build.VERSION_CODES.N_MR1)
    method initNotificationChannels (line 91) | private void initNotificationChannels() {
    class AppLifecycleObserver (line 105) | private class AppLifecycleObserver implements LifecycleEventObserver {
      method onStateChanged (line 106) | @Override
    type EntryPoint (line 116) | @EarlyEntryPoint
      method getVaultManager (line 119) | VaultManager getVaultManager();

FILE: app/src/main/java/com/beemdevelopment/aegis/AegisBackupAgent.java
  class AegisBackupAgent (line 25) | public class AegisBackupAgent extends BackupAgent {
    method onCreate (line 32) | @Override
    method onFullBackup (line 42) | @Override
    method fullBackup (line 73) | private void fullBackup(FullBackupDataOutput data) throws IOException {
    method onRestoreFile (line 94) | @Override
    method onQuotaExceeded (line 114) | @Override
    method onBackup (line 120) | @Override
    method onRestore (line 125) | @Override
    method createBackupDir (line 130) | private void createBackupDir() throws IOException {
    method deleteBackupDir (line 137) | private void deleteBackupDir() {
    method getVaultBackupFile (line 144) | private File getVaultBackupFile() {

FILE: app/src/main/java/com/beemdevelopment/aegis/AegisModule.java
  class AegisModule (line 21) | @Module
    method provideIconPackManager (line 24) | @Provides
    method provideAuditLogRepository (line 30) | @Provides
    method provideVaultManager (line 37) | @Provides
    method providePreferences (line 43) | @Provides
    method provideAppDatabase (line 48) | @Provides

FILE: app/src/main/java/com/beemdevelopment/aegis/BackupsVersioningStrategy.java
  type BackupsVersioningStrategy (line 3) | public enum BackupsVersioningStrategy {

FILE: app/src/main/java/com/beemdevelopment/aegis/CopyBehavior.java
  type CopyBehavior (line 3) | public enum CopyBehavior {
    method fromInteger (line 14) | public static CopyBehavior fromInteger(int x) {

FILE: app/src/main/java/com/beemdevelopment/aegis/EventType.java
  type EventType (line 3) | public enum EventType {
    method fromInteger (line 18) | public static EventType fromInteger(int x) {
    method getEventTitleRes (line 22) | public static int getEventTitleRes(EventType eventType) {

FILE: app/src/main/java/com/beemdevelopment/aegis/GroupPlaceholderType.java
  type GroupPlaceholderType (line 3) | public enum GroupPlaceholderType {
    method getStringRes (line 8) | public int getStringRes() {

FILE: app/src/main/java/com/beemdevelopment/aegis/PassReminderFreq.java
  type PassReminderFreq (line 7) | public enum PassReminderFreq {
    method getDurationMillis (line 14) | public long getDurationMillis() {
    method getStringRes (line 37) | @StringRes
    method fromInteger (line 53) | public static PassReminderFreq fromInteger(int i) {

FILE: app/src/main/java/com/beemdevelopment/aegis/Preferences.java
  class Preferences (line 33) | public class Preferences {
    method Preferences (line 61) | public Preferences(Context context) {
    method migratePreferences (line 71) | public void migratePreferences() {
    method isTapToRevealEnabled (line 85) | public boolean isTapToRevealEnabled() {
    method isGroupMultiselectEnabled (line 89) | public boolean isGroupMultiselectEnabled() {
    method isEntryHighlightEnabled (line 93) | public boolean isEntryHighlightEnabled() {
    method isHapticFeedbackEnabled (line 97) | public boolean isHapticFeedbackEnabled() {
    method isPauseFocusedEnabled (line 101) | public boolean isPauseFocusedEnabled() {
    method isPanicTriggerEnabled (line 107) | public boolean isPanicTriggerEnabled() {
    method setIsPanicTriggerEnabled (line 111) | public void setIsPanicTriggerEnabled(boolean enabled) {
    method isSecureScreenEnabled (line 115) | public boolean isSecureScreenEnabled() {
    method getPasswordReminderFrequency (line 120) | public PassReminderFreq getPasswordReminderFrequency() {
    method setPasswordReminderFrequency (line 130) | public void setPasswordReminderFrequency(PassReminderFreq freq) {
    method isPasswordReminderNeeded (line 134) | public boolean isPasswordReminderNeeded() {
    method isPasswordReminderNeeded (line 138) | boolean isPasswordReminderNeeded(long currTime) {
    method getPasswordReminderTimestamp (line 148) | public Date getPasswordReminderTimestamp() {
    method setPasswordReminderTimestamp (line 152) | void setPasswordReminderTimestamp(long timestamp) {
    method resetPasswordReminderTimestamp (line 156) | public void resetPasswordReminderTimestamp() {
    method onlyShowNecessaryAccountNames (line 160) | public boolean onlyShowNecessaryAccountNames() { return _prefs.getBool...
    method isIconVisible (line 162) | public boolean isIconVisible() {
    method getShowNextCode (line 166) | public boolean getShowNextCode() {
    method getShowExpirationState (line 170) | public boolean getShowExpirationState() {
    method getCodeGroupSize (line 174) | public CodeGrouping getCodeGroupSize() {
    method setCodeGroupSize (line 180) | public void setCodeGroupSize(CodeGrouping codeGroupSize) {
    method isIntroDone (line 184) | public boolean isIntroDone() {
    method getAutoLockMask (line 188) | private int getAutoLockMask() {
    method getSearchBehaviorMask (line 197) | public int getSearchBehaviorMask() {
    method isSearchBehaviorTypeEnabled (line 203) | public boolean isSearchBehaviorTypeEnabled(int searchBehaviorType) {
    method setSearchBehaviorMask (line 207) | public void setSearchBehaviorMask(int searchBehavior) {
    method isAutoLockEnabled (line 211) | public boolean isAutoLockEnabled() {
    method isAutoLockTypeEnabled (line 215) | public boolean isAutoLockTypeEnabled(int autoLockType) {
    method setAutoLockMask (line 219) | public void setAutoLockMask(int autoLock) {
    method setIntroDone (line 223) | public void setIntroDone(boolean done) {
    method setTapToRevealTime (line 227) | public void setTapToRevealTime(int number) {
    method setCurrentSortCategory (line 231) | public void setCurrentSortCategory(SortCategory category) {
    method getCurrentSortCategory (line 235) | public SortCategory getCurrentSortCategory() {
    method getTapToRevealTime (line 239) | public int getTapToRevealTime() {
    method getCurrentTheme (line 243) | public Theme getCurrentTheme() {
    method setCurrentTheme (line 247) | public void setCurrentTheme(Theme theme) {
    method isDynamicColorsEnabled (line 251) | public boolean isDynamicColorsEnabled() {
    method getCurrentViewMode (line 255) | public ViewMode getCurrentViewMode() {
    method setCurrentViewMode (line 259) | public void setCurrentViewMode(ViewMode viewMode) {
    method getAccountNamePosition (line 263) | public AccountNamePosition getAccountNamePosition() {
    method setAccountNamePosition (line 267) | public void setAccountNamePosition(AccountNamePosition accountNamePosi...
    method getUsageCount (line 271) | public Integer getUsageCount(UUID uuid) {
    method resetUsageCount (line 277) | public void resetUsageCount(UUID uuid) {
    method getLastUsedTimestamp (line 284) | public long getLastUsedTimestamp(UUID uuid) {
    method clearUsageCount (line 294) | public void clearUsageCount() {
    method getLastUsedTimestamps (line 298) | public Map<UUID, Long> getLastUsedTimestamps() {
    method setLastUsedTimestamps (line 313) | public void setLastUsedTimestamps(Map<UUID, Long> lastUsedTimestamps) {
    method getUsageCounts (line 329) | public Map<UUID, Integer> getUsageCounts() {
    method setUsageCount (line 344) | public void setUsageCount(Map<UUID, Integer> usageCounts) {
    method getTimeout (line 360) | public int getTimeout() {
    method getLanguage (line 364) | public String getLanguage() {
    method setLanguage (line 368) | public void setLanguage(String lang) {
    method getLocale (line 372) | public Locale getLocale() {
    method isAndroidBackupsEnabled (line 391) | public boolean isAndroidBackupsEnabled() {
    method setIsAndroidBackupsEnabled (line 395) | public void setIsAndroidBackupsEnabled(boolean enabled) {
    method isBackupsEnabled (line 400) | public boolean isBackupsEnabled() {
    method setIsBackupsEnabled (line 404) | public void setIsBackupsEnabled(boolean enabled) {
    method isBackupReminderEnabled (line 409) | public boolean isBackupReminderEnabled() {
    method setIsBackupReminderEnabled (line 413) | public void setIsBackupReminderEnabled(boolean enabled) {
    method getBackupsLocation (line 417) | public Uri getBackupsLocation() {
    method getFocusSearchEnabled (line 426) | public boolean getFocusSearchEnabled() {
    method setFocusSearch (line 430) | public void setFocusSearch(boolean enabled) {
    method setLatestExportTimeNow (line 434) | public void setLatestExportTimeNow() {
    method getLatestBackupOrExportTime (line 439) | public Date getLatestBackupOrExportTime() {
    method setBackupsLocation (line 464) | public void setBackupsLocation(Uri location) {
    method getBackupsVersionCount (line 468) | public int getBackupsVersionCount() {
    method setBackupsVersionCount (line 472) | public void setBackupsVersionCount(int versions) {
    method setAndroidBackupResult (line 476) | public void setAndroidBackupResult(@Nullable BackupResult res) {
    method setBuiltInBackupResult (line 480) | public void setBuiltInBackupResult(@Nullable BackupResult res) {
    method getAndroidBackupResult (line 484) | @Nullable
    method getBuiltInBackupResult (line 489) | @Nullable
    method getErroredBackupResult (line 494) | @Nullable
    method setBackupResult (line 507) | private void setBackupResult(boolean isBuiltInBackup, @Nullable Backup...
    method getBackupResult (line 516) | @Nullable
    method getBackupResultKey (line 532) | private static String getBackupResultKey(boolean isBuiltInBackup) {
    method setIsBackupReminderNeeded (line 536) | public void setIsBackupReminderNeeded(boolean needed) {
    method isBackupsReminderNeeded (line 542) | public boolean isBackupsReminderNeeded() {
    method setIsPlaintextBackupWarningNeeded (line 546) | public void setIsPlaintextBackupWarningNeeded(boolean needed) {
    method isPlaintextBackupWarningNeeded (line 550) | public boolean isPlaintextBackupWarningNeeded() {
    method setIsPlaintextBackupWarningDisabled (line 555) | public void setIsPlaintextBackupWarningDisabled(boolean disabled) {
    method isPlaintextBackupWarningDisabled (line 559) | public boolean isPlaintextBackupWarningDisabled() {
    method isPinKeyboardEnabled (line 563) | public boolean isPinKeyboardEnabled() {
    method isTimeSyncWarningEnabled (line 567) | public boolean isTimeSyncWarningEnabled() {
    method setIsTimeSyncWarningEnabled (line 571) | public void setIsTimeSyncWarningEnabled(boolean enabled) {
    method getCopyBehavior (line 575) | public CopyBehavior getCopyBehavior() {
    method setCopyBehavior (line 579) | public void setCopyBehavior(CopyBehavior copyBehavior) {
    method isMinimizeOnCopyEnabled (line 583) | public boolean isMinimizeOnCopyEnabled() {
    method setGroupFilter (line 587) | public void setGroupFilter(Set<UUID> groupFilter) {
    method getGroupFilter (line 592) | public Set<UUID> getGroupFilter() {
    method getBackupVersioningStrategy (line 610) | @NonNull
    class BackupResult (line 623) | public static class BackupResult {
      method BackupResult (line 629) | public BackupResult(@Nullable Exception e) {
      method BackupResult (line 633) | private BackupResult(Date time, @Nullable String error, boolean isPe...
      method getError (line 639) | @Nullable
      method isSuccessful (line 644) | public boolean isSuccessful() {
      method getTime (line 648) | public Date getTime() {
      method getElapsedSince (line 652) | public String getElapsedSince(Context context) {
      method isBuiltIn (line 656) | public boolean isBuiltIn() {
      method setIsBuiltIn (line 660) | private void setIsBuiltIn(boolean isBuiltIn) {
      method isPermissionError (line 664) | public boolean isPermissionError() {
      method toJson (line 668) | public String toJson() {
      method fromJson (line 682) | public static BackupResult fromJson(String json) throws JSONException {
    type CodeGrouping (line 691) | public enum CodeGrouping {
      method CodeGrouping (line 699) | CodeGrouping(int value) {
      method getValue (line 703) | public int getValue() {

FILE: app/src/main/java/com/beemdevelopment/aegis/SortCategory.java
  type SortCategory (line 12) | public enum SortCategory {
    method fromInteger (line 27) | public static SortCategory fromInteger(int x) {
    method getComparator (line 31) | public Comparator<VaultEntry> getComparator() {
    method getMenuItem (line 57) | public int getMenuItem() {

FILE: app/src/main/java/com/beemdevelopment/aegis/Theme.java
  type Theme (line 3) | public enum Theme {
    method fromInteger (line 16) | public static Theme fromInteger(int x) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ThemeMap.java
  class ThemeMap (line 7) | public class ThemeMap {
    method ThemeMap (line 8) | private ThemeMap() {

FILE: app/src/main/java/com/beemdevelopment/aegis/VibrationPatterns.java
  class VibrationPatterns (line 5) | public class VibrationPatterns {
    method getLengthInMillis (line 9) | public static long getLengthInMillis(long[] pattern) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ViewMode.java
  type ViewMode (line 5) | public enum ViewMode {
    method fromInteger (line 17) | public static ViewMode fromInteger(int x) {
    method getLayoutId (line 21) | @LayoutRes
    method getItemOffset (line 40) | public float getItemOffset() {
    method getSpanCount (line 50) | public int getSpanCount() {
    method getFormattedAccountName (line 58) | public String getFormattedAccountName(String accountName) {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/CryptParameters.java
  class CryptParameters (line 11) | public class CryptParameters implements Serializable {
    method CryptParameters (line 15) | public CryptParameters(byte[] nonce, byte[] tag) {
    method toJson (line 20) | public JSONObject toJson() {
    method fromJson (line 33) | public static CryptParameters fromJson(JSONObject obj) throws JSONExce...
    method getNonce (line 39) | public byte[] getNonce() {
    method getTag (line 43) | public byte[] getTag() {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/CryptResult.java
  class CryptResult (line 3) | public class CryptResult {
    method CryptResult (line 7) | public CryptResult(byte[] data, CryptParameters params) {
    method getData (line 12) | public byte[] getData() {
    method getParams (line 16) | public CryptParameters getParams() {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/CryptoUtils.java
  class CryptoUtils (line 26) | public class CryptoUtils {
    method deriveKey (line 36) | public static SecretKey deriveKey(byte[] input, SCryptParameters param...
    method deriveKey (line 41) | public static SecretKey deriveKey(char[] password, SCryptParameters pa...
    method createEncryptCipher (line 46) | public static Cipher createEncryptCipher(SecretKey key)
    method createDecryptCipher (line 52) | public static Cipher createDecryptCipher(SecretKey key, byte[] nonce)
    method createCipher (line 58) | private static Cipher createCipher(SecretKey key, int opmode, byte[] n...
    method encrypt (line 75) | public static CryptResult encrypt(byte[] data, Cipher cipher)
    method decrypt (line 85) | public static CryptResult decrypt(byte[] encrypted, Cipher cipher, Cry...
    method decrypt (line 90) | public static CryptResult decrypt(byte[] encrypted, int encryptedOffse...
    method generateKey (line 103) | public static SecretKey generateKey() {
    method generateSalt (line 113) | public static byte[] generateSalt() {
    method generateRandomBytes (line 117) | public static byte[] generateRandomBytes(int length) {
    method toBytes (line 124) | public static byte[] toBytes(char[] chars) {
    method toBytesOld (line 132) | @Deprecated

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/KeyStoreHandle.java
  class KeyStoreHandle (line 23) | public class KeyStoreHandle {
    method KeyStoreHandle (line 27) | public KeyStoreHandle() throws KeyStoreHandleException {
    method containsKey (line 36) | public boolean containsKey(String id) throws KeyStoreHandleException {
    method generateKey (line 44) | public SecretKey generateKey(String id) throws KeyStoreHandleException {
    method getKey (line 70) | public SecretKey getKey(String id) throws KeyStoreHandleException {
    method isKeyPermanentlyInvalidated (line 90) | private static boolean isKeyPermanentlyInvalidated(SecretKey key) {
    method deleteKey (line 105) | public void deleteKey(String id) throws KeyStoreHandleException {
    method clear (line 113) | public void clear() throws KeyStoreHandleException {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/KeyStoreHandleException.java
  class KeyStoreHandleException (line 3) | public class KeyStoreHandleException extends Exception {
    method KeyStoreHandleException (line 4) | public KeyStoreHandleException(Throwable cause) {
    method KeyStoreHandleException (line 8) | public KeyStoreHandleException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKey.java
  class MasterKey (line 15) | public class MasterKey implements Serializable {
    method MasterKey (line 18) | public MasterKey(SecretKey key)  {
    method generate (line 25) | public static MasterKey generate() {
    method encrypt (line 29) | public CryptResult encrypt(byte[] bytes) throws MasterKeyException {
    method decrypt (line 43) | public CryptResult decrypt(byte[] bytes, CryptParameters params) throw...
    method getBytes (line 58) | public byte[] getBytes() {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKeyException.java
  class MasterKeyException (line 3) | public class MasterKeyException extends Exception {
    method MasterKeyException (line 4) | public MasterKeyException(Throwable cause) {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/SCryptParameters.java
  class SCryptParameters (line 5) | public class SCryptParameters implements Serializable {
    method SCryptParameters (line 11) | public SCryptParameters(int n, int r, int p, byte[] salt) {
    method getSalt (line 18) | public byte[] getSalt() {
    method getN (line 22) | public int getN() {
    method getR (line 26) | public int getR() {
    method getP (line 30) | public int getP() {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/bc/SCrypt.java
  class SCrypt (line 37) | public class SCrypt
    method SCrypt (line 39) | private SCrypt()
    method generate (line 57) | public static byte[] generate(byte[] P, byte[] S, int N, int r, int p,...
    method MFcrypt (line 93) | private static byte[] MFcrypt(byte[] P, byte[] S, int N, int r, int p,...
    method SingleIterationPBKDF2 (line 136) | private static byte[] SingleIterationPBKDF2(byte[] P, byte[] S, int dk...
    method SMix (line 144) | private static void SMix(int[] B, int BOff, int N, int d, int r)
    method BlockMix (line 200) | private static void BlockMix(int[] B, int[] X1, int[] X2, int[] Y, int r)
    method Xor (line 218) | private static void Xor(int[] a, int[] b, int bOff, int[] output)
    method Clear (line 226) | private static void Clear(byte[] array)
    method Clear (line 234) | private static void Clear(int[] array)
    method ClearAll (line 242) | private static void ClearAll(int[][] arrays)
    method isPowerOf2 (line 251) | private static boolean isPowerOf2(int x)

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/bc/Salsa20Engine.java
  class Salsa20Engine (line 26) | public class Salsa20Engine {
    method Salsa20Engine (line 27) | private Salsa20Engine()
    method salsaCore (line 32) | public static void salsaCore(int rounds, int[] input, int[] x)

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/otp/HOTP.java
  class HOTP (line 11) | public class HOTP {
    method HOTP (line 12) | private HOTP() {
    method generateOTP (line 15) | public static OTP generateOTP(byte[] secret, String algo, int digits, ...
    method getHash (line 30) | public static byte[] getHash(byte[] secret, String algo, long counter)

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/otp/MOTP.java
  class MOTP (line 12) | public class MOTP {
    method MOTP (line 16) | private MOTP(String code, int digits) {
    method generateOTP (line 21) | @NonNull
    method generateOTP (line 28) | @NonNull
    method getDigest (line 40) | @VisibleForTesting
    method toString (line 49) | @NonNull

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java
  class OTP (line 5) | public class OTP {
    method OTP (line 11) | public OTP(int code, int digits) {
    method getCode (line 16) | public int getCode() {
    method getDigits (line 20) | public int getDigits() {
    method toString (line 24) | @NonNull
    method toSteamString (line 38) | public String toSteamString() {

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/otp/TOTP.java
  class TOTP (line 6) | public class TOTP {
    method TOTP (line 8) | private TOTP() {
    method generateOTP (line 11) | public static OTP generateOTP(byte[] secret, String algo, int digits, ...
    method generateOTP (line 17) | public static OTP generateOTP(byte[] secret, String algo, int digits, ...

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/otp/YAOTP.java
  class YAOTP (line 15) | public class YAOTP {
    method YAOTP (line 20) | private YAOTP(long code, int digits) {
    method generateOTP (line 25) | public static YAOTP generateOTP(byte[] secret, String pin, int digits,...
    method generateOTP (line 31) | public static YAOTP generateOTP(byte[] secret, String pin, int digits,...
    method toString (line 58) | @NonNull

FILE: app/src/main/java/com/beemdevelopment/aegis/crypto/pins/GuardianProjectFDroidRSA2048.java
  class GuardianProjectFDroidRSA2048 (line 5) | public final class GuardianProjectFDroidRSA2048 extends ApkSignaturePin {
    method GuardianProjectFDroidRSA2048 (line 7) | public GuardianProjectFDroidRSA2048() {

FILE: app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java
  class AppDatabase (line 12) | @Database(entities = {AuditLogEntry.class}, version = 1)
    method auditLogDao (line 14) | public abstract AuditLogDao auditLogDao();

FILE: app/src/main/java/com/beemdevelopment/aegis/database/AuditLogDao.java
  type AuditLogDao (line 10) | @Dao
    method insert (line 12) | @Insert
    method getAll (line 15) | @Query("SELECT * FROM audit_logs WHERE timestamp >= strftime('%s', 'no...

FILE: app/src/main/java/com/beemdevelopment/aegis/database/AuditLogEntry.java
  class AuditLogEntry (line 12) | @Entity(tableName = "audit_logs")
    method AuditLogEntry (line 27) | @Ignore
    method AuditLogEntry (line 32) | @Ignore
    method AuditLogEntry (line 39) | AuditLogEntry(long id, @NonNull EventType eventType, @Nullable String ...
    method getId (line 46) | public long getId() {
    method getEventType (line 50) | public EventType getEventType() {
    method getReference (line 54) | public String getReference() {
    method getTimestamp (line 58) | public long getTimestamp() {

FILE: app/src/main/java/com/beemdevelopment/aegis/database/AuditLogRepository.java
  class AuditLogRepository (line 11) | public class AuditLogRepository {
    method AuditLogRepository (line 15) | public AuditLogRepository(AuditLogDao auditLogDao) {
    method getAllAuditLogEntries (line 20) | public LiveData<List<AuditLogEntry>> getAllAuditLogEntries() {
    method addVaultUnlockedEvent (line 24) | public void addVaultUnlockedEvent() {
    method addBackupCreatedEvent (line 29) | public void addBackupCreatedEvent() {
    method addAndroidBackupCreatedEvent (line 34) | public void addAndroidBackupCreatedEvent() {
    method addVaultExportedEvent (line 39) | public void addVaultExportedEvent() {
    method addEntrySharedEvent (line 44) | public void addEntrySharedEvent(String reference) {
    method addVaultUnlockFailedPasswordEvent (line 49) | public void addVaultUnlockFailedPasswordEvent() {
    method addVaultUnlockFailedBiometricsEvent (line 55) | public void addVaultUnlockFailedBiometricsEvent() {
    method insert (line 60) | public void insert(AuditLogEntry auditLogEntry) {

FILE: app/src/main/java/com/beemdevelopment/aegis/encoding/Base32.java
  class Base32 (line 8) | public class Base32 {
    method Base32 (line 9) | private Base32() {
    method decode (line 13) | public static byte[] decode(String s) throws EncodingException {
    method encode (line 21) | public static String encode(byte[] data) {
    method encode (line 25) | public static String encode(String s) {

FILE: app/src/main/java/com/beemdevelopment/aegis/encoding/Base64.java
  class Base64 (line 7) | public class Base64 {
    method Base64 (line 8) | private Base64() {
    method decode (line 12) | public static byte[] decode(String s) throws EncodingException {
    method decode (line 20) | public static byte[] decode(byte[] s) throws EncodingException {
    method encode (line 24) | public static String encode(byte[] data) {

FILE: app/src/main/java/com/beemdevelopment/aegis/encoding/EncodingException.java
  class EncodingException (line 5) | public class EncodingException extends IOException {
    method EncodingException (line 6) | public EncodingException(Throwable cause) {
    method EncodingException (line 10) | public EncodingException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/encoding/Hex.java
  class Hex (line 7) | public class Hex {
    method Hex (line 8) | private Hex() {
    method decode (line 12) | public static byte[] decode(String s) throws EncodingException {
    method encode (line 20) | public static String encode(byte[] data) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/AnimationsHelper.java
  class AnimationsHelper (line 9) | public class AnimationsHelper {
    method AnimationsHelper (line 10) | private AnimationsHelper() {
    method loadScaledAnimation (line 14) | public static Animation loadScaledAnimation(Context context, int anima...
    method loadScaledAnimation (line 18) | public static Animation loadScaledAnimation(Context context, int anima...
    method loadScaledLayoutAnimation (line 25) | public static LayoutAnimationController loadScaledLayoutAnimation(Cont...
    method loadScaledLayoutAnimation (line 29) | public static LayoutAnimationController loadScaledLayoutAnimation(Cont...
    type Scale (line 36) | public enum Scale {
      method Scale (line 42) | Scale(String setting) {
      method getValue (line 46) | public float getValue(Context context) {
      method isZero (line 50) | public boolean isZero(Context context) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/BiometricSlotInitializer.java
  class BiometricSlotInitializer (line 24) | public class BiometricSlotInitializer extends BiometricPrompt.Authentica...
    method BiometricSlotInitializer (line 29) | public BiometricSlotInitializer(Fragment fragment, Listener listener) {
    method BiometricSlotInitializer (line 34) | public BiometricSlotInitializer(FragmentActivity activity, Listener li...
    method authenticate (line 45) | public void authenticate(BiometricPrompt.PromptInfo info) {
    method cancelAuthentication (line 78) | public void cancelAuthentication() {
    method reset (line 87) | private void reset() {
    method fail (line 105) | private void fail(int errorCode, CharSequence errString) {
    method fail (line 110) | private void fail(Exception e) {
    method onAuthenticationError (line 115) | @Override
    method onAuthenticationSucceeded (line 121) | @Override
    method onAuthenticationFailed (line 127) | @Override
    type Listener (line 132) | public interface Listener {
      method onInitializeSlot (line 133) | void onInitializeSlot(BiometricSlot slot, Cipher cipher);
      method onSlotInitializationFailed (line 134) | void onSlotInitializationFailed(int errorCode, @NonNull CharSequence...

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/BiometricsHelper.java
  class BiometricsHelper (line 8) | public class BiometricsHelper {
    method BiometricsHelper (line 9) | private BiometricsHelper() {
    method getManager (line 13) | public static BiometricManager getManager(Context context) {
    method isCanceled (line 21) | public static boolean isCanceled(int errorCode) {
    method isAvailable (line 27) | public static boolean isAvailable(Context context) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/BitmapHelper.java
  class BitmapHelper (line 12) | public class BitmapHelper {
    method BitmapHelper (line 13) | private BitmapHelper() {
    method resize (line 20) | public static Bitmap resize(Bitmap bitmap, int maxWidth, int maxHeight) {
    method isVaultEntryIconOptimized (line 39) | public static boolean isVaultEntryIconOptimized(VaultEntryIcon icon) {
    method toVaultEntryIcon (line 46) | public static VaultEntryIcon toVaultEntryIcon(Bitmap bitmap, IconType ...

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/CenterVerticalSpan.java
  class CenterVerticalSpan (line 9) | public class CenterVerticalSpan extends MetricAffectingSpan {
    method CenterVerticalSpan (line 12) | public CenterVerticalSpan(Rect substringBounds) {
    method updateMeasureState (line 16) | @Override
    method updateDrawState (line 21) | @Override
    method applyBaselineShift (line 26) | private void applyBaselineShift(TextPaint textPaint) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/ContextHelper.java
  class ContextHelper (line 15) | public class ContextHelper {
    method ContextHelper (line 16) | private ContextHelper() {
    method getActivity (line 21) | @Nullable
    method getLifecycle (line 34) | @Nullable

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/DropdownHelper.java
  class DropdownHelper (line 13) | public class DropdownHelper {
    method DropdownHelper (line 14) | private DropdownHelper() {
    method fillDropdown (line 18) | public static void fillDropdown(Context context, AutoCompleteTextView ...
    method fillDropdown (line 23) | public static <T> void fillDropdown(Context context, AutoCompleteTextV...

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/EditTextHelper.java
  class EditTextHelper (line 8) | public class EditTextHelper {
    method EditTextHelper (line 9) | private EditTextHelper() {
    method getEditTextChars (line 12) | public static char[] getEditTextChars(EditText text) {
    method areEditTextsEqual (line 19) | public static boolean areEditTextsEqual(EditText text1, EditText text2) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/FabMenuHelper.java
  class FabMenuHelper (line 19) | public class FabMenuHelper {
    method FabMenuHelper (line 29) | public FabMenuHelper(
    method setOnFabMenuStateChangeListener (line 50) | public void setOnFabMenuStateChangeListener(Consumer<Boolean> listener) {
    method setupClickListeners (line 54) | private void setupClickListeners(Map<View, Runnable> actions) {
    method toggle (line 68) | public void toggle() {
    method open (line 76) | public void open() {
    method close (line 104) | public void close() {
    method animateFabIconForward (line 136) | private void animateFabIconForward(FloatingActionButton fab) {
    method animateFabIconBackward (line 140) | private void animateFabIconBackward(FloatingActionButton fab) {
    method animateFabIcon (line 144) | private void animateFabIcon(FloatingActionButton fab, float from, floa...
    method animateActionIn (line 163) | private void animateActionIn(View action, long delay) {
    method animateActionOut (line 179) | private void animateActionOut(View action, long delay) {
    method isOpen (line 190) | public boolean isOpen() {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/FabScrollHelper.java
  class FabScrollHelper (line 10) | public class FabScrollHelper {
    method FabScrollHelper (line 14) | public FabScrollHelper(View floatingActionsMenu) {
    method onScroll (line 18) | public void onScroll(int dx, int dy) {
    method setVisible (line 26) | public void setVisible(boolean visible) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/ItemTouchHelperAdapter.java
  type ItemTouchHelperAdapter (line 5) | public interface ItemTouchHelperAdapter {
    method onItemMove (line 19) | void onItemMove(int fromPosition, int toPosition);
    method onItemDismiss (line 31) | void onItemDismiss(int position);
    method onItemDrop (line 38) | void onItemDrop(int position);

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/MetricsHelper.java
  class MetricsHelper (line 6) | public class MetricsHelper {
    method MetricsHelper (line 7) | private MetricsHelper() {
    method convertDpToPixels (line 11) | public static int convertDpToPixels(Context context, float dp) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/PasswordStrengthHelper.java
  class PasswordStrengthHelper (line 16) | public class PasswordStrengthHelper {
    method PasswordStrengthHelper (line 29) | public PasswordStrengthHelper(
    method measure (line 41) | public void measure(Context context) {
    method getString (line 57) | private static String getString(int score, Context context) {
    method getColor (line 66) | private static String getColor(int score) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/PermissionHelper.java
  class PermissionHelper (line 13) | public class PermissionHelper {
    method PermissionHelper (line 14) | private PermissionHelper() {
    method granted (line 18) | public static boolean granted(Context context, String permission) {
    method request (line 22) | public static boolean request(Activity activity, int requestCode, Stri...
    method checkResults (line 38) | public static boolean checkResults(int[] grantResults) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeAnalyzer.java
  class QrCodeAnalyzer (line 18) | public class QrCodeAnalyzer implements ImageAnalysis.Analyzer {
    method QrCodeAnalyzer (line 24) | public QrCodeAnalyzer(QrCodeAnalyzer.Listener listener) {
    method analyze (line 28) | @Override
    type Listener (line 66) | public interface Listener {
      method onQrCodeDetected (line 67) | void onQrCodeDetected(Result result);

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeHelper.java
  class QrCodeHelper (line 27) | public class QrCodeHelper {
    method QrCodeHelper (line 28) | private QrCodeHelper() {
    method decodeFromSource (line 32) | public static Result decodeFromSource(LuminanceSource source) throws N...
    method decodeFromStream (line 42) | public static Result decodeFromStream(InputStream inStream) throws Dec...
    method encodeToBitmap (line 70) | public static Bitmap encodeToBitmap(String data, int width, int height...
    class DecodeError (line 87) | public static class DecodeError extends Exception {
      method DecodeError (line 88) | public DecodeError(String message) {
      method DecodeError (line 92) | public DecodeError(Throwable cause) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/SafHelper.java
  class SafHelper (line 11) | public class SafHelper {
    method SafHelper (line 12) | private SafHelper() {
    method getFileName (line 16) | public static String getFileName(Context context, Uri uri) {
    method getMimeType (line 31) | public static String getMimeType(Context context, Uri uri) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleAnimationEndListener.java
  class SimpleAnimationEndListener (line 5) | public class SimpleAnimationEndListener implements Animation.AnimationLi...
    method SimpleAnimationEndListener (line 8) | public SimpleAnimationEndListener(Listener listener) {
    method onAnimationStart (line 12) | @Override
    method onAnimationEnd (line 17) | @Override
    method onAnimationRepeat (line 24) | @Override
    type Listener (line 29) | public interface Listener {
      method onAnimationEnd (line 30) | void onAnimationEnd(Animation animation);

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleItemTouchHelperCallback.java
  class SimpleItemTouchHelperCallback (line 12) | public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callb...
    method SimpleItemTouchHelperCallback (line 21) | public SimpleItemTouchHelperCallback(EntryAdapter adapter) {
    method isLongPressDragEnabled (line 25) | @Override
    method setIsLongPressDragEnabled (line 30) | public void setIsLongPressDragEnabled(boolean enabled) {
    method setSelectedEntry (line 34) | public void setSelectedEntry(VaultEntry entry) {
    method isItemViewSwipeEnabled (line 45) | @Override
    method setDragFlags (line 50) | public void setDragFlags(int dragFlags) {
    method getMovementFlags (line 54) | @Override
    method onMove (line 80) | @Override
    method onSwiped (line 96) | @Override
    method clearView (line 101) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleTextWatcher.java
  class SimpleTextWatcher (line 6) | public final class SimpleTextWatcher implements TextWatcher {
    method SimpleTextWatcher (line 9) | public SimpleTextWatcher(Listener listener) {
    method beforeTextChanged (line 13) | @Override
    method onTextChanged (line 18) | @Override
    method afterTextChanged (line 23) | @Override
    type Listener (line 30) | public interface Listener {
      method afterTextChanged (line 31) | void afterTextChanged(Editable s);

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/TextDrawableHelper.java
  class TextDrawableHelper (line 11) | public class TextDrawableHelper {
    method TextDrawableHelper (line 35) | private TextDrawableHelper() {
    method generate (line 39) | public static TextDrawable generate(String text, String fallback, View...
    method getFirstGrapheme (line 55) | private static String getFirstGrapheme(String text) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/ThemeHelper.java
  class ThemeHelper (line 15) | public class ThemeHelper {
    method ThemeHelper (line 19) | public ThemeHelper(AppCompatActivity activity, Preferences prefs) {
    method setTheme (line 28) | public void setTheme(Map<Theme, Integer> themeMap) {
    method getConfiguredTheme (line 44) | public Theme getConfiguredTheme() {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/UiRefresher.java
  class UiRefresher (line 7) | public class UiRefresher {
    method UiRefresher (line 12) | public UiRefresher(Listener listener) {
    method destroy (line 17) | public void destroy() {
    method start (line 22) | public void start() {
    method getInitialRun (line 45) | private long getInitialRun() {
    method getNextRun (line 54) | private long getNextRun() {
    method stop (line 58) | public void stop() {
    type Listener (line 63) | public interface Listener {
      method onRefresh (line 64) | void onRefresh();
      method onExpiring (line 65) | void onExpiring();
      method getMillisTillNextRefresh (line 66) | long getMillisTillNextRefresh();
      method getPeriodMillis (line 67) | long getPeriodMillis();

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/UiThreadExecutor.java
  class UiThreadExecutor (line 10) | public class UiThreadExecutor implements Executor {
    method execute (line 13) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/VibrationHelper.java
  class VibrationHelper (line 11) | public class VibrationHelper {
    method VibrationHelper (line 14) | public VibrationHelper(Context context) {
    method vibratePattern (line 18) | public void vibratePattern(Context context, long[] pattern) {
    method isHapticFeedbackEnabled (line 41) | public boolean isHapticFeedbackEnabled() {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/ViewHelper.java
  class ViewHelper (line 9) | public class ViewHelper {
    method ViewHelper (line 10) | private ViewHelper() {
    method setupAppBarInsets (line 14) | public static void setupAppBarInsets(AppBarLayout appBar) {

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/AccountNameComparator.java
  class AccountNameComparator (line 7) | public class AccountNameComparator implements Comparator<VaultEntry> {
    method compare (line 8) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/FavoriteComparator.java
  class FavoriteComparator (line 7) | public class FavoriteComparator implements Comparator<VaultEntry> {
    method compare (line 8) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/IssuerNameComparator.java
  class IssuerNameComparator (line 7) | public class IssuerNameComparator implements Comparator<VaultEntry> {
    method compare (line 8) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/LastUsedComparator.java
  class LastUsedComparator (line 7) | public class LastUsedComparator implements Comparator<VaultEntry> {
    method compare (line 8) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/UsageCountComparator.java
  class UsageCountComparator (line 7) | public class UsageCountComparator implements Comparator<VaultEntry> {
    method compare (line 8) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/icons/IconPack.java
  class IconPack (line 22) | public class IconPack {
    method IconPack (line 30) | private IconPack(UUID uuid, String name, int version, List<Icon> icons) {
    method getUUID (line 37) | public UUID getUUID() {
    method getName (line 41) | public String getName() {
    method getVersion (line 45) | public int getVersion() {
    method getIcons (line 49) | public List<Icon> getIcons() {
    method getSuggestedIcons (line 56) | public List<Icon> getSuggestedIcons(String issuer) {
    method getDirectory (line 78) | @Nullable
    method setDirectory (line 83) | void setDirectory(@NonNull File dir) {
    method equals (line 92) | @Override
    method hashCode (line 102) | @Override
    method fromJson (line 107) | public static IconPack fromJson(JSONObject obj) throws JSONException {
    method fromBytes (line 128) | public static IconPack fromBytes(byte[] data) throws JSONException {
    class Icon (line 133) | public static class Icon implements Serializable {
      method Icon (line 141) | protected Icon(String filename, String name, String category, List<S...
      method getRelativeFilename (line 148) | public String getRelativeFilename() {
      method getFile (line 152) | @Nullable
      method setFile (line 157) | void setFile(@NonNull File file) {
      method getIconType (line 161) | public IconType getIconType() {
      method getName (line 165) | public String getName() {
      method getCategory (line 172) | public String getCategory() {
      method getMatchFor (line 176) | private MatchType getMatchFor(String issuer) {
      method fromJson (line 196) | public static Icon fromJson(JSONObject obj) throws JSONException {
    type MatchType (line 212) | private enum MatchType {

FILE: app/src/main/java/com/beemdevelopment/aegis/icons/IconPackException.java
  class IconPackException (line 3) | public class IconPackException extends Exception {
    method IconPackException (line 4) | public IconPackException(Throwable cause) {
    method IconPackException (line 8) | public IconPackException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/icons/IconPackExistsException.java
  class IconPackExistsException (line 3) | public class IconPackExistsException extends IconPackException {
    method IconPackExistsException (line 6) | public IconPackExistsException(IconPack pack) {
    method getIconPack (line 11) | public IconPack getIconPack() {

FILE: app/src/main/java/com/beemdevelopment/aegis/icons/IconPackManager.java
  class IconPackManager (line 24) | public class IconPackManager {
    method IconPackManager (line 30) | public IconPackManager(Context context) {
    method getIconPackByUUID (line 36) | private IconPack getIconPackByUUID(UUID uuid) {
    method hasIconPack (line 45) | public boolean hasIconPack() {
    method getIconPacks (line 49) | public List<IconPack> getIconPacks() {
    method removeIconPack (line 53) | public void removeIconPack(IconPack pack) throws IconPackException {
    method importPack (line 64) | public IconPack importPack(File inFile) throws IconPackException {
    method rescanIconPacks (line 132) | private void rescanIconPacks() {
    method getIconPackDir (line 177) | private File getIconPackDir(IconPack pack) {
    method getLatestVersionDir (line 181) | @Nullable
    method deleteDir (line 209) | private static void deleteDir(File dir) throws IOException {

FILE: app/src/main/java/com/beemdevelopment/aegis/icons/IconType.java
  type IconType (line 7) | public enum IconType {
    method fromMimeType (line 13) | public static IconType fromMimeType(String mimeType) {
    method fromFilename (line 26) | public static IconType fromFilename(String filename) {
    method toMimeType (line 41) | public String toMimeType() {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/AegisImporter.java
  class AegisImporter (line 33) | public class AegisImporter extends DatabaseImporter {
    method AegisImporter (line 35) | public AegisImporter(Context context) {
    method getAppPath (line 39) | @Override
    method read (line 44) | @Override
    class EncryptedState (line 58) | public static class EncryptedState extends State {
      method EncryptedState (line 61) | private EncryptedState(VaultFile file) {
      method getSlots (line 66) | public SlotList getSlots() {
      method decrypt (line 70) | public State decrypt(VaultFileCredentials creds) throws DatabaseImpo...
      method decrypt (line 81) | public State decrypt(char[] password) throws DatabaseImporterExcepti...
      method decrypt (line 88) | @Override
    class DecryptedState (line 113) | public static class DecryptedState extends State {
      method DecryptedState (line 117) | private DecryptedState(JSONObject obj) {
      method DecryptedState (line 121) | private DecryptedState(JSONObject obj, VaultFileCredentials creds) {
      method getCredentials (line 127) | @Nullable
      method convert (line 132) | @Override
      method convertEntry (line 174) | private static VaultEntry convertEntry(JSONObject obj) throws Databa...
      method convertGroup (line 182) | private static VaultGroup convertGroup(JSONObject obj) throws Databa...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java
  class AndOtpImporter (line 49) | public class AndOtpImporter extends DatabaseImporter {
    method AndOtpImporter (line 56) | public AndOtpImporter(Context context) {
    method getAppPath (line 60) | @Override
    method read (line 65) | @Override
    method read (line 83) | private static DecryptedState read(byte[] bytes) throws JSONException {
    class EncryptedState (line 88) | public static class EncryptedState extends DatabaseImporter.State {
      method EncryptedState (line 91) | public EncryptedState(byte[] data) {
      method decryptContent (line 96) | private DecryptedState decryptContent(SecretKey key, int offset) thr...
      method getKeyDerivationParams (line 117) | private PBKDFTask.Params getKeyDerivationParams(char[] password) thr...
      method decryptOldFormat (line 134) | protected DecryptedState decryptOldFormat(char[] password) throws Da...
      method decryptNewFormat (line 149) | protected DecryptedState decryptNewFormat(SecretKey key) throws Data...
      method decryptNewFormat (line 153) | protected DecryptedState decryptNewFormat(char[] password)
      method decrypt (line 160) | private void decrypt(Context context, char[] password, boolean oldFo...
      method decrypt (line 179) | @Override
    class DecryptedState (line 203) | public static class DecryptedState extends DatabaseImporter.State {
      method DecryptedState (line 206) | private DecryptedState(JSONArray obj) {
      method convert (line 211) | @Override
      method convertEntry (line 230) | private static VaultEntry convertEntry(JSONObject obj) throws Databa...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/AuthenticatorPlusImporter.java
  class AuthenticatorPlusImporter (line 18) | public class AuthenticatorPlusImporter extends DatabaseImporter {
    method AuthenticatorPlusImporter (line 21) | public AuthenticatorPlusImporter(Context context) {
    method getAppPath (line 25) | @Override
    method read (line 30) | @Override
    class EncryptedState (line 39) | public static class EncryptedState extends DatabaseImporter.State {
      method EncryptedState (line 42) | private EncryptedState(byte[] data) {
      method decrypt (line 47) | protected State decrypt(char[] password) throws DatabaseImporterExce...
      method decrypt (line 65) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/AuthyImporter.java
  class AuthyImporter (line 48) | public class AuthyImporter extends DatabaseImporter {
    method AuthyImporter (line 61) | public AuthyImporter(Context context) {
    method getAppPath (line 65) | @Override
    method readFromApp (line 70) | @Override
    method read (line 100) | @Override
    method read (line 123) | private State read(JSONArray array) throws DatabaseImporterException {
    method readFile (line 138) | private JSONArray readFile(SuFile file, String key) throws IOException...
    class EncryptedState (line 157) | public static class EncryptedState extends DatabaseImporter.State {
      method EncryptedState (line 160) | private EncryptedState(JSONArray array) {
      method decrypt (line 165) | protected DecryptedState decrypt(char[] password) throws DatabaseImp...
      method decrypt (line 205) | @Override
    class DecryptedState (line 218) | public static class DecryptedState extends DatabaseImporter.State {
      method DecryptedState (line 221) | private DecryptedState(JSONArray array) {
      method convert (line 226) | @Override
      method convertEntry (line 247) | private static VaultEntry convertEntry(JSONObject entry) throws Data...
      method sanitizeEntryInfo (line 273) | private static void sanitizeEntryInfo(AuthyEntryInfo info, boolean i...
    class AuthyEntryInfo (line 301) | private static class AuthyEntryInfo {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/BattleNetImporter.java
  class BattleNetImporter (line 23) | public class BattleNetImporter extends DatabaseImporter {
    method BattleNetImporter (line 29) | public BattleNetImporter(Context context) {
    method getAppPath (line 41) | @Override
    method read (line 46) | @Override
    class State (line 77) | public static class State extends DatabaseImporter.State {
      method State (line 81) | public State(String serial, String secretValue) {
      method convert (line 87) | @Override
      method convertEntry (line 101) | private static VaultEntry convertEntry(String serial, String secretS...
      method unmask (line 114) | private static String unmask(String s) throws EncodingException {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/BitwardenImporter.java
  class BitwardenImporter (line 31) | public class BitwardenImporter extends DatabaseImporter {
    method BitwardenImporter (line 32) | public BitwardenImporter(Context context) {
    method getAppPath (line 36) | @Override
    method read (line 41) | @Override
    class State (line 80) | public static class State extends DatabaseImporter.State {
      method State (line 83) | public State(List<String> entries) {
      method convert (line 88) | @Override
      method convertEntry (line 104) | private static VaultEntry convertEntry(String obj) throws DatabaseIm...
    method parseUri (line 114) | private static GoogleAuthInfo parseUri(String s) throws EncodingExcept...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseImporter.java
  class DatabaseImporter (line 25) | public abstract class DatabaseImporter {
    method DatabaseImporter (line 54) | public DatabaseImporter(Context context) {
    method requireContext (line 58) | protected Context requireContext() {
    method getAppPath (line 62) | protected abstract SuFile getAppPath() throws DatabaseImporterExceptio...
    method getAppPath (line 64) | protected SuFile getAppPath(String pkgName, String subPath) throws Pac...
    method isInstalledAppVersionSupported (line 69) | public boolean isInstalledAppVersionSupported() {
    method read (line 73) | protected abstract State read(InputStream stream, boolean isInternal) ...
    method read (line 75) | public State read(InputStream stream) throws DatabaseImporterException {
    method readFromApp (line 79) | public State readFromApp(Shell shell) throws PackageManager.NameNotFou...
    method create (line 90) | public static DatabaseImporter create(Context context, Class<? extends...
    method getImporters (line 99) | public static List<Definition> getImporters(boolean isDirect) {
    class Definition (line 107) | public static class Definition implements Serializable {
      method Definition (line 120) | public Definition(String name, Class<? extends DatabaseImporter> typ...
      method getName (line 127) | public String getName() {
      method getType (line 131) | public Class<? extends DatabaseImporter> getType() {
      method getHelp (line 135) | public @StringRes int getHelp() {
      method supportsDirect (line 139) | public boolean supportsDirect() {
    class State (line 144) | public static abstract class State {
      method State (line 147) | public State(boolean encrypted) {
      method isEncrypted (line 151) | public boolean isEncrypted() {
      method decrypt (line 155) | public void decrypt(Context context, DecryptListener listener) throw...
      method convert (line 163) | public Result convert() throws DatabaseImporterException {
    class Result (line 172) | public static class Result {
      method addEntry (line 177) | public void addEntry(VaultEntry entry) {
      method addGroup (line 181) | public void addGroup(VaultGroup group) {
      method addError (line 185) | public void addError(DatabaseImporterEntryException error) {
      method getEntries (line 189) | public UUIDMap<VaultEntry> getEntries() {
      method getGroups (line 193) | public UUIDMap<VaultGroup> getGroups() {
      method getErrors (line 197) | public List<DatabaseImporterEntryException> getErrors() {
    class DecryptListener (line 202) | public static abstract class DecryptListener {
      method onStateDecrypted (line 203) | protected abstract void onStateDecrypted(State state);
      method onError (line 204) | protected abstract void onError(Exception e);
      method onCanceled (line 205) | protected abstract void onCanceled();

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseImporterEntryException.java
  class DatabaseImporterEntryException (line 3) | public class DatabaseImporterEntryException extends Exception {
    method DatabaseImporterEntryException (line 6) | public DatabaseImporterEntryException(String message, String text) {
    method DatabaseImporterEntryException (line 11) | public DatabaseImporterEntryException(Throwable cause, String text) {
    method getText (line 16) | public String getText() {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseImporterException.java
  class DatabaseImporterException (line 3) | public class DatabaseImporterException extends Exception {
    method DatabaseImporterException (line 4) | public DatabaseImporterException(Throwable cause) {
    method DatabaseImporterException (line 8) | public DatabaseImporterException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/DuoImporter.java
  class DuoImporter (line 27) | public class DuoImporter extends DatabaseImporter {
    method DuoImporter (line 31) | public DuoImporter(Context context) {
    method getAppPath (line 35) | @Override
    method read (line 40) | @Override
    class DecryptedState (line 52) | public static class DecryptedState extends DatabaseImporter.State {
      method DecryptedState (line 55) | public DecryptedState(@NonNull JSONArray array) {
      method convert (line 60) | @Override
      method convertEntry (line 80) | private static @NonNull VaultEntry convertEntry(

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/EnteAuthImporter.java
  class EnteAuthImporter (line 12) | public class EnteAuthImporter extends DatabaseImporter {
    method EnteAuthImporter (line 13) | public EnteAuthImporter(Context context) {
    method getAppPath (line 17) | @Override
    method read (line 22) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java
  class FreeOtpImporter (line 55) | public class FreeOtpImporter extends DatabaseImporter {
    method FreeOtpImporter (line 59) | public FreeOtpImporter(Context context) {
    method getAppPath (line 63) | @Override
    method read (line 68) | @Override
    method readV1 (line 87) | private DecryptedStateV1 readV1(InputStream stream) throws DatabaseImp...
    method readV2 (line 106) | private EncryptedState readV2(DataInputStream stream) throws DatabaseI...
    class EncryptedState (line 116) | public static class EncryptedState extends State {
      method EncryptedState (line 128) | private EncryptedState(JSONObject mkObj, Map<String, String> entries)
      method decrypt (line 149) | public State decrypt(char[] password) throws DatabaseImporterExcepti...
      method decrypt (line 155) | public State decrypt(SecretKey passKey) throws DatabaseImporterExcep...
      method decrypt (line 174) | @Override
      method getKeyDerivationParams (line 199) | private PBKDFTask.Params getKeyDerivationParams(char[] password, Str...
    class DecryptedStateV2 (line 204) | public static class DecryptedStateV2 extends DatabaseImporter.State {
      method DecryptedStateV2 (line 208) | public DecryptedStateV2(Map<String, String> entries, SecretKey maste...
      method convert (line 214) | @Override
      method convertEntry (line 239) | private VaultEntry convertEntry(JSONObject encObj, JSONObject tokenObj)
    class DecryptedStateV1 (line 274) | public static class DecryptedStateV1 extends DatabaseImporter.State {
      method DecryptedStateV1 (line 277) | public DecryptedStateV1(List<JSONObject> entries) {
      method convert (line 282) | @Override
      method convertEntry (line 298) | private static VaultEntry convertEntry(JSONObject obj) throws Databa...
    method parseNonce (line 332) | private static byte[] parseNonce(byte[] parameters) throws IOException {
    method toBytes (line 349) | private static byte[] toBytes(JSONArray array) throws JSONException {
    class SerializedHashMapParser (line 356) | private static class SerializedHashMapParser {
      method SerializedHashMapParser (line 366) | private SerializedHashMapParser() {
      method parse (line 370) | public static Map<String, String> parse(DataInputStream inStream)
      method parseClassDescriptor (line 407) | private static void parseClassDescriptor(DataInputStream inputStream)
      method parseStringObject (line 444) | private static String parseStringObject(DataInputStream inputStream)
      method parseUTF (line 458) | private static String parseUTF(DataInputStream inputStream) throws I...
      class ParseException (line 465) | private static class ParseException extends Exception {
        method ParseException (line 466) | public ParseException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpPlusImporter.java
  class FreeOtpPlusImporter (line 19) | public class FreeOtpPlusImporter extends DatabaseImporter {
    method FreeOtpPlusImporter (line 23) | public FreeOtpPlusImporter(Context context) {
    method getAppPath (line 27) | @Override
    method read (line 32) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/GoogleAuthImporter.java
  class GoogleAuthImporter (line 22) | public class GoogleAuthImporter extends DatabaseImporter {
    method GoogleAuthImporter (line 29) | public GoogleAuthImporter(Context context) {
    method getAppPath (line 33) | @Override
    method isInstalledAppVersionSupported (line 39) | @Override
    method read (line 51) | @Override
    method readFromApp (line 59) | @Override
    class State (line 70) | public static class State extends DatabaseImporter.State {
      method State (line 74) | private State(List<Entry> entries, Context context) {
      method convert (line 80) | @Override
      method convertEntry (line 96) | private static VaultEntry convertEntry(Entry entry, Context context)...
    class Entry (line 128) | private static class Entry extends SqlImporterHelper.Entry {
      method Entry (line 136) | public Entry(Cursor cursor) {
      method getType (line 147) | public int getType() {
      method isEncrypted (line 151) | public boolean isEncrypted() {
      method getSecret (line 155) | public String getSecret() {
      method getEmail (line 159) | public String getEmail() {
      method getIssuer (line 163) | public String getIssuer() {
      method getCounter (line 167) | public long getCounter() {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/GoogleAuthUriImporter.java
  class GoogleAuthUriImporter (line 16) | public class GoogleAuthUriImporter extends DatabaseImporter {
    method GoogleAuthUriImporter (line 17) | public GoogleAuthUriImporter(Context context) {
    method getAppPath (line 21) | @Override
    method read (line 26) | @Override
    class State (line 45) | public static class State extends DatabaseImporter.State {
      method State (line 48) | private State(ArrayList<String> lines) {
      method convert (line 53) | @Override
      method convertEntry (line 69) | private static VaultEntry convertEntry(String line) throws DatabaseI...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/MicrosoftAuthImporter.java
  class MicrosoftAuthImporter (line 20) | public class MicrosoftAuthImporter extends DatabaseImporter {
    method MicrosoftAuthImporter (line 27) | public MicrosoftAuthImporter(Context context) {
    method getAppPath (line 31) | @Override
    method read (line 36) | @Override
    method readFromApp (line 43) | @Override
    class State (line 53) | public static class State extends DatabaseImporter.State {
      method State (line 56) | private State(List<Entry> entries) {
      method convert (line 61) | @Override
      method convertEntry (line 80) | private static VaultEntry convertEntry(Entry entry) throws DatabaseI...
    class Entry (line 105) | private static class Entry extends SqlImporterHelper.Entry {
      method Entry (line 111) | public Entry(Cursor cursor) {
      method getType (line 119) | public int getType() {
      method getSecret (line 123) | public String getSecret() {
      method getIssuer (line 127) | public String getIssuer() {
      method getUserName (line 131) | public String getUserName() {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/ProtonAuthenticatorImporter.java
  class ProtonAuthenticatorImporter (line 24) | public class ProtonAuthenticatorImporter extends DatabaseImporter {
    method ProtonAuthenticatorImporter (line 26) | public ProtonAuthenticatorImporter(Context context) {
    method getAppPath (line 30) | @Override
    method read (line 35) | @Override
    class DecryptedState (line 47) | public static class DecryptedState extends DatabaseImporter.State {
      method DecryptedState (line 50) | public DecryptedState(@NonNull JSONObject json) {
      method convert (line 55) | @Override
      method convertEntry (line 76) | private static @NonNull VaultEntry convertEntry(@NonNull JSONObject ...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/SqlImporterHelper.java
  class SqlImporterHelper (line 24) | public class SqlImporterHelper {
    method SqlImporterHelper (line 27) | public SqlImporterHelper(Context context) {
    method read (line 31) | public <T extends Entry> List<T> read(Class<T> type, SuFile path, Stri...
    method findDatabaseFiles (line 67) | private static SuFile[] findDatabaseFiles(SuFile path) throws Database...
    method read (line 76) | public <T extends Entry> List<T> read(Class<T> type, InputStream inStr...
    method read (line 99) | private <T extends Entry> List<T> read(Class<T> type, File file, Strin...
    method getString (line 121) | @SuppressLint("Range")
    method getString (line 126) | @SuppressLint("Range")
    method getInt (line 135) | @SuppressLint("Range")
    method getLong (line 140) | @SuppressLint("Range")
    class Entry (line 145) | public static abstract class Entry {
      method Entry (line 146) | public Entry(Cursor cursor) {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/SteamImporter.java
  class SteamImporter (line 26) | public class SteamImporter extends DatabaseImporter {
    method SteamImporter (line 30) | public SteamImporter(Context context) {
    method getAppPath (line 34) | @Override
    method isInstalledAppVersionSupported (line 47) | @Override
    method read (line 59) | @Override
    class State (line 82) | public static class State extends DatabaseImporter.State {
      method State (line 85) | private State(List<JSONObject> objs) {
      method convert (line 90) | @Override
      method convertEntry (line 106) | private static VaultEntry convertEntry(JSONObject obj) throws Databa...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/StratumImporter.java
  class StratumImporter (line 48) | public class StratumImporter extends DatabaseImporter {
    type Algorithm (line 54) | private enum Algorithm {
    method StratumImporter (line 60) | public StratumImporter(Context context) {
    method getAppPath (line 64) | @Override
    method read (line 69) | @Override
    method readInternal (line 74) | private State readInternal(InputStream stream) throws DatabaseImporter...
    method readExternal (line 79) | private static State readExternal(InputStream stream) throws DatabaseI...
    method readEncrypted (line 94) | private static State readEncrypted(DataInputStream stream) throws Data...
    method parseOtpInfo (line 114) | private static OtpInfo parseOtpInfo(int type, byte[] secret, Algorithm...
    class EncryptedState (line 128) | static class EncryptedState extends State {
      method EncryptedState (line 141) | public EncryptedState(Cipher cipher, byte[] salt, byte[] iv, byte[] ...
      method decrypt (line 149) | public JsonState decrypt(char[] password) throws DatabaseImporterExc...
      method decrypt (line 155) | public JsonState decrypt(SecretKey key) throws DatabaseImporterExcep...
      method decrypt (line 166) | @Override
      method getKeyDerivationParams (line 183) | private Argon2Task.Params getKeyDerivationParams(char[] password) {
      method parseHeader (line 193) | private static EncryptedState parseHeader(DataInputStream stream)
    class LegacyEncryptedState (line 206) | static class LegacyEncryptedState extends State {
      method LegacyEncryptedState (line 216) | public LegacyEncryptedState(Cipher cipher, byte[] salt, byte[] iv, b...
      method decrypt (line 224) | public JsonState decrypt(char[] password) throws DatabaseImporterExc...
      method decrypt (line 230) | public JsonState decrypt(SecretKey key) throws DatabaseImporterExcep...
      method decrypt (line 241) | @Override
      method getKeyDerivationParams (line 258) | private PBKDFTask.Params getKeyDerivationParams(char[] password) {
      method parseHeader (line 262) | private static LegacyEncryptedState parseHeader(DataInputStream stream)
    class JsonState (line 275) | private static class JsonState extends State {
      method JsonState (line 278) | public JsonState(JSONObject obj) {
      method convert (line 283) | @Override
      method convertEntry (line 304) | private static VaultEntry convertEntry(JSONObject obj) throws Databa...
    class SqlState (line 324) | private static class SqlState extends State {
      method SqlState (line 327) | public SqlState(List<SqlEntry> entries) {
      method convert (line 332) | @Override
    class SqlEntry (line 348) | private static class SqlEntry extends SqlImporterHelper.Entry {
      method SqlEntry (line 358) | public SqlEntry(Cursor cursor) {
      method convert (line 370) | public VaultEntry convert() throws DatabaseImporterEntryException {

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/TotpAuthenticatorImporter.java
  class TotpAuthenticatorImporter (line 46) | public class TotpAuthenticatorImporter extends DatabaseImporter {
    method TotpAuthenticatorImporter (line 60) | public TotpAuthenticatorImporter(Context context) {
    method getAppPath (line 64) | @Override
    method read (line 69) | @Override
    method parse (line 101) | private static List<JSONObject> parse(String data) throws JSONException {
    class EncryptedState (line 113) | public static class EncryptedState extends DatabaseImporter.State {
      method EncryptedState (line 116) | public EncryptedState(byte[] data) {
      method decrypt (line 121) | protected DecryptedState decrypt(char[] password) throws DatabaseImp...
      method decrypt (line 154) | @Override
      method decrypt (line 169) | private void decrypt(char[] password, DecryptListener listener) {
    class DecryptedState (line 179) | public static class DecryptedState extends DatabaseImporter.State {
      method DecryptedState (line 182) | private DecryptedState(List<JSONObject> objs) {
      method convert (line 187) | @Override
      method convertEntry (line 203) | private static VaultEntry convertEntry(JSONObject obj) throws Databa...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/TwoFASImporter.java
  class TwoFASImporter (line 46) | public class TwoFASImporter extends DatabaseImporter {
    method TwoFASImporter (line 50) | public TwoFASImporter(Context context) {
    method getAppPath (line 54) | @Override
    method read (line 59) | @Override
    method arrayToList (line 90) | private static List<JSONObject> arrayToList(JSONArray array) throws JS...
    class EncryptedState (line 99) | public static class EncryptedState extends State {
      method EncryptedState (line 104) | private EncryptedState(byte[] data, byte[] salt, byte[] iv) {
      method deriveKey (line 111) | private SecretKey deriveKey(char[] password)
      method decrypt (line 119) | public DecryptedState decrypt(char[] password) throws DatabaseImport...
      method decrypt (line 138) | @Override
    class DecryptedState (line 151) | public static class DecryptedState extends DatabaseImporter.State {
      method DecryptedState (line 154) | public DecryptedState(List<JSONObject> entries) {
      method convert (line 159) | @Override
      method convertEntry (line 175) | private static VaultEntry convertEntry(JSONObject obj) throws Databa...

FILE: app/src/main/java/com/beemdevelopment/aegis/importers/WinAuthImporter.java
  class WinAuthImporter (line 10) | public class WinAuthImporter extends DatabaseImporter {
    method WinAuthImporter (line 11) | public WinAuthImporter(Context context) {
    method getAppPath (line 15) | @Override
    method read (line 20) | @Override
    class State (line 27) | public static class State extends DatabaseImporter.State {
      method State (line 30) | private State(DatabaseImporter.State state) {
      method convert (line 35) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java
  class GoogleAuthInfo (line 22) | public class GoogleAuthInfo implements Transferable, Serializable {
    method GoogleAuthInfo (line 30) | public GoogleAuthInfo(OtpInfo info, String accountName, String issuer) {
    method parseUri (line 36) | public static GoogleAuthInfo parseUri(String s) throws GoogleAuthInfoE...
    method parseUri (line 44) | public static GoogleAuthInfo parseUri(Uri uri) throws GoogleAuthInfoEx...
    method parseSecret (line 166) | public static byte[] parseSecret(String s) throws EncodingException {
    method parseExportUri (line 171) | public static Export parseExportUri(String s) throws GoogleAuthInfoExc...
    method parseExportUri (line 179) | public static Export parseExportUri(Uri uri) throws GoogleAuthInfoExce...
    method getOtpInfo (line 274) | public OtpInfo getOtpInfo() {
    method getUri (line 278) | @Override
    method getIssuer (line 323) | public String getIssuer() {
    method getAccountName (line 327) | public String getAccountName() {
    class Export (line 331) | public static class Export implements Transferable, Serializable {
      method Export (line 337) | public Export(List<GoogleAuthInfo> entries, int batchId, int batchIn...
      method getEntries (line 344) | public List<GoogleAuthInfo> getEntries() {
      method getBatchSize (line 348) | public int getBatchSize() {
      method getBatchIndex (line 352) | public int getBatchIndex() {
      method getBatchId (line 356) | public int getBatchId() {
      method getMissingIndices (line 360) | public static List<Integer> getMissingIndices(@NonNull List<Export> ...
      method isSingleBatch (line 383) | public static boolean isSingleBatch(@NonNull List<Export> exports) {
      method getUri (line 398) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfoException.java
  class GoogleAuthInfoException (line 5) | public class GoogleAuthInfoException extends Exception {
    method GoogleAuthInfoException (line 8) | public GoogleAuthInfoException(Uri uri, Throwable cause) {
    method GoogleAuthInfoException (line 13) | public GoogleAuthInfoException(Uri uri, String message) {
    method GoogleAuthInfoException (line 18) | public GoogleAuthInfoException(Uri uri, String message, Throwable caus...
    method isPhoneFactor (line 26) | public boolean isPhoneFactor() {
    method getMessage (line 30) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/HotpInfo.java
  class HotpInfo (line 12) | public class HotpInfo extends OtpInfo {
    method HotpInfo (line 18) | public HotpInfo(byte[] secret, long counter) throws OtpInfoException {
    method HotpInfo (line 23) | public HotpInfo(byte[] secret) throws OtpInfoException {
    method HotpInfo (line 27) | public HotpInfo(byte[] secret, String algorithm, int digits, long coun...
    method getOtp (line 32) | @Override
    method getTypeId (line 44) | @Override
    method toJson (line 49) | @Override
    method getCounter (line 60) | public long getCounter() {
    method isCounterValid (line 64) | public static boolean isCounterValid(long counter) {
    method setCounter (line 68) | public void setCounter(long counter) throws OtpInfoException {
    method incrementCounter (line 75) | public void incrementCounter() throws OtpInfoException {
    method equals (line 79) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/MotpInfo.java
  class MotpInfo (line 14) | public class MotpInfo extends TotpInfo {
    method MotpInfo (line 24) | public MotpInfo(@NonNull byte[] secret) throws OtpInfoException {
    method MotpInfo (line 28) | public MotpInfo(byte[] secret, String pin) throws OtpInfoException {
    method getOtp (line 33) | @Override
    method getTypeId (line 47) | @Override
    method toJson (line 52) | @Override
    method getPin (line 63) | @Nullable
    method setPin (line 68) | public void setPin(@NonNull String pin) {
    method equals (line 72) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java
  class OtpInfo (line 13) | public abstract class OtpInfo implements Serializable {
    method OtpInfo (line 21) | public OtpInfo(byte[] secret) throws OtpInfoException {
    method OtpInfo (line 25) | public OtpInfo(byte[] secret, String algorithm, int digits) throws Otp...
    method getOtp (line 31) | public abstract String getOtp() throws OtpInfoException;
    method checkSecret (line 33) | protected void checkSecret() throws OtpInfoException {
    method getTypeId (line 39) | public abstract String getTypeId();
    method getType (line 41) | public String getType() {
    method toJson (line 45) | public JSONObject toJson() {
    method getSecret (line 59) | public byte[] getSecret() {
    method getAlgorithm (line 63) | public String getAlgorithm(boolean java) {
    method getDigits (line 70) | public int getDigits() {
    method setSecret (line 74) | public void setSecret(byte[] secret) {
    method isAlgorithmValid (line 78) | public static boolean isAlgorithmValid(String algorithm) {
    method setAlgorithm (line 83) | public void setAlgorithm(String algorithm) throws OtpInfoException {
    method isDigitsValid (line 95) | public static boolean isDigitsValid(int digits) {
    method setDigits (line 100) | public void setDigits(int digits) throws OtpInfoException {
    method fromJson (line 107) | public static OtpInfo fromJson(String type, JSONObject obj) throws Otp...
    method equals (line 147) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfoException.java
  class OtpInfoException (line 3) | public class OtpInfoException extends Exception {
    method OtpInfoException (line 4) | public OtpInfoException(Throwable cause) {
    method OtpInfoException (line 8) | public OtpInfoException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/SteamInfo.java
  class SteamInfo (line 10) | public class SteamInfo extends TotpInfo {
    method SteamInfo (line 14) | public SteamInfo(byte[] secret) throws OtpInfoException {
    method SteamInfo (line 18) | public SteamInfo(byte[] secret, String algorithm, int digits, int peri...
    method getOtp (line 22) | @Override
    method getTypeId (line 34) | @Override
    method getType (line 39) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/TotpInfo.java
  class TotpInfo (line 12) | public class TotpInfo extends OtpInfo {
    method TotpInfo (line 18) | public TotpInfo(byte[] secret) throws OtpInfoException {
    method TotpInfo (line 23) | public TotpInfo(byte[] secret, String algorithm, int digits, int perio...
    method getOtp (line 28) | @Override
    method getOtp (line 33) | public String getOtp(long time) throws OtpInfoException {
    method getTypeId (line 44) | @Override
    method toJson (line 49) | @Override
    method getPeriod (line 60) | public int getPeriod() {
    method isPeriodValid (line 64) | public static boolean isPeriodValid(int period) {
    method setPeriod (line 73) | public void setPeriod(int period) throws OtpInfoException {
    method getMillisTillNextRotation (line 80) | public long getMillisTillNextRotation() {
    method getMillisTillNextRotation (line 84) | public static long getMillisTillNextRotation(int period) {
    method equals (line 89) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/Transferable.java
  type Transferable (line 5) | public interface Transferable {
    method getUri (line 6) | Uri getUri() throws GoogleAuthInfoException;

FILE: app/src/main/java/com/beemdevelopment/aegis/otp/YandexInfo.java
  class YandexInfo (line 18) | public class YandexInfo extends TotpInfo {
    method YandexInfo (line 30) | public YandexInfo(@NonNull byte[] secret) throws OtpInfoException {
    method YandexInfo (line 34) | public YandexInfo(@NonNull byte[] secret, @Nullable String pin) throws...
    method getOtp (line 40) | @Override
    method getPin (line 54) | @Nullable
    method setPin (line 59) | public void setPin(@NonNull String pin) {
    method getTypeId (line 63) | @Override
    method getType (line 68) | @Override
    method toJson (line 74) | @Override
    method equals (line 85) | @Override
    method parseSecret (line 95) | public static byte[] parseSecret(byte[] secret) throws OtpInfoException {
    method validateSecret (line 110) | public static void validateSecret(byte[] secret) throws OtpInfoExcepti...
    method getNumberOfLeadingZeros (line 164) | private static int getNumberOfLeadingZeros(char value) {

FILE: app/src/main/java/com/beemdevelopment/aegis/receivers/QsTileRefreshReceiver.java
  class QsTileRefreshReceiver (line 15) | public class QsTileRefreshReceiver extends BroadcastReceiver {
    method onReceive (line 16) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/receivers/VaultLockReceiver.java
  class VaultLockReceiver (line 15) | @AndroidEntryPoint
    method onReceive (line 23) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/services/LaunchAppTileService.java
  class LaunchAppTileService (line 14) | @RequiresApi(api = Build.VERSION_CODES.N)
    method onStartListening (line 17) | @Override
    method onClick (line 27) | @SuppressLint("StartActivityAndCollapseDeprecated")

FILE: app/src/main/java/com/beemdevelopment/aegis/services/LaunchScannerTileService.java
  class LaunchScannerTileService (line 14) | @RequiresApi(api = Build.VERSION_CODES.N)
    method onStartListening (line 17) | @Override
    method onClick (line 27) | @SuppressLint("StartActivityAndCollapseDeprecated")

FILE: app/src/main/java/com/beemdevelopment/aegis/services/NotificationService.java
  class NotificationService (line 17) | public class NotificationService extends Service {
    method onStartCommand (line 22) | @Override
    method serviceMethod (line 29) | @SuppressLint("LaunchActivityFromNotification")
    method onDestroy (line 49) | @Override
    method onTaskRemoved (line 56) | @Override
    method onBind (line 62) | @Nullable

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/AboutActivity.java
  class AboutActivity (line 27) | public class AboutActivity extends AegisActivity {
    method onCreate (line 37) | @Override
    method getCurrentAppVersion (line 111) | private static String getCurrentAppVersion() {
    method openUrl (line 119) | private void openUrl(String url) {
    method copyToClipboard (line 127) | private void copyToClipboard(String text, @StringRes int messageId) {
    method openMail (line 134) | private void openMail(String mailaddress) {
    method getThemeColorAsHex (line 143) | private String getThemeColorAsHex(@AttrRes int attributeId) {
    method onOptionsItemSelected (line 148) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java
  class AegisActivity (line 44) | @AndroidEntryPoint
    method onCreate (line 60) | @Override
    method onDestroy (line 80) | @Override
    method onResume (line 87) | @CallSuper
    method onLocked (line 94) | @SuppressLint("SoonBlockedPrivateApi")
    method onSetTheme (line 116) | protected void onSetTheme() {
    method setLocale (line 120) | protected void setLocale(Locale locale) {
    method saveVault (line 129) | protected boolean saveVault() {
    method saveAndBackupVault (line 139) | protected boolean saveAndBackupVault() {
    method abortIfOrphan (line 154) | protected boolean abortIfOrphan(Bundle savedInstanceState) {
    method onSupportActionModeStarted (line 166) | @Override
    method onSupportActionModeFinished (line 172) | @Override
    class ActionModeStatusGuardHack (line 186) | private class ActionModeStatusGuardHack {
      method ActionModeStatusGuardHack (line 191) | private ActionModeStatusGuardHack() {
      method apply (line 201) | private void apply(int visibility) {
    method isOrphan (line 243) | private boolean isOrphan() {
    type PrefEntryPoint (line 250) | @EarlyEntryPoint
      method getPreferences (line 253) | Preferences getPreferences();

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/AssignIconsActivity.java
  class AssignIconsActivity (line 48) | public class AssignIconsActivity extends AegisActivity implements Assign...
    method onCreate (line 56) | @Override
    method findSuggestedIcon (line 116) | private IconPack.Icon findSuggestedIcon(AssignIconEntry entry) {
    method saveAndFinish (line 125) | private void saveAndFinish() throws IOException {
    method discardAndFinish (line 152) | private void discardAndFinish() {
    method onCreateOptionsMenu (line 164) | @Override
    method onOptionsItemSelected (line 170) | @Override
    method onAssignIconEntryClick (line 188) | @Override
    method onSetPreloadView (line 206) | @Override
    class BackPressHandler (line 211) | private class BackPressHandler extends OnBackPressedCallback {
      method BackPressHandler (line 212) | public BackPressHandler() {
      method handleOnBackPressed (line 216) | @Override
    class EntryIconPreloadProvider (line 222) | private class EntryIconPreloadProvider implements ListPreloader.Preloa...
      method getPreloadItems (line 223) | @NonNull
      method getPreloadRequestBuilder (line 233) | @Nullable
    class IconPreloadProvider (line 242) | private class IconPreloadProvider implements ListPreloader.PreloadMode...
      method getPreloadItems (line 243) | @NonNull
      method getPreloadRequestBuilder (line 253) | @Nullable
    class SpacesItemDecoration (line 262) | private class SpacesItemDecoration extends RecyclerView.ItemDecoration {
      method SpacesItemDecoration (line 265) | public SpacesItemDecoration(int dpSpace) {
      method getItemOffsets (line 270) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java
  class AuthActivity (line 52) | public class AuthActivity extends AegisActivity {
    method onCreate (line 72) | @Override
    method onSaveInstanceState (line 197) | @Override
    method selectPassword (line 203) | private void selectPassword() {
    method onResume (line 210) | @Override
    method onPause (line 226) | @Override
    method onAttachedToWindow (line 236) | @Override
    method focusPasswordField (line 243) | private void focusPasswordField() {
    method showPasswordReminder (line 248) | private void showPasswordReminder() {
    method showBiometricPrompt (line 270) | public BiometricPrompt showBiometricPrompt() {
    method finish (line 295) | private void finish(MasterKey key, boolean isSlotRepaired) {
    method onInvalidPassword (line 313) | private void onInvalidPassword() {
    class BackPressHandler (line 329) | private class BackPressHandler extends OnBackPressedCallback {
      method BackPressHandler (line 330) | public BackPressHandler() {
      method handleOnBackPressed (line 334) | @Override
    class PasswordDerivationListener (line 343) | private class PasswordDerivationListener implements PasswordSlotDecryp...
      method onTaskFinished (line 344) | @Override
    class BiometricPromptListener (line 366) | private class BiometricPromptListener extends BiometricPrompt.Authenti...
      method onAuthenticationError (line 367) | @Override
      method onAuthenticationSucceeded (line 378) | @Override
      method onAuthenticationFailed (line 397) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java
  class EditEntryActivity (line 100) | public class EditEntryActivity extends AegisActivity {
    method onCreate (line 164) | @Override
    method showGroupSelectionDialog (line 384) | private void showGroupSelectionDialog() {
    method addChipTo (line 440) | private void addChipTo(ChipGroup chipGroup, VaultGroupModel group, Boo...
    method getCheckedUUID (line 451) | private static Set<UUID> getCheckedUUID(ChipGroup chipGroup) {
    method getCheckedNames (line 461) | private static String getCheckedNames(ChipGroup chipGroup) {
    method updateAdvancedFieldStatus (line 471) | private void updateAdvancedFieldStatus(String otpType) {
    method updatePinFieldVisibility (line 479) | private void updatePinFieldVisibility(String otpType) {
    method openAdvancedSettings (line 485) | private void openAdvancedSettings() {
    method hasUnsavedChanges (line 501) | private boolean hasUnsavedChanges(VaultEntry newEntry) {
    method discardAndFinish (line 505) | private void discardAndFinish() {
    method onOptionsItemSelected (line 534) | @Override
    method startImageSelectionActivity (line 568) | private void startImageSelectionActivity() {
    method resetUsageCount (line 580) | private void resetUsageCount() {
    method startIconSelection (line 585) | private void startIconSelection() {
    method selectIcon (line 608) | private void selectIcon(IconPack.Icon icon) {
    method startEditingIcon (line 616) | private void startEditingIcon(Uri data) {
    method stopEditingIcon (line 643) | private void stopEditingIcon(boolean save) {
    method onCreateOptionsMenu (line 655) | @Override
    method addAndFinish (line 668) | private void addAndFinish(VaultEntry entry) {
    method setLastUsedTimestamp (line 683) | private void setLastUsedTimestamp(long timestamp) {
    method deleteAndFinish (line 693) | private void deleteAndFinish(VaultEntry entry) {
    method saveAndFinish (line 698) | private void saveAndFinish(VaultEntry entry, boolean delete) {
    method parsePeriod (line 709) | private int parsePeriod() throws ParseException {
    method parseEntry (line 717) | private VaultEntry parseEntry() throws ParseException {
    method onSaveError (line 836) | private void onSaveError(String msg) {
    method onSave (line 845) | private boolean onSave() {
    method showDuplicateBottomSheet (line 871) | private void showDuplicateBottomSheet(VaultEntry newEntry) {
    method setViewEnabled (line 944) | private static void setViewEnabled(View view, boolean enabled) {
    method updateBackPressHandlerState (line 966) | private void updateBackPressHandlerState() {
    class BackPressHandler (line 978) | private class BackPressHandler extends OnBackPressedCallback {
      method BackPressHandler (line 979) | public BackPressHandler() {
      method handleOnBackPressed (line 983) | @Override
    class IconBackPressHandler (line 989) | private class IconBackPressHandler extends OnBackPressedCallback {
      method IconBackPressHandler (line 990) | public IconBackPressHandler() {
      method handleOnBackPressed (line 994) | @Override
    class ParseException (line 1000) | private static class ParseException extends Exception {
      method ParseException (line 1001) | public ParseException(String message) {
    class CustomSvgIcon (line 1006) | private static class CustomSvgIcon extends IconPack.Icon {
      method CustomSvgIcon (line 1009) | protected CustomSvgIcon(File file) {
      method getFile (line 1014) | @Nullable
      method getIconType (line 1020) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/ExitActivity.java
  class ExitActivity (line 8) | public class ExitActivity extends Activity {
    method onCreate (line 10) | @Override
    method exitAppAndRemoveFromRecents (line 17) | public static void exitAppAndRemoveFromRecents(Context context) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/GroupManagerActivity.java
  class GroupManagerActivity (line 28) | public class GroupManagerActivity extends AegisActivity implements Group...
    method onCreate (line 35) | @Override
    method onSaveInstanceState (line 102) | @Override
    method onEditGroup (line 113) | @Override
    method onRemoveGroup (line 128) | @Override
    method onRemoveUnusedGroups (line 144) | public void onRemoveUnusedGroups() {
    method saveAndFinish (line 164) | private void saveAndFinish() {
    method discardAndFinish (line 177) | private void discardAndFinish() {
    method onCreateOptionsMenu (line 188) | @Override
    method onOptionsItemSelected (line 194) | @Override
    method updateEmptyState (line 210) | private void updateEmptyState() {
    class BackPressHandler (line 220) | private class BackPressHandler extends OnBackPressedCallback {
      method BackPressHandler (line 221) | public BackPressHandler() {
      method handleOnBackPressed (line 225) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/ImportEntriesActivity.java
  class ImportEntriesActivity (line 52) | public class ImportEntriesActivity extends AegisActivity {
    method onCreate (line 61) | @Override
    method startImport (line 107) | private void startImport(DatabaseImporter.Definition importerDef, @Nul...
    method startImportFile (line 131) | private void startImportFile(@NonNull DatabaseImporter importer, @NonN...
    method startImportApp (line 143) | private void startImportApp(@NonNull DatabaseImporter importer) {
    method processImporterState (line 176) | private void processImporterState(DatabaseImporter.State state) {
    method processDecryptedImporterState (line 205) | private void processDecryptedImporterState(DatabaseImporter.State stat...
    method processImporterResult (line 235) | private void processImporterResult(DatabaseImporter.Result result) {
    method showWipeEntriesDialog (line 254) | private void showWipeEntriesDialog() {
    method saveAndFinish (line 262) | private void saveAndFinish(boolean wipeEntries) {
    method findDuplicates (line 344) | private void findDuplicates(List<ImportEntry> importEntries) {
    method onCreateOptionsMenu (line 396) | @Override
    method onOptionsItemSelected (line 403) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/IntroActivity.java
  class IntroActivity (line 30) | public class IntroActivity extends IntroBaseActivity {
    method onCreate (line 34) | @Override
    method onBeforeSlideChanged (line 44) | @Override
    method onAfterSlideChanged (line 72) | @Override
    method onDonePressed (line 85) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/LicensesActivity.java
  class LicensesActivity (line 19) | public class LicensesActivity extends LibsActivity {
    method onCreate (line 20) | @Override
    type PrefEntryPoint (line 35) | @EarlyEntryPoint
      method getPreferences (line 38) | Preferences getPreferences();

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java
  class MainActivity (line 99) | public class MainActivity extends AegisActivity implements EntryListView...
    method onCreate (line 192) | @Override
    method setGroups (line 266) | public void setGroups(Collection<VaultGroup> groups) {
    method initializeGroups (line 289) | private void initializeGroups() {
    method cleanGroupFilter (line 302) | private Set<UUID> cleanGroupFilter(Set<UUID> groupFilter) {
    method addChipTo (line 310) | private void addChipTo(ChipGroup chipGroup, VaultGroupModel group) {
    method addSaveChip (line 354) | private void addSaveChip(ChipGroup chipGroup) {
    method setSaveChipVisibility (line 373) | private void setSaveChipVisibility(boolean visible) {
    method getGroupFilter (line 379) | private static Set<UUID> getGroupFilter(ChipGroup chipGroup) {
    method onDestroy (line 395) | @Override
    method onPause (line 401) | @Override
    method onSaveInstanceState (line 416) | @Override
    method onRequestPermissionsResult (line 429) | @Override
    method onKeyDown (line 443) | @Override
    method isDPadKey (line 449) | private static boolean isDPadKey(int keyCode) {
    method onEntryListTouch (line 453) | @Override
    method onPreferencesResult (line 467) | private void onPreferencesResult() {
    method startEditEntryActivity (line 474) | private void startEditEntryActivity() {
    method startEditEntryActivityForNew (line 502) | private void startEditEntryActivityForNew(VaultEntry entry) {
    method startEditEntryActivityForManual (line 509) | private void startEditEntryActivityForManual() {
    method startEditEntryActivity (line 516) | private void startEditEntryActivity(VaultEntry entry) {
    method startAssignIconsActivity (line 522) | private void startAssignIconsActivity(List<VaultEntry> entries) {
    method startAssignGroupsDialog (line 533) | private void startAssignGroupsDialog() {
    method startIntroActivity (line 603) | private void startIntroActivity() {
    method onScanResult (line 611) | private void onScanResult(Intent data) {
    method onAddEntryResult (line 618) | private void onAddEntryResult(Intent data) {
    method onEditEntryResult (line 627) | private void onEditEntryResult() {
    method onAssignIconsResult (line 633) | private void onAssignIconsResult() {
    method onScanImageResult (line 639) | private void onScanImageResult(Intent intent) {
    method buildImportError (line 662) | private static CharSequence buildImportError(String fileName, Throwabl...
    method startDecodeQrCodeImages (line 668) | private void startDecodeQrCodeImages(List<Uri> uris) {
    method importScannedEntries (line 729) | private void importScannedEntries(List<VaultEntry> entries) {
    method updateSortCategoryMenu (line 745) | private void updateSortCategoryMenu() {
    method onIntroResult (line 752) | private void onIntroResult() {
    method checkTimeSyncSetting (line 756) | private void checkTimeSyncSetting() {
    method checkIconOptimization (line 766) | private void checkIconOptimization() {
    method onIconsOptimized (line 783) | private void onIconsOptimized(Map<UUID, VaultEntryIcon> newIcons) {
    method onDecryptResult (line 797) | private void onDecryptResult() {
    method startScanActivity (line 803) | private void startScanActivity() {
    method startScanImageActivity (line 812) | private void startScanImageActivity() {
    method startPreferencesActivity (line 826) | private void startPreferencesActivity() {
    method startPreferencesActivity (line 830) | private void startPreferencesActivity(Class<? extends PreferencesFragm...
    method doShortcutActions (line 837) | private void doShortcutActions() {
    method handleIncomingIntent (line 853) | private void handleIncomingIntent() {
    method onStop (line 931) | @Override
    method onStart (line 938) | @Override
    method onCreateOptionsMenu (line 1010) | @Override
    method onOptionsItemSelected (line 1085) | @Override
    method collapseSearchView (line 1127) | private void collapseSearchView() {
    method loadEntries (line 1133) | private void loadEntries() {
    method startAuthActivity (line 1146) | private void startAuthActivity(boolean inhibitBioPrompt) {
    method updateLockIcon (line 1155) | private void updateLockIcon() {
    method updateErrorCard (line 1163) | private void updateErrorCard() {
    method showPlaintextExportWarningOptions (line 1199) | private void showPlaintextExportWarningOptions() {
    method onRestoreInstanceState (line 1229) | @Override
    method onEntryClick (line 1242) | @Override
    method onSelect (line 1254) | @Override
    method onDeselect (line 1259) | @Override
    method setIsMultipleSelected (line 1264) | private void setIsMultipleSelected(boolean multipleSelected) {
    method setAssignIconsMenuItemVisibility (line 1270) | private void setAssignIconsMenuItemVisibility() {
    method setFavoriteMenuItemVisiblity (line 1275) | private void setFavoriteMenuItemVisiblity() {
    method onLongEntryClick (line 1292) | @Override
    method startActionMode (line 1303) | private void startActionMode() {
    method onEntryMove (line 1310) | @Override
    method onEntryDrop (line 1315) | @Override
    method onEntryChange (line 1320) | @Override
    method onEntryCopy (line 1325) | public void onEntryCopy(VaultEntry entry) {
    method onScroll (line 1329) | @Override
    method onListChange (line 1336) | @Override
    method onSaveGroupFilter (line 1339) | @Override
    method onLocked (line 1347) | @Override
    method saveAndBackupVault (line 1369) | @Override
    method copyEntryCode (line 1376) | @SuppressLint("InlinedApi")
    class SearchViewBackPressHandler (line 1398) | private class SearchViewBackPressHandler extends OnBackPressedCallback {
      method SearchViewBackPressHandler (line 1399) | public SearchViewBackPressHandler() {
      method handleOnBackPressed (line 1403) | @Override
    class LockBackPressHandler (line 1417) | private class LockBackPressHandler extends OnBackPressedCallback {
      method LockBackPressHandler (line 1418) | public LockBackPressHandler() {
      method handleOnBackPressed (line 1422) | @Override
    class ActionModeBackPressHandler (line 1430) | private class ActionModeBackPressHandler extends OnBackPressedCallback {
      method ActionModeBackPressHandler (line 1431) | public ActionModeBackPressHandler() {
      method handleOnBackPressed (line 1435) | @Override
    class FabMenuBackPressHandler (line 1443) | private class FabMenuBackPressHandler extends OnBackPressedCallback {
      method FabMenuBackPressHandler (line 1444) | public FabMenuBackPressHandler() {
      method handleOnBackPressed (line 1448) | @Override
    class ActionModeCallbacks (line 1456) | private class ActionModeCallbacks implements ActionMode.Callback {
      method onCreateActionMode (line 1457) | @Override
      method onPrepareActionMode (line 1464) | @Override
      method onActionItemClicked (line 1469) | @Override
      method onDestroyActionMode (line 1533) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/PanicResponderActivity.java
  class PanicResponderActivity (line 15) | public class PanicResponderActivity extends AegisActivity {
    method onCreate (line 18) | @Override
    method finishApp (line 49) | private void finishApp() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesActivity.java
  class PreferencesActivity (line 18) | public class PreferencesActivity extends AegisActivity implements
    method onCreate (line 23) | @Override
    method onSaveInstanceState (line 62) | @Override
    method onOptionsItemSelected (line 68) | @Override
    method onPreferenceStartFragment (line 79) | @Override
    method showFragment (line 91) | private void showFragment(Fragment fragment) {
    method getRequestedFragment (line 99) | @SuppressWarnings("unchecked")
    class FragmentResumeListener (line 113) | private class FragmentResumeListener extends FragmentManager.FragmentL...
      method onFragmentStarted (line 114) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java
  class ScannerActivity (line 36) | public class ScannerActivity extends AegisActivity implements QrCodeAnal...
    method onCreate (line 52) | @Override
    method onDestroy (line 91) | @Override
    method onCreateOptionsMenu (line 99) | @Override
    method onOptionsItemSelected (line 106) | @Override
    method addCamera (line 123) | private void addCamera(int lens) {
    method updateCameraIcon (line 134) | private void updateCameraIcon() {
    method bindPreview (line 152) | private void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
    method unbindPreview (line 169) | private void unbindPreview(@NonNull ProcessCameraProvider cameraProvid...
    method onQrCodeDetected (line 174) | @Override
    method handleUri (line 202) | private void handleUri(Uri uri) throws GoogleAuthInfoException {
    method handleExportUri (line 209) | private void handleExportUri(Uri uri) throws GoogleAuthInfoException {
    method finish (line 236) | private void finish(List<VaultEntry> entries) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/TransferEntriesActivity.java
  class TransferEntriesActivity (line 40) | public class TransferEntriesActivity extends AegisActivity {
    method onCreate (line 54) | @Override
    method getSystemBrightness (line 165) | private float getSystemBrightness() {
    method setBrightness (line 176) | private void setBrightness(float brightnessAmount) {
    method onOptionsItemSelected (line 182) | @Override
    method generateQR (line 195) | private void generateQR() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/components/DropdownCheckBoxes.java
  class DropdownCheckBoxes (line 26) | public class DropdownCheckBoxes<T> extends AppCompatAutoCompleteTextView {
    method DropdownCheckBoxes (line 37) | public DropdownCheckBoxes(Context context) {
    method DropdownCheckBoxes (line 42) | public DropdownCheckBoxes(Context context, AttributeSet attrs) {
    method DropdownCheckBoxes (line 47) | public DropdownCheckBoxes(Context context, AttributeSet attrs, int def...
    method initialise (line 52) | private void initialise(Context context, AttributeSet attrs) {
    method addItems (line 81) | public void addItems(List<T> items, boolean startChecked) {
    method updateCheckedItemsCountText (line 93) | private void updateCheckedItemsCountText() {
    method setCheckedItemsCountTextRes (line 104) | public void setCheckedItemsCountTextRes(@PluralsRes int resId) {
    method getCheckedItems (line 108) | public Set<T> getCheckedItems() {
    class CheckboxAdapter (line 112) | private class CheckboxAdapter extends BaseAdapter implements Filterable {
      method getCount (line 114) | @Override
      method getItem (line 119) | @Override
      method getItemId (line 124) | @Override
      method getView (line 129) | @Override
      method getFilter (line 155) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/components/NoAutofillEditText.java
  class NoAutofillEditText (line 13) | public class NoAutofillEditText extends TextInputEditText {
    method NoAutofillEditText (line 15) | public NoAutofillEditText(@NonNull Context context) {
    method NoAutofillEditText (line 19) | public NoAutofillEditText(@NonNull Context context, @Nullable Attribut...
    method NoAutofillEditText (line 23) | public NoAutofillEditText(@NonNull Context context, @Nullable Attribut...
    method getAutofillType (line 27) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/ChangelogDialog.java
  class ChangelogDialog (line 7) | public class ChangelogDialog extends SimpleWebViewDialog {
    method ChangelogDialog (line 8) | public ChangelogDialog() {
    method create (line 12) | public static ChangelogDialog create() {
    method getContent (line 16) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/Dialogs.java
  class Dialogs (line 55) | public class Dialogs {
    method Dialogs (line 56) | private Dialogs() {
    method secureDialog (line 60) | public static void secureDialog(Dialog dialog) {
    method showSecureDialog (line 66) | public static void showSecureDialog(Dialog dialog) {
    method showDeleteEntriesDialog (line 71) | public static void showDeleteEntriesDialog(Context context, List<Vault...
    method getVaultEntryName (line 99) | private static String getVaultEntryName(Context context, VaultEntry en...
    method showDiscardDialog (line 111) | public static void showDiscardDialog(Context context, DialogInterface....
    method showSetPasswordDialog (line 121) | public static void showSetPasswordDialog(ComponentActivity activity, P...
    method showTextInputDialog (line 194) | private static void showTextInputDialog(Context context, @StringRes in...
    method showTextInputDialog (line 242) | public static void showTextInputDialog(Context context, @StringRes int...
    method showTextInputDialog (line 246) | private static void showTextInputDialog(Context context, @StringRes in...
    method showTextInputDialog (line 250) | public static void showTextInputDialog(Context context, @StringRes int...
    method showPasswordInputDialog (line 254) | public static void showPasswordInputDialog(Context context, TextInputL...
    method showPasswordInputDialog (line 258) | public static void showPasswordInputDialog(Context context, TextInputL...
    method showPasswordInputDialog (line 262) | public static void showPasswordInputDialog(Context context, @StringRes...
    method showPasswordInputDialog (line 266) | public static void showPasswordInputDialog(Context context, @StringRes...
    method showPasswordInputDialog (line 270) | public static void showPasswordInputDialog(Context context, @StringRes...
    method showCheckboxDialog (line 274) | public static void showCheckboxDialog(Context context, @StringRes int ...
    method showTapToRevealTimeoutPickerDialog (line 305) | public static void showTapToRevealTimeoutPickerDialog(Context context,...
    method showBackupVersionsPickerDialog (line 323) | public static void showBackupVersionsPickerDialog(Context context, int...
    method showErrorDialog (line 355) | public static void showErrorDialog(Context context, @StringRes int mes...
    method showErrorDialog (line 359) | public static void showErrorDialog(Context context, String message, Ex...
    method showErrorDialog (line 363) | public static void showErrorDialog(Context context, @StringRes int mes...
    method showErrorDialog (line 367) | public static void showErrorDialog(Context context, @StringRes int mes...
    method showErrorDialog (line 371) | public static void showErrorDialog(Context context, String message, Ex...
    method showErrorDialog (line 375) | public static void showErrorDialog(Context context, @StringRes int mes...
    method showErrorDialog (line 379) | public static void showErrorDialog(Context context, String message, Ch...
    method showBackupErrorDialog (line 420) | public static void showBackupErrorDialog(Context context, Preferences....
    method showMultiErrorDialog (line 427) | public static void showMultiErrorDialog(
    method showMultiExceptionDialog (line 445) | public static <T extends Throwable> void showMultiExceptionDialog(
    method showDetailedMultiErrorDialog (line 455) | private static void showDetailedMultiErrorDialog(
    method showTimeSyncWarningDialog (line 489) | public static void showTimeSyncWarningDialog(Context context, Dialog.O...
    method showImportersDialog (line 515) | public static void showImportersDialog(Context context, boolean isDire...
    method showPartialGoogleAuthImportWarningDialog (line 542) | public static void showPartialGoogleAuthImportWarningDialog(Context co...
    method showBackupsVersioningStrategy (line 583) | public static void showBackupsVersioningStrategy(Context context, Back...
    method setImporterHelpText (line 631) | private static void setImporterHelpText(TextView view, DatabaseImporte...
    type CheckboxInputListener (line 639) | public interface CheckboxInputListener {
      method onCheckboxInputResult (line 640) | void onCheckboxInputResult(boolean checkbox);
    type NumberInputListener (line 643) | public interface NumberInputListener {
      method onNumberInputResult (line 644) | void onNumberInputResult(int number);
    type TextInputListener (line 647) | public interface TextInputListener {
      method onTextInputResult (line 648) | void onTextInputResult(char[] text);
    type PasswordSlotListener (line 651) | public interface PasswordSlotListener {
      method onSlotResult (line 652) | void onSlotResult(PasswordSlot slot, Cipher cipher);
      method onException (line 653) | void onException(Exception e);
    type ImporterListener (line 656) | public interface ImporterListener {
      method onImporterSelectionResult (line 657) | void onImporterSelectionResult(DatabaseImporter.Definition definition);
    type BackupsVersioningStrategyListener (line 660) | public interface BackupsVersioningStrategyListener {
      method onStrategySelectionResult (line 661) | void onStrategySelectionResult(BackupsVersioningStrategy strategy);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/IconPickerDialog.java
  class IconPickerDialog (line 37) | public class IconPickerDialog {
    method IconPickerDialog (line 38) | private IconPickerDialog() {
    method create (line 42) | public static BottomSheetDialog create(Activity activity, List<IconPac...

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/LicenseDialog.java
  class LicenseDialog (line 7) | public class LicenseDialog extends SimpleWebViewDialog {
    method LicenseDialog (line 8) | public LicenseDialog() {
    method create (line 12) | public static LicenseDialog create() {
    method getContent (line 16) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/SimpleWebViewDialog.java
  class SimpleWebViewDialog (line 29) | public abstract class SimpleWebViewDialog extends DialogFragment {
    method SimpleWebViewDialog (line 33) | protected SimpleWebViewDialog(@StringRes int title) {
    method getContent (line 37) | protected abstract String getContent(Context context);
    method onCreateDialog (line 39) | @SuppressLint("InflateParams")
    method setTheme (line 67) | public SimpleWebViewDialog setTheme(Theme theme) {
    method getBackgroundColor (line 72) | protected String getBackgroundColor() {
    method getTextColor (line 81) | protected String getTextColor() {
    method colorToCSS (line 90) | @SuppressLint("DefaultLocale")
    method readAssetAsString (line 95) | protected static String readAssetAsString(Context context, String name) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AppearancePreferencesFragment.java
  class AppearancePreferencesFragment (line 23) | public class AppearancePreferencesFragment extends PreferencesFragment {
    method onCreatePreferences (line 28) | @Override
    method refreshAccountNamePositionText (line 176) | private void refreshAccountNamePositionText() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AuditLogPreferencesFragment.java
  class AuditLogPreferencesFragment (line 33) | @AndroidEntryPoint
    method AuditLogPreferencesFragment (line 47) | public AuditLogPreferencesFragment() {
    method onViewCreated (line 51) | @Override
    class SpacesItemDecoration (line 93) | private class SpacesItemDecoration extends RecyclerView.ItemDecoration {
      method SpacesItemDecoration (line 96) | public SpacesItemDecoration(int dpSpace) {
      method getItemOffsets (line 100) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BackupsPreferencesFragment.java
  class BackupsPreferencesFragment (line 28) | public class BackupsPreferencesFragment extends PreferencesFragment {
    method onResume (line 50) | @Override
    method onCreatePreferences (line 56) | @Override
    method saveAndDisableBackupReminder (line 172) | private void saveAndDisableBackupReminder(boolean understand) {
    method onSelectBackupsLocationResult (line 179) | private void onSelectBackupsLocationResult(int resultCode, Intent data) {
    method updateBackupPreference (line 196) | private void updateBackupPreference() {
    method updateBackupStatus (line 221) | private void updateBackupStatus(Preference pref, Preferences.BackupRes...
    method getBackupStatusMessage (line 236) | private CharSequence getBackupStatusMessage(@Nullable Preferences.Back...
    method createBackupFile (line 255) | private void createBackupFile() {
    method selectBackupsLocation (line 263) | private void selectBackupsLocation() {
    method scheduleBackup (line 273) | private void scheduleBackup() {
    method updateBackupsVersioningStrategySummary (line 283) | private void updateBackupsVersioningStrategySummary() {
    method updateBackupsLocationSummary (line 292) | private void updateBackupsLocationSummary() {
    method updateBackupsVersionsSummary (line 307) | private void updateBackupsVersionsSummary() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BehaviorPreferencesFragment.java
  class BehaviorPreferencesFragment (line 15) | public class BehaviorPreferencesFragment extends PreferencesFragment {
    method onCreatePreferences (line 17) | @Override
    method getSearchBehaviorSummary (line 96) | private String getSearchBehaviorSummary() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/IconPacksManagerFragment.java
  class IconPacksManagerFragment (line 43) | @AndroidEntryPoint
    method IconPacksManagerFragment (line 64) | public IconPacksManagerFragment() {
    method onViewCreated (line 68) | @Override
    method onCreateAnimation (line 110) | @Override
    method onRemoveIconPack (line 120) | @Override
    method importIconPack (line 133) | private void importIconPack(Uri uri) {
    method removeIconPack (line 158) | private boolean removeIconPack(IconPack pack) {
    method startImportIconPack (line 172) | private void startImportIconPack() {
    method updateEmptyState (line 178) | private void updateEmptyState() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java
  class ImportExportPreferencesFragment (line 68) | public class ImportExportPreferencesFragment extends PreferencesFragment {
    method onCreatePreferences (line 97) | @Override
    method onSaveInstanceState (line 138) | @Override
    method onImportSelectResult (line 144) | private void onImportSelectResult(int resultCode, Intent data) {
    method startImportEntriesActivity (line 161) | private void startImportEntriesActivity(DatabaseImporter.Definition im...
    method startExport (line 168) | private void startExport() {
    method getVaultEntryFilter (line 335) | private Vault.EntryFilter getVaultEntryFilter(DropdownCheckBoxes<Vault...
    method startGoogleAuthenticatorStyleExport (line 350) | private void startGoogleAuthenticatorStyleExport() {
    method getExportRequestCode (line 393) | private static int getExportRequestCode(int spinnerPos, boolean encryp...
    method getExportRequestLauncher (line 403) | private ActivityResultLauncher<Intent> getExportRequestLauncher(int sp...
    method getExportFileInfo (line 413) | private static VaultBackupManager.FileInfo getExportFileInfo(int spinn...
    method getExportMimeType (line 424) | private static String getExportMimeType(int requestCode) {
    method getExportCacheDir (line 433) | private File getExportCacheDir() throws IOException {
    method startExportVault (line 442) | private void startExportVault(int requestCode, StartExportCallback cb,...
    method onExportResult (line 505) | private void onExportResult(int requestCode, int resultCode, @Nullable...
    method getStringResourceIndex (line 540) | private int getStringResourceIndex(@ArrayRes int id, String string) {
    class ExportResultListener (line 550) | private class ExportResultListener implements ExportTask.Callback {
      method onTaskFinished (line 551) | @Override
    type FinishExportCallback (line 565) | private interface FinishExportCallback {
      method exportVault (line 566) | void exportVault(OutputStream stream) throws IOException, VaultRepos...
    type StartExportCallback (line 569) | private interface StartExportCallback {
      method exportVault (line 570) | void exportVault(FinishExportCallback exportCb);
    type DialogStateValidator (line 573) | private interface DialogStateValidator {
      method enableIfValid (line 574) | void enableIfValid();

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/MainPreferencesFragment.java
  class MainPreferencesFragment (line 7) | public class MainPreferencesFragment extends PreferencesFragment {
    method onCreatePreferences (line 8) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/PreferencesFragment.java
  class PreferencesFragment (line 31) | @AndroidEntryPoint
    method onResume (line 48) | @Override
    method onCreateAnimation (line 61) | @Override
    method onCreateRecyclerView (line 71) | @NonNull
    method saveAndBackupVault (line 88) | protected boolean saveAndBackupVault() {
    method requirePreference (line 100) | @NonNull

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java
  class SecurityPreferencesFragment (line 40) | public class SecurityPreferencesFragment extends PreferencesFragment {
    method onResume (line 50) | @Override
    method onCreatePreferences (line 56) | @Override
    method updateEncryptionPreferences (line 258) | private void updateEncryptionPreferences() {
    method getPasswordReminderSummary (line 290) | private String getPasswordReminderSummary() {
    method getAutoLockSummary (line 300) | private String getAutoLockSummary() {
    class SetPasswordListener (line 322) | private class SetPasswordListener implements Dialogs.PasswordSlotListe...
      method onSlotResult (line 323) | @Override
      method onException (line 354) | @Override
    class SetBackupPasswordListener (line 362) | private class SetBackupPasswordListener implements Dialogs.PasswordSlo...
      method onSlotResult (line 363) | @Override
      method onException (line 391) | @Override
    class RegisterBiometricsListener (line 399) | private class RegisterBiometricsListener implements BiometricSlotIniti...
      method onInitializeSlot (line 400) | @Override
      method onSlotInitializationFailed (line 417) | @Override
    class EnableEncryptionListener (line 425) | private class EnableEncryptionListener implements Dialogs.PasswordSlot...
      method onSlotResult (line 426) | @Override
      method onException (line 443) | @Override
    class PasswordConfirmationListener (line 450) | private class PasswordConfirmationListener implements PasswordSlotDecr...
      method onTaskFinished (line 451) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/glide/AegisGlideModule.java
  class AegisGlideModule (line 19) | @GlideModule
    method registerComponents (line 21) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/glide/GlideHelper.java
  class GlideHelper (line 26) | public class GlideHelper {
    method GlideHelper (line 27) | private GlideHelper() {
    method loadIconFile (line 31) | public static void loadIconFile(RequestManager rm, File file, IconType...
    method loadIcon (line 35) | public static void loadIcon(RequestManager rm, IconPack.Icon icon, Ima...
    method loadEntryIcon (line 39) | public static void loadEntryIcon(RequestManager rm, VaultEntry entry, ...
    method load (line 53) | private static void load(RequestBuilder<Drawable> rb, IconType iconTyp...
    method setCommonOptions (line 57) | public static RequestBuilder<Drawable> setCommonOptions(RequestBuilder...
    method setLayerType (line 75) | private static void setLayerType(ImageView view, IconType iconType) {
    class ViewReadyListener (line 84) | private static class ViewReadyListener<T> implements RequestListener<T> {
      method ViewReadyListener (line 87) | public ViewReadyListener(Listener<T> listener) {
      method onLoadFailed (line 91) | @Override
      method onResourceReady (line 96) | @Override
      type Listener (line 107) | public interface Listener<T> {
        method onConfigureImageView (line 108) | void onConfigureImageView(ImageView targetView);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/glide/SvgBytesDecoder.java
  class SvgBytesDecoder (line 14) | public class SvgBytesDecoder implements ResourceDecoder<ByteBuffer, SVG> {
    method handles (line 17) | @Override
    method decode (line 24) | public Resource<SVG> decode(@NonNull ByteBuffer source, int width, int...

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/glide/SvgDecoder.java
  class SvgDecoder (line 21) | public class SvgDecoder implements ResourceDecoder<InputStream, SVG> {
    method handles (line 23) | @Override
    method decode (line 28) | public Resource<SVG> decode(

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/glide/SvgDrawableTranscoder.java
  class SvgDrawableTranscoder (line 20) | public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, Pi...
    method transcode (line 21) | @Nullable

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/glide/VaultEntryIconKey.java
  class VaultEntryIconKey (line 10) | public class VaultEntryIconKey implements Key {
    method VaultEntryIconKey (line 13) | public VaultEntryIconKey(VaultEntryIcon icon) {
    method updateDiskCacheKey (line 17) | @Override
    method equals (line 22) | @Override
    method hashCode (line 27) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/glide/VaultEntryIconLoader.java
  class VaultEntryIconLoader (line 18) | public class VaultEntryIconLoader implements ModelLoader<VaultEntryIcon,...
    method buildLoadData (line 21) | @Override
    method handles (line 26) | @Override
    class Fetcher (line 31) | public static class Fetcher implements DataFetcher<ByteBuffer> {
      method Fetcher (line 34) | private Fetcher(VaultEntryIcon icon) {
      method loadData (line 38) | @Override
      method cleanup (line 45) | @Override
      method cancel (line 50) | @Override
      method getDataClass (line 55) | @NonNull
      method getDataSource (line 61) | @NonNull
    class Factory (line 68) | public static class Factory implements ModelLoaderFactory<VaultEntryIc...
      method build (line 69) | @NonNull
      method teardown (line 75) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroActivityInterface.java
  type IntroActivityInterface (line 7) | public interface IntroActivityInterface {
    method goToNextSlide (line 11) | void goToNextSlide();
    method goToPreviousSlide (line 16) | void goToPreviousSlide();
    method skipToSlide (line 21) | void skipToSlide(Class<? extends SlideFragment> type);
    method getState (line 28) | @NonNull

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroBaseActivity.java
  class IntroBaseActivity (line 24) | public abstract class IntroBaseActivity extends AegisActivity implements...
    method onCreate (line 35) | @Override
    method onRestoreInstanceState (line 62) | @Override
    method onSaveInstanceState (line 69) | @Override
    method setCurrentSlide (line 75) | void setCurrentSlide(SlideFragment slide) {
    method goToNextSlide (line 79) | @Override
    method goToPreviousSlide (line 95) | @Override
    method skipToSlide (line 103) | @Override
    method onBeforeSlideChanged (line 121) | protected boolean onBeforeSlideChanged(@Nullable Class<? extends Slide...
    method onAfterSlideChanged (line 130) | protected void onAfterSlideChanged(@Nullable Class<? extends SlideFrag...
    method setPagerPosition (line 134) | private void setPagerPosition(int pos) {
    method setPagerPosition (line 149) | private void setPagerPosition(int pos, int delta) {
    method updatePagerControls (line 154) | private void updatePagerControls() {
    method getState (line 167) | @NonNull
    method onDonePressed (line 172) | protected abstract void onDonePressed();
    method addSlide (line 174) | public void addSlide(Class<? extends SlideFragment> type) {
    class BackPressHandler (line 190) | private class BackPressHandler extends OnBackPressedCallback {
      method BackPressHandler (line 191) | public BackPressHandler() {
      method handleOnBackPressed (line 195) | @Override
    class ScreenSlidePagerAdapter (line 201) | private class ScreenSlidePagerAdapter extends FragmentStateAdapter {
      method ScreenSlidePagerAdapter (line 202) | public ScreenSlidePagerAdapter(FragmentManager fm) {
      method createFragment (line 206) | @NonNull
      method getItemCount (line 218) | @Override
    class SlideSkipBlocker (line 224) | private class SlideSkipBlocker extends ViewPager2.OnPageChangeCallback {
      method onPageScrollStateChanged (line 225) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/intro/SlideFragment.java
  class SlideFragment (line 12) | public abstract class SlideFragment extends Fragment implements IntroAct...
    method onAttach (line 15) | @CallSuper
    method onResume (line 27) | @CallSuper
    method isFinished (line 38) | public boolean isFinished() {
    method onNotFinishedError (line 45) | protected void onNotFinishedError() {
    method onSaveIntroState (line 54) | protected void onSaveIntroState(@NonNull Bundle introState) {
    method goToNextSlide (line 58) | @Override
    method goToPreviousSlide (line 63) | @Override
    method skipToSlide (line 68) | @Override
    method getState (line 73) | @NonNull
    method getParent (line 79) | @NonNull

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/intro/SlideIndicator.java
  class SlideIndicator (line 15) | public class SlideIndicator extends View {
    method SlideIndicator (line 25) | public SlideIndicator(Context context, @Nullable AttributeSet attrs) {
    method setSlideCount (line 45) | public void setSlideCount(int slideCount) {
    method setCurrentSlide (line 54) | public void setCurrentSlide(int index) {
    method onDraw (line 67) | @Override
    method isRtl (line 95) | private boolean isRtl() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/models/AssignIconEntry.java
  class AssignIconEntry (line 8) | public class AssignIconEntry implements Serializable {
    method setOnResetListener (line 15) | public void setOnResetListener(AssignIconEntry.Listener listener) {
    method AssignIconEntry (line 19) | public AssignIconEntry(VaultEntry entry) {
    method getEntry (line 23) | public VaultEntry getEntry() {
    method getNewIcon (line 27) | public IconPack.Icon getNewIcon() { return _newIcon; }
    method setNewIcon (line 29) | public void setNewIcon(IconPack.Icon icon) {
    type Listener (line 37) | public interface Listener {
      method onNewIconChanged (line 38) | void onNewIconChanged();

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/models/AuditLogEntryModel.java
  class AuditLogEntryModel (line 8) | public class AuditLogEntryModel {
    method AuditLogEntryModel (line 12) | public AuditLogEntryModel(AuditLogEntry auditLogEntry, @Nullable Vault...
    method getAuditLogEntry (line 17) | public AuditLogEntry getAuditLogEntry() {
    method getReferencedVaultEntry (line 21) | public VaultEntry getReferencedVaultEntry() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/models/ErrorCardInfo.java
  class ErrorCardInfo (line 9) | public class ErrorCardInfo {
    method ErrorCardInfo (line 13) | public ErrorCardInfo(String message, View.OnClickListener listener) {
    method getMessage (line 18) | public String getMessage() {
    method getListener (line 22) | public View.OnClickListener getListener() {
    method hashCode (line 26) | @Override
    method equals (line 31) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/models/ImportEntry.java
  class ImportEntry (line 7) | public class ImportEntry implements Serializable {
    method ImportEntry (line 13) | public ImportEntry(VaultEntry entry) {
    method getEntry (line 17) | public VaultEntry getEntry() {
    method setOnCheckedChangedListener (line 21) | public void setOnCheckedChangedListener(Listener listener) {
    method isChecked (line 25) | public boolean isChecked() {
    method setIsChecked (line 29) | public void setIsChecked(boolean isChecked) {
    type Listener (line 37) | public interface Listener {
      method onCheckedChanged (line 38) | void onCheckedChanged(boolean value);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/models/VaultGroupModel.java
  class VaultGroupModel (line 14) | public class VaultGroupModel implements Serializable {
    method VaultGroupModel (line 19) | public VaultGroupModel(VaultGroup group) {
    method VaultGroupModel (line 25) | public VaultGroupModel(Context context, GroupPlaceholderType placehold...
    method getGroup (line 31) | public VaultGroup getGroup() {
    method getName (line 35) | public String getName() {
    method getPlaceholderType (line 39) | public GroupPlaceholderType getPlaceholderType() {
    method isPlaceholder (line 43) | public boolean isPlaceholder() {
    method getUUID (line 47) | @Nullable
    method toString (line 52) | @NonNull

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/preferences/SwitchPreference.java
  class SwitchPreference (line 9) | public class SwitchPreference extends SwitchPreferenceCompat {
    method SwitchPreference (line 12) | public SwitchPreference(Context context, AttributeSet attrs, int defSt...
    method SwitchPreference (line 16) | public SwitchPreference(Context context, AttributeSet attrs, int defSt...
    method SwitchPreference (line 20) | public SwitchPreference(Context context, AttributeSet attrs) {
    method SwitchPreference (line 24) | public SwitchPreference(Context context) {
    method setOnPreferenceChangeListener (line 28) | @Override
    method setChecked (line 34) | @Override
    method setChecked (line 39) | public void setChecked(boolean checked, boolean silent) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/slides/DoneSlide.java
  class DoneSlide (line 11) | public class DoneSlide extends SlideFragment {
    method onCreateView (line 12) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/slides/SecurityPickerSlide.java
  class SecurityPickerSlide (line 18) | public class SecurityPickerSlide extends SlideFragment {
    method onCreateView (line 28) | @Override
    method onResume (line 38) | @Override
    method updateBiometricsOption (line 48) | private void updateBiometricsOption(boolean autoSelect) {
    method isFinished (line 62) | @Override
    method onNotFinishedError (line 67) | @Override
    method onSaveIntroState (line 72) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/slides/SecuritySetupSlide.java
  class SecuritySetupSlide (line 42) | public class SecuritySetupSlide extends SlideFragment {
    method onCreateView (line 53) | @Override
    method onResume (line 88) | @Override
    method showBiometricPrompt (line 100) | private void showBiometricPrompt() {
    method deriveKey (line 109) | private void deriveKey() {
    method isFinished (line 116) | @Override
    method onNotFinishedError (line 137) | @Override
    method onSaveIntroState (line 148) | @Override
    class PasswordDerivationListener (line 153) | private class PasswordDerivationListener implements KeyDerivationTask....
      method onTaskFinished (line 154) | @Override
    class BiometricsListener (line 170) | private class BiometricsListener implements BiometricSlotInitializer.L...
      method onInitializeSlot (line 171) | @Override
      method onSlotInitializationFailed (line 185) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/slides/WelcomeSlide.java
  class WelcomeSlide (line 28) | public class WelcomeSlide extends SlideFragment {
    method onCreateView (line 40) | @Override
    method onSaveIntroState (line 51) | @Override
    method startImportVault (line 57) | private void startImportVault(Uri uri) {
    method importVault (line 98) | private void importVault(File file) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/Argon2Task.java
  class Argon2Task (line 13) | public class Argon2Task extends ProgressDialogTask<Argon2Task.Params, Se...
    method Argon2Task (line 16) | public Argon2Task(Context context, Callback cb) {
    method doInBackground (line 21) | @Override
    method deriveKey (line 29) | public static SecretKey deriveKey(Params params) {
    method onPostExecute (line 38) | @Override
    type Callback (line 44) | public interface Callback {
      method onTaskFinished (line 45) | void onTaskFinished(SecretKey key);
    class Params (line 48) | public static class Params {
      method Params (line 53) | public Params(char[] password, Argon2Parameters argon2Params, int ke...
      method getPassword (line 59) | public char[] getPassword() {
      method getArgon2Params (line 63) | public Argon2Parameters getArgon2Params() {
      method getKeySize (line 67) | public int getKeySize() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ExportTask.java
  class ExportTask (line 15) | public class ExportTask extends ProgressDialogTask<ExportTask.Params, Ex...
    method ExportTask (line 18) | public ExportTask(Context context, Callback cb) {
    method doInBackground (line 23) | @Override
    method onPostExecute (line 42) | @Override
    class Params (line 48) | public static class Params {
      method Params (line 52) | public Params(File file, Uri destUri) {
      method getFile (line 57) | public File getFile() {
      method getDestUri (line 61) | public Uri getDestUri() {
    type Callback (line 66) | public interface Callback {
      method onTaskFinished (line 67) | void onTaskFinished(Exception e);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/IconOptimizationTask.java
  class IconOptimizationTask (line 16) | public class IconOptimizationTask extends ProgressDialogTask<Map<UUID, V...
    method IconOptimizationTask (line 19) | public IconOptimizationTask(Context context, Callback cb) {
    method doInBackground (line 24) | @Override
    method onPostExecute (line 54) | @Override
    type Callback (line 60) | public interface Callback {
      method onTaskFinished (line 61) | void onTaskFinished(Map<UUID, VaultEntryIcon> results);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ImportFileTask.java
  class ImportFileTask (line 18) | public class ImportFileTask extends ProgressDialogTask<ImportFileTask.Pa...
    method ImportFileTask (line 21) | public ImportFileTask(Context context, Callback cb) {
    method doInBackground (line 26) | @Override
    method onPostExecute (line 52) | @Override
    type Callback (line 58) | public interface Callback {
      method onTaskFinished (line 59) | void onTaskFinished(Result result);
    class Params (line 62) | public static class Params {
      method Params (line 67) | public Params(Uri uri, String namePrefix, String nameSuffix) {
      method getUri (line 73) | public Uri getUri() {
      method getNamePrefix (line 77) | public String getNamePrefix() {
      method getNameSuffix (line 81) | public String getNameSuffix() {
    class Result (line 86) | public static class Result {
      method Result (line 91) | public Result(Uri uri, File file) {
      method Result (line 96) | public Result(Uri uri, Exception e) {
      method getUri (line 101) | public Uri getUri() {
      method getFile (line 105) | public File getFile() {
      method getError (line 109) | public String getError() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ImportIconPackTask.java
  class ImportIconPackTask (line 17) | public class ImportIconPackTask extends ProgressDialogTask<ImportIconPac...
    method ImportIconPackTask (line 20) | public ImportIconPackTask(Context context, ImportIconPackTask.Callback...
    method doInBackground (line 25) | @Override
    method onPostExecute (line 53) | @Override
    type Callback (line 59) | public interface Callback {
      method onTaskFinished (line 60) | void onTaskFinished(ImportIconPackTask.Result result);
    class Params (line 63) | public static class Params {
      method Params (line 67) | public Params(IconPackManager manager, Uri uri) {
      method getManager (line 72) | public IconPackManager getManager() {
      method getUri (line 76) | public Uri getUri() {
    class Result (line 81) | public static class Result {
      method Result (line 85) | public Result(IconPack pack, Exception e) {
      method getIconPack (line 90) | public IconPack getIconPack() {
      method getException (line 94) | public Exception getException() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/KeyDerivationTask.java
  class KeyDerivationTask (line 12) | public class KeyDerivationTask extends ProgressDialogTask<KeyDerivationT...
    method KeyDerivationTask (line 15) | public KeyDerivationTask(Context context, Callback cb) {
    method doInBackground (line 20) | @Override
    method onPostExecute (line 38) | @Override
    class Params (line 44) | public static class Params {
      method Params (line 48) | public Params(PasswordSlot slot, char[] password) {
      method getSlot (line 53) | public PasswordSlot getSlot() {
      method getPassword (line 57) | public char[] getPassword() {
    class Result (line 62) | public static class Result {
      method Result (line 66) | public Result(PasswordSlot slot, SecretKey key) {
      method getSlot (line 71) | public PasswordSlot getSlot() {
      method getKey (line 75) | public SecretKey getKey() {
    type Callback (line 80) | public interface Callback {
      method onTaskFinished (line 81) | void onTaskFinished(PasswordSlot slot, SecretKey key);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/PBKDFTask.java
  class PBKDFTask (line 21) | public class PBKDFTask extends ProgressDialogTask<PBKDFTask.Params, Secr...
    method PBKDFTask (line 24) | public PBKDFTask(Context context, Callback cb) {
    method doInBackground (line 29) | @Override
    method deriveKey (line 37) | public static SecretKey deriveKey(Params params) {
    method onPostExecute (line 57) | @Override
    type Callback (line 63) | public interface Callback {
      method onTaskFinished (line 64) | void onTaskFinished(SecretKey key);
    class Params (line 67) | public static class Params {
      method Params (line 74) | public Params(String algorithm, int keySize, char[] password, byte[]...
      method getAlgorithm (line 82) | public String getAlgorithm() {
      method getKeySize (line 86) | public int getKeySize() {
      method getPassword (line 90) | public char[] getPassword() {
      method getIterations (line 94) | public int getIterations() {
      method getSalt (line 98) | public byte[] getSalt() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/PasswordSlotDecryptTask.java
  class PasswordSlotDecryptTask (line 18) | public class PasswordSlotDecryptTask extends ProgressDialogTask<Password...
    method PasswordSlotDecryptTask (line 21) | public PasswordSlotDecryptTask(Context context, Callback cb) {
    method doInBackground (line 26) | @Override
    method decrypt (line 34) | public static Result decrypt(List<PasswordSlot> slots, char[] password) {
    method decryptPasswordSlot (line 48) | public static Result decryptPasswordSlot(PasswordSlot slot, char[] pas...
    method decryptPasswordSlot (line 80) | public static MasterKey decryptPasswordSlot(PasswordSlot slot, SecretK...
    method onPostExecute (line 86) | @Override
    class Params (line 92) | public static class Params {
      method Params (line 96) | public Params(List<PasswordSlot> slots, char[] password) {
      method getSlots (line 101) | public List<PasswordSlot> getSlots() {
      method getPassword (line 105) | public char[] getPassword() {
    class Result (line 110) | public static class Result {
      method Result (line 115) | public Result(MasterKey key, PasswordSlot slot, boolean repaired) {
      method Result (line 121) | public Result(MasterKey key, PasswordSlot slot) {
      method getKey (line 125) | public MasterKey getKey() {
      method getSlot (line 129) | public Slot getSlot() {
      method isSlotRepaired (line 133) | public boolean isSlotRepaired() {
    type Callback (line 138) | public interface Callback {
      method onTaskFinished (line 139) | void onTaskFinished(Result result);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ProgressDialogTask.java
  class ProgressDialogTask (line 22) | public abstract class ProgressDialogTask<Params, Result> extends AsyncTa...
    method ProgressDialogTask (line 26) | public ProgressDialogTask(Context context, String message) {
    method onPreExecute (line 39) | @CallSuper
    method onPostExecute (line 45) | @CallSuper
    method onProgressUpdate (line 53) | @Override
    method setPriority (line 60) | protected void setPriority() {
    method getDialog (line 64) | protected final AlertDialog getDialog() {
    method execute (line 68) | @SafeVarargs
    class Observer (line 77) | private static class Observer implements LifecycleObserver {
      method Observer (line 80) | public Observer(Dialog dialog) {
      method onPause (line 84) | @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/QrDecodeTask.java
  class QrDecodeTask (line 15) | public class QrDecodeTask extends ProgressDialogTask<List<Uri>, List<QrD...
    method QrDecodeTask (line 18) | public QrDecodeTask(Context context, Callback cb) {
    method doInBackground (line 23) | @Override
    method onPostExecute (line 50) | @Override
    type Callback (line 56) | public interface Callback {
      method onTaskFinished (line 57) | void onTaskFinished(List<Result> results);
    class Result (line 60) | public static class Result {
      method Result (line 66) | public Result(Uri uri, String fileName, com.google.zxing.Result resu...
      method getUri (line 73) | public Uri getUri() {
      method getFileName (line 77) | public String getFileName() {
      method getResult (line 81) | public com.google.zxing.Result getResult() {
      method getException (line 85) | public Exception getException() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/tasks/RootShellTask.java
  class RootShellTask (line 8) | public class RootShellTask extends ProgressDialogTask<Object, Shell> {
    method RootShellTask (line 11) | public RootShellTask(Context context, Callback cb) {
    method doInBackground (line 16) | @Override
    method onPostExecute (line 22) | @Override
    type Callback (line 28) | public interface Callback {
      method onTaskFinished (line 29) | void onTaskFinished(Shell shell);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/AssignIconAdapter.java
  class AssignIconAdapter (line 15) | public class AssignIconAdapter extends RecyclerView.Adapter<AssignIconHo...
    method AssignIconAdapter (line 19) | public AssignIconAdapter(AssignIconAdapter.Listener listener) {
    method addEntries (line 24) | public void addEntries(Collection<AssignIconEntry> entries) {
    method onCreateViewHolder (line 28) | @Override
    method onBindViewHolder (line 37) | @Override
    method getItemCount (line 46) | @Override
    type Listener (line 51) | public interface Listener {
      method onAssignIconEntryClick (line 52) | void onAssignIconEntryClick(AssignIconEntry entry);
      method onSetPreloadView (line 53) | void onSetPreloadView(View view);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/AssignIconHolder.java
  class AssignIconHolder (line 14) | public class AssignIconHolder extends RecyclerView.ViewHolder implements...
    method AssignIconHolder (line 24) | public AssignIconHolder(final View view) {
    method setData (line 37) | public void setData(AssignIconEntry entry) {
    method setNewIcon (line 46) | private void setNewIcon() {
    method getOldIconView (line 57) | public View getOldIconView() {
    method onNewIconChanged (line 61) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/AuditLogAdapter.java
  class AuditLogAdapter (line 19) | public class AuditLogAdapter extends RecyclerView.Adapter<AuditLogHolder> {
    method AuditLogAdapter (line 23) | public AuditLogAdapter() {
    method addAuditLogEntryModel (line 28) | public void addAuditLogEntryModel(AuditLogEntryModel auditLogEntryMode...
    method addReferencedEntry (line 39) | public void addReferencedEntry(VaultEntry vaultEntry) {
    method onCreateViewHolder (line 43) | @NonNull
    method onBindViewHolder (line 50) | @Override
    method getItemCount (line 58) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/AuditLogHolder.java
  class AuditLogHolder (line 26) | public class AuditLogHolder extends RecyclerView.ViewHolder {
    method AuditLogHolder (line 38) | public AuditLogHolder(final View view) {
    method setData (line 53) | public void setData(AuditLogEntryModel auditLogEntryModel) {
    method setCardBackgroundColor (line 75) | private void setCardBackgroundColor(EventType eventType) {
    method getEventTypeDescriptionRes (line 85) | private int getEventTypeDescriptionRes(EventType eventType) {
    method getIconResource (line 106) | private int getIconResource(EventType eventType) {
    method formatTimestamp (line 125) | private static String formatTimestamp(Context context, long epochMilli) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java
  class EntryAdapter (line 53) | public class EntryAdapter extends RecyclerView.Adapter<RecyclerView.View...
    method EntryAdapter (line 87) | public EntryAdapter(EntryListView view) {
    method destroy (line 97) | public void destroy() {
    method setCodeGroupSize (line 104) | public void setCodeGroupSize(Preferences.CodeGrouping codeGroupSize) {
    method setAccountNamePosition (line 108) | public void setAccountNamePosition(AccountNamePosition accountNamePosi...
    method setOnlyShowNecessaryAccountNames (line 112) | public void setOnlyShowNecessaryAccountNames(boolean onlyShowNecessary...
    method setShowIcon (line 116) | public void setShowIcon(boolean showIcon) {
    method setShowNextCode (line 120) | public void setShowNextCode(boolean showNextCode) {
    method setShowExpirationState (line 124) | public void setShowExpirationState(boolean showExpirationState) {
    method setTapToReveal (line 128) | public void setTapToReveal(boolean tapToReveal) {
    method setTapToRevealTime (line 132) | public void setTapToRevealTime(int number) {
    method setHighlightEntry (line 136) | public void setHighlightEntry(boolean highlightEntry) {
    method setTempHighlightEntry (line 140) | public void setTempHighlightEntry(boolean highlightEntry) {
    method setCopyBehavior (line 144) | public void setCopyBehavior(CopyBehavior copyBehavior) { _copyBehavior...
    method setSearchBehaviorMask (line 146) | public void setSearchBehaviorMask(int searchBehaviorMask) { _searchBeh...
    method setPauseFocused (line 148) | public void setPauseFocused(boolean pauseFocused) {
    method setErrorCardInfo (line 152) | public void setErrorCardInfo(ErrorCardInfo info) {
    method getEntryAtPosition (line 164) | public VaultEntry getEntryAtPosition(int position) {
    method getEntryPosition (line 168) | public int getEntryPosition(VaultEntry entry) {
    method setEntries (line 172) | public void setEntries(List<VaultEntry> entries) {
    method clearEntries (line 186) | public void clearEntries() {
    method translateEntryPosToIndex (line 190) | public int translateEntryPosToIndex(int position) {
    method isEntryFiltered (line 194) | private boolean isEntryFiltered(VaultEntry entry) {
    method doesAnyGroupMatchSearchFilter (line 225) | private boolean doesAnyGroupMatchSearchFilter(Set<UUID> entryGroupUUID...
    method refresh (line 232) | public void refresh(boolean hard) {
    method setGroupFilter (line 243) | public void setGroupFilter(@NonNull Set<UUID> groups) {
    method setSortCategory (line 252) | public void setSortCategory(SortCategory category, boolean apply) {
    method getSearchFilter (line 263) | public String getSearchFilter() {
    method setSearchFilter (line 267) | public void setSearchFilter(String search) {
    method refreshEntryList (line 277) | private void refreshEntryList() {
    method replaceEntryList (line 285) | private void replaceEntryList(EntryList newEntryList) {
    method calculateShownEntries (line 299) | private List<VaultEntry> calculateShownEntries(List<VaultEntry> entrie...
    method sortEntries (line 311) | private static void sortEntries(List<VaultEntry> entries, SortCategory...
    method isEntryDraggable (line 323) | private boolean isEntryDraggable(VaultEntry entry) {
    method setViewMode (line 331) | public void setViewMode(ViewMode viewMode) {
    method setUsageCounts (line 335) | public void setUsageCounts(Map<UUID, Integer> usageCounts) { _usageCou...
    method getUsageCounts (line 337) | public Map<UUID, Integer> getUsageCounts() { return _usageCounts; }
    method setGroups (line 339) | public void setGroups(Collection<VaultGroup> groups) { _groups = group...
    method setLastUsedTimestamps (line 341) | public void setLastUsedTimestamps(Map<UUID, Long> lastUsedTimestamps) ...
    method getLastUsedTimestamps (line 343) | public Map<UUID, Long> getLastUsedTimestamps() { return _lastUsedTimes...
    method getShownFavoritesCount (line 345) | public int getShownFavoritesCount() {
    method onItemDismiss (line 349) | @Override
    method onItemDrop (line 354) | @Override
    method onItemMove (line 366) | @Override
    method getItemViewType (line 393) | @Override
    method onCreateViewHolder (line 406) | @Override
    method onViewRecycled (line 428) | @Override
    method onBindViewHolder (line 436) | @Override
    method updatePeriodUniformity (line 575) | private void updatePeriodUniformity() {
    method getMostFrequentPeriod (line 594) | public int getMostFrequentPeriod() {
    method focusEntry (line 633) | public void focusEntry(VaultEntry entry, int secondsToFocus) {
    method resetFocus (line 664) | private void resetFocus() {
    method updateDraggableStatus (line 681) | private void updateDraggableStatus() {
    method removeSelectedEntry (line 694) | public void removeSelectedEntry(VaultEntry entry) {
    method addSelectedEntry (line 699) | public void addSelectedEntry(VaultEntry entry) {
    method selectAllEntries (line 708) | public List<VaultEntry> selectAllEntries() {
    method deselectAllEntries (line 725) | public void deselectAllEntries() {
    method incrementUsageCount (line 740) | private void incrementUsageCount(VaultEntry entry) {
    method isDragAndDropAllowed (line 751) | public boolean isDragAndDropAllowed() {
    method isPeriodUniform (line 755) | public boolean isPeriodUniform() {
    method isPeriodUniform (line 759) | private static boolean isPeriodUniform(int period) {
    method getItemCount (line 763) | @Override
    method getShownEntriesCount (line 768) | public int getShownEntriesCount() {
    method isPositionFooter (line 772) | public boolean isPositionFooter(int position) {
    method isPositionErrorCard (line 776) | public boolean isPositionErrorCard(int position) {
    method isErrorCardShown (line 780) | public boolean isErrorCardShown() {
    class FooterView (line 784) | private class FooterView extends RecyclerView.ViewHolder {
      method FooterView (line 787) | public FooterView(@NonNull View itemView) {
      method refresh (line 792) | public void refresh() {
    class EntryList (line 808) | private static class EntryList {
      method EntryList (line 813) | public EntryList() {
      method EntryList (line 817) | public EntryList(
      method getEntries (line 827) | public List<VaultEntry> getEntries() {
      method getShownEntries (line 831) | public List<VaultEntry> getShownEntries() {
      method getItemCount (line 835) | public int getItemCount() {
      method getErrorCardInfo (line 846) | @Nullable
      method isErrorCardShown (line 851) | public boolean isErrorCardShown() {
      method isPositionErrorCard (line 855) | public boolean isPositionErrorCard(int position) {
      method isPositionFooter (line 859) | public boolean isPositionFooter(int position) {
      method translateEntryPosToIndex (line 866) | public int translateEntryPosToIndex(int position) {
      method translateEntryIndexToPos (line 881) | public int translateEntryIndexToPos(int index) {
    class DiffCallback (line 895) | private static class DiffCallback extends DiffUtil.Callback {
      method DiffCallback (line 899) | public DiffCallback(EntryList oldList, EntryList newList) {
      method getOldListSize (line 904) | @Override
      method getNewListSize (line 909) | @Override
      method areItemsTheSame (line 914) | @Override
      method areContentsTheSame (line 936) | @Override
    type Listener (line 953) | public interface Listener {
      method onEntryClick (line 954) | void onEntryClick(VaultEntry entry);
      method onLongEntryClick (line 955) | boolean onLongEntryClick(VaultEntry entry);
      method onEntryMove (line 956) | void onEntryMove(VaultEntry entry1, VaultEntry entry2);
      method onEntryDrop (line 957) | void onEntryDrop(VaultEntry entry);
      method onEntryChange (line 958) | void onEntryChange(VaultEntry entry);
      method onEntryCopy (line 959) | void onEntryCopy(VaultEntry entry);
      method onPeriodUniformityChanged (line 960) | void onPeriodUniformityChanged(boolean uniform, int period);
      method onSelect (line 961) | void onSelect(VaultEntry entry);
      method onDeselect (line 962) | void onDeselect(VaultEntry entry);
      method onListChange (line 963) | void onListChange();

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java
  class EntryHolder (line 45) | public class EntryHolder extends RecyclerView.ViewHolder {
    method EntryHolder (line 83) | public EntryHolder(final View view) {
    method setData (line 128) | public void setData(VaultEntry entry, Preferences.CodeGrouping groupSi...
    method setAccountNameLayout (line 175) | private void setAccountNameLayout(AccountNamePosition accountNamePosit...
    method getEntry (line 220) | public VaultEntry getEntry() {
    method loadIcon (line 224) | public void loadIcon(Fragment fragment) {
    method getIconView (line 228) | public ImageView getIconView() {
    method setOnRefreshClickListener (line 232) | public void setOnRefreshClickListener(View.OnClickListener listener) {
    method setShowDragHandle (line 236) | public void setShowDragHandle(boolean showDragHandle) {
    method setShowProgress (line 244) | public void setShowProgress(boolean showProgress) {
    method setFocused (line 258) | public void setFocused(boolean focused) {
    method setFocusedAndAnimate (line 265) | public void setFocusedAndAnimate(boolean focused) {
    method destroy (line 278) | public void destroy() {
    method startRefreshLoop (line 282) | public void startRefreshLoop() {
    method stopRefreshLoop (line 287) | public void stopRefreshLoop() {
    method refresh (line 292) | public void refresh() {
    method refreshCode (line 297) | public void refreshCode() {
    method updateCodes (line 304) | private void updateCodes() {
    method getOtp (line 312) | private String getOtp() {
    method getOtp (line 316) | private String getOtp(int offset) {
    method formatCode (line 341) | private String formatCode(String code) {
    method revealCode (line 370) | public void revealCode() {
    method hideCode (line 376) | public void hideCode() {
    method updateTextViewWithDots (line 387) | private void updateTextViewWithDots(TextView textView, String hiddenCo...
    method startExpirationAnimation (line 428) | public void startExpirationAnimation() {
    method stopExpirationAnimation (line 483) | private void stopExpirationAnimation() {
    method showIcon (line 495) | public void showIcon(boolean show) {
    method isHidden (line 503) | public boolean isHidden() {
    method setPaused (line 507) | public void setPaused(boolean paused) {
    method dim (line 518) | public void dim() {
    method highlight (line 522) | public void highlight() {
    method animateCopyText (line 526) | public void animateCopyText() {
    method animateAlphaTo (line 557) | private void animateAlphaTo(float alpha) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java
  class EntryListView (line 66) | public class EntryListView extends Fragment implements EntryAdapter.List...
    method onCreate (line 83) | @Override
    method onDestroy (line 90) | @Override
    method onCreateView (line 96) | @Override
    method setPreloadView (line 190) | public void setPreloadView(View view) {
    method getScrollPosition (line 194) | public int getScrollPosition() {
    method scrollToPosition (line 198) | public void scrollToPosition(int position) {
    method onDestroyView (line 202) | @Override
    method onRefreshStop (line 208) | public void onRefreshStop() {
    method onRefreshStart (line 212) | public void onRefreshStart() {
    method setGroups (line 218) | public void setGroups(Collection<VaultGroup> groups) {
    method setGroupFilter (line 223) | public void setGroupFilter(Set<UUID> groups) {
    method setIsLongPressDragEnabled (line 230) | public void setIsLongPressDragEnabled(boolean enabled) {
    method setCopyBehavior (line 234) | public void setCopyBehavior(CopyBehavior copyBehavior) {
    method setSearchBehaviorMask (line 238) | public void setSearchBehaviorMask(int searchBehaviorMask) {
    method selectAllEntries (line 242) | public List<VaultEntry> selectAllEntries() {
    method setActionModeState (line 246) | public void setActionModeState(boolean enabled, VaultEntry entry) {
    method setSortCategory (line 257) | public void setSortCategory(SortCategory sortCategory, boolean apply) {
    method setUsageCounts (line 263) | public void setUsageCounts(Map<UUID, Integer> usageCounts) {
    method getUsageCounts (line 267) | public Map<UUID, Integer> getUsageCounts() {
    method setLastUsedTimestamps (line 271) | public void setLastUsedTimestamps(Map<UUID, Long> lastUsedTimestamps) {
    method getLastUsedTimestamps (line 275) | public Map<UUID, Long> getLastUsedTimestamps() {
    method setSearchFilter (line 279) | public void setSearchFilter(String search) {
    method setSelectedEntry (line 286) | public void setSelectedEntry(VaultEntry entry) {
    method setViewMode (line 290) | public void setViewMode(ViewMode mode) {
    method startDrag (line 303) | public void startDrag(RecyclerView.ViewHolder viewHolder) {
    method refresh (line 307) | public void refresh(boolean hard) {
    method setListener (line 315) | public void setListener(Listener listener) {
    method onEntryClick (line 319) | @Override
    method onLongEntryClick (line 326) | public boolean onLongEntryClick(VaultEntry entry) {
    method onEntryMove (line 333) | @Override
    method onEntryDrop (line 340) | @Override
    method onEntryChange (line 347) | @Override
    method onEntryCopy (line 354) | @Override
    method onSelect (line 361) | @Override
    method onDeselect (line 368) | @Override
    method onPeriodUniformityChanged (line 375) | @Override
    method onListChange (line 390) | @Override
    method setCodeGroupSize (line 397) | public void setCodeGroupSize(Preferences.CodeGrouping codeGrouping) {
    method setAccountNamePosition (line 401) | public void setAccountNamePosition(AccountNamePosition accountNamePosi...
    method setOnlyShowNecessaryAccountNames (line 405) | public void setOnlyShowNecessaryAccountNames(boolean onlyShowNecessary...
    method setShowIcon (line 409) | public void setShowIcon(boolean showIcon) {
    method setShowNextCode (line 413) | public void setShowNextCode(boolean showNextCode) {
    method setShowExpirationState (line 417) | public void setShowExpirationState(boolean showExpirationState) {
    method setHighlightEntry (line 421) | public void setHighlightEntry(boolean highlightEntry) {
    method setPauseFocused (line 425) | public void setPauseFocused(boolean pauseFocused) {
    method setTapToReveal (line 429) | public void setTapToReveal(boolean tapToReveal) {
    method setTapToRevealTime (line 433) | public void setTapToRevealTime(int number) {
    method setErrorCardInfo (line 437) | public void setErrorCardInfo(ErrorCardInfo info) {
    method onEntryAdded (line 441) | @SuppressLint("ClickableViewAccessibility")
    method tempHighlightEntry (line 495) | public void tempHighlightEntry(VaultEntry entry) {
    method setEntries (line 502) | public void setEntries(Collection<VaultEntry> entries) {
    method clearEntries (line 507) | public void clearEntries() {
    method runEntriesAnimation (line 512) | public void runEntriesAnimation() {
    method setShowProgress (line 519) | private void setShowProgress(boolean showProgress) {
    method updateDividerDecoration (line 524) | private void updateDividerDecoration() {
    method updateEmptyState (line 539) | private void updateEmptyState() {
    type Listener (line 551) | public interface Listener {
      method onEntryClick (line 552) | void onEntryClick(VaultEntry entry);
      method onEntryMove (line 553) | void onEntryMove(VaultEntry entry1, VaultEntry entry2);
      method onEntryDrop (line 554) | void onEntryDrop(VaultEntry entry);
      method onEntryChange (line 555) | void onEntryChange(VaultEntry entry);
      method onEntryCopy (line 556) | void onEntryCopy(VaultEntry entry);
      method onLongEntryClick (line 557) | void onLongEntryClick(VaultEntry entry);
      method onScroll (line 558) | void onScroll(int dx, int dy);
      method onSelect (line 559) | void onSelect(VaultEntry entry);
      method onDeselect (line 560) | void onDeselect(VaultEntry entry);
      method onListChange (line 561) | void onListChange();
      method onSaveGroupFilter (line 562) | void onSaveGroupFilter(Set<UUID> groupFilter);
      method onEntryListTouch (line 563) | void onEntryListTouch();
    class VerticalSpaceItemDecoration (line 566) | private class VerticalSpaceItemDecoration extends RecyclerView.ItemDec...
      method VerticalSpaceItemDecoration (line 570) | private VerticalSpaceItemDecoration(float offset) {
      method getItemOffsets (line 580) | @Override
      method decorateFavoriteEntries (line 621) | private void decorateFavoriteEntries(@NonNull MaterialCardView view,...
      method getStyledAttrs (line 642) | private int getStyledAttrs(@StyleRes int styleId, @AttrRes int attrI...
    class TileSpaceItemDecoration (line 657) | private class TileSpaceItemDecoration extends RecyclerView.ItemDecorat...
      method TileSpaceItemDecoration (line 660) | private TileSpaceItemDecoration(float offset) {
      method getItemOffsets (line 664) | @Override
      method isInFirstEntryRow (line 683) | private boolean isInFirstEntryRow(int pos) {
    class IconPreloadProvider (line 689) | private class IconPreloadProvider implements ListPreloader.PreloadMode...
      method getPreloadItems (line 690) | @NonNull
      method getPreloadRequestBuilder (line 709) | @Nullable

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/ErrorCardHolder.java
  class ErrorCardHolder (line 13) | public class ErrorCardHolder extends RecyclerView.ViewHolder {
    method ErrorCardHolder (line 14) | public ErrorCardHolder(@NonNull View itemView, ErrorCardInfo info) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/GroupAdapter.java
  class GroupAdapter (line 17) | public class GroupAdapter extends RecyclerView.Adapter<GroupHolder> impl...
    method GroupAdapter (line 21) | public GroupAdapter(GroupAdapter.Listener listener) {
    method addGroup (line 26) | public void addGroup(VaultGroup group) {
    method getGroups (line 37) | public ArrayList<VaultGroup> getGroups() {
    method replaceGroup (line 41) | public void replaceGroup(UUID uuid, VaultGroup newGroup) {
    method removeGroup (line 48) | public void removeGroup(VaultGroup group) {
    method onCreateViewHolder (line 54) | @Override
    method onBindViewHolder (line 60) | @Override
    method onItemMove (line 73) | @Override
    method onItemDismiss (line 79) | @Override
    method onItemDrop (line 82) | @Override
    method getGroupByUUID (line 85) | private VaultGroup getGroupByUUID(UUID uuid) {
    method getItemCount (line 94) | @Override
    type Listener (line 99) | public interface Listener {
      method onEditGroup (line 100) | void onEditGroup(VaultGroup group);
      method onRemoveGroup (line 101) | void onRemoveGroup(VaultGroup group);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/GroupHolder.java
  class GroupHolder (line 12) | public class GroupHolder extends RecyclerView.ViewHolder {
    method GroupHolder (line 17) | public GroupHolder(final View view) {
    method setData (line 24) | public void setData(VaultGroup group) {
    method setOnEditClickListener (line 28) | public void setOnEditClickListener(View.OnClickListener listener) {
    method setOnDeleteClickListener (line 32) | public void setOnDeleteClickListener(View.OnClickListener listener) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/IconAdapter.java
  class IconAdapter (line 22) | public class IconAdapter extends RecyclerView.Adapter<RecyclerView.ViewH...
    method IconAdapter (line 31) | public IconAdapter(@NonNull Context context, String issuer, @NonNull L...
    method loadIcons (line 42) | public void loadIcons(IconPack pack, boolean showAddCustom) {
    method setQuery (line 92) | public void setQuery(@Nullable String query) {
    method getIconAt (line 103) | public IconPack.Icon getIconAt(int position) {
    method getCategoryAt (line 112) | public CategoryHeader getCategoryAt(int position) {
    method getCategoryString (line 119) | private String getCategoryString(String category) {
    method isCategoryPosition (line 123) | private boolean isCategoryPosition(int position) {
    method translateIconPosition (line 131) | private int translateIconPosition(int position) {
    method updateCategoryPositions (line 145) | private void updateCategoryPositions() {
    method onCreateViewHolder (line 159) | @NonNull
    method onBindViewHolder (line 166) | @Override
    method getItemCount (line 201) | @Override
    method getItemViewType (line 215) | @Override
    method isQueryActive (line 224) | private boolean isQueryActive() {
    type Listener (line 228) | public interface Listener {
      method onIconSelected (line 229) | void onIconSelected(IconPack.Icon icon);
      method onCustomSelected (line 230) | void onCustomSelected();
    class DummyIcon (line 233) | public static class DummyIcon extends IconPack.Icon {
      method DummyIcon (line 234) | protected DummyIcon(String name) {
      method getIconType (line 238) | @Override
    class CategoryHeader (line 244) | public static class CategoryHeader {
      method CategoryHeader (line 250) | public CategoryHeader(String category) {
      method getCategory (line 255) | public String getCategory() {
      method getPosition (line 259) | public int getPosition() {
      method setPosition (line 263) | public void setPosition(int position) {
      method getIcons (line 267) | public List<IconPack.Icon> getIcons() {
      method isCollapsed (line 271) | public boolean isCollapsed() {
      method setIsCollapsed (line 275) | public void setIsCollapsed(boolean collapsed) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/IconCategoryHolder.java
  class IconCategoryHolder (line 11) | public class IconCategoryHolder extends RecyclerView.ViewHolder {
    method IconCategoryHolder (line 15) | public IconCategoryHolder(final View view) {
    method setData (line 21) | public void setData(IconAdapter.CategoryHeader header) {
    method setIsCollapsed (line 26) | public void setIsCollapsed(boolean collapsed) {
    method getRotation (line 33) | private static int getRotation(boolean collapsed) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/IconHolder.java
  class IconHolder (line 19) | public class IconHolder extends RecyclerView.ViewHolder {
    method IconHolder (line 27) | public IconHolder(final View view) {
    method setData (line 33) | public void setData(IconPack.Icon icon) {
    method loadIcon (line 40) | public void loadIcon(Context context) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/IconPackAdapter.java
  class IconPackAdapter (line 16) | public class IconPackAdapter extends RecyclerView.Adapter<IconPackHolder> {
    method IconPackAdapter (line 20) | public IconPackAdapter(IconPackAdapter.Listener listener) {
    method addIconPack (line 25) | public void addIconPack(IconPack pack) {
    method removeIconPack (line 36) | public void removeIconPack(IconPack pack) {
    method onCreateViewHolder (line 44) | @NonNull
    method onBindViewHolder (line 51) | @Override
    method getItemCount (line 60) | @Override
    type Listener (line 65) | public interface Listener {
      method onRemoveIconPack (line 66) | void onRemoveIconPack(IconPack pack);

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/IconPackHolder.java
  class IconPackHolder (line 12) | public class IconPackHolder extends RecyclerView.ViewHolder {
    method IconPackHolder (line 17) | public IconPackHolder(final View view) {
    method setData (line 24) | public void setData(IconPack pack) {
    method setOnDeleteClickListener (line 29) | public void setOnDeleteClickListener(View.OnClickListener listener) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/IconRecyclerView.java
  class IconRecyclerView (line 14) | public class IconRecyclerView extends RecyclerView {
    method IconRecyclerView (line 19) | public IconRecyclerView(@NonNull Context context) {
    method IconRecyclerView (line 24) | public IconRecyclerView(@NonNull Context context, @Nullable AttributeS...
    method IconRecyclerView (line 29) | public IconRecyclerView(@NonNull Context context, @Nullable AttributeS...
    method init (line 34) | @SuppressLint("ResourceType")
    method onMeasure (line 49) | @Override
    method getGridLayoutManager (line 58) | public GridLayoutManager getGridLayoutManager() {
    method getSpanCount (line 62) | public int getSpanCount() {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/ImportEntriesAdapter.java
  class ImportEntriesAdapter (line 17) | public class ImportEntriesAdapter extends RecyclerView.Adapter<ImportEnt...
    method ImportEntriesAdapter (line 20) | public ImportEntriesAdapter() {
    method addEntry (line 24) | public void addEntry(ImportEntry entry) {
    method onCreateViewHolder (line 35) | @NonNull
    method onBindViewHolder (line 42) | @Override
    method onViewRecycled (line 49) | @Override
    method getItemCount (line 54) | @Override
    method getCheckedEntries (line 59) | public List<ImportEntry> getCheckedEntries() {
    method setCheckboxStates (line 71) | public void setCheckboxStates(List<UUID> uuids, boolean state) {
    method toggleCheckboxes (line 79) | public void toggleCheckboxes() {
    method setCheckboxStates (line 88) | private void setCheckboxStates(boolean checked) {

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/ImportEntryHolder.java
  class ImportEntryHolder (line 13) | public class ImportEntryHolder extends RecyclerView.ViewHolder implement...
    method ImportEntryHolder (line 20) | public ImportEntryHolder(final View view) {
    method setData (line 29) | public void setData(ImportEntry data) {
    method getData (line 38) | public ImportEntry getData() {
    method onCheckedChanged (line 42) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/ui/views/TotpProgressBar.java
  class TotpProgressBar (line 13) | public class TotpProgressBar extends ProgressBar {
    method TotpProgressBar (line 18) | public TotpProgressBar(Context context) {
    method TotpProgressBar (line 22) | public TotpProgressBar(Context context, AttributeSet attrs) {
    method TotpProgressBar (line 26) | public TotpProgressBar(Context context, AttributeSet attrs, int defSty...
    method TotpProgressBar (line 30) | public TotpProgressBar(Context context, AttributeSet attrs, int defSty...
    method setPeriod (line 34) | public void setPeriod(int period) {
    method start (line 38) | public void start() {
    method stop (line 45) | public void stop() {
    method restart (line 52) | public void restart() {
    method refresh (line 57) | private void refresh() {

FILE: app/src/main/java/com/beemdevelopment/aegis/util/ClipboardUtils.java
  class ClipboardUtils (line 7) | public final class ClipboardUtils {
    method readText (line 8) | public static String readText(Context context) {

FILE: app/src/main/java/com/beemdevelopment/aegis/util/Cloner.java
  class Cloner (line 10) | public class Cloner {
    method Cloner (line 11) | private Cloner() {
    method clone (line 18) | @SuppressWarnings("unchecked cast")

FILE: app/src/main/java/com/beemdevelopment/aegis/util/CollectionUtils.java
  class CollectionUtils (line 5) | public class CollectionUtils {
    method move (line 7) | public static <T> void move(List<T> list, int fromIndex, int toIndex) {

FILE: app/src/main/java/com/beemdevelopment/aegis/util/IOUtils.java
  class IOUtils (line 11) | public class IOUtils {
    method IOUtils (line 12) | private IOUtils() {
    method readFile (line 16) | public static byte[] readFile(FileInputStream inStream) throws IOExcep...
    method readAll (line 24) | public static byte[] readAll(InputStream inStream) throws IOException {
    method copy (line 31) | public static void copy(InputStream inStream, OutputStream outStream) ...
    method clearDirectory (line 39) | public static void clearDirectory(File dir, boolean deleteRoot) {

FILE: app/src/main/java/com/beemdevelopment/aegis/util/JsonUtils.java
  class JsonUtils (line 7) | public class JsonUtils {
    method JsonUtils (line 8) | private JsonUtils() {
    method optString (line 12) | @Nullable

FILE: app/src/main/java/com/beemdevelopment/aegis/util/PreferenceParser.java
  class PreferenceParser (line 10) | public class PreferenceParser {
    method PreferenceParser (line 11) | private PreferenceParser() {
    method parse (line 15) | public static List<XmlEntry> parse(XmlPullParser parser) throws IOExce...
    method parseEntry (line 35) | private static XmlEntry parseEntry(XmlPullParser parser) throws IOExce...
    method parseText (line 47) | private static String parseText(XmlPullParser parser) throws IOExcepti...
    method skip (line 56) | private static void skip(XmlPullParser parser) throws IOException, Xml...
    class XmlEntry (line 75) | public static class XmlEntry {

FILE: app/src/main/java/com/beemdevelopment/aegis/util/TimeUtils.java
  class TimeUtils (line 11) | public class TimeUtils {
    method TimeUtils (line 12) | private TimeUtils() {
    method getElapsedSince (line 16) | public static String getElapsedSince(Context context, Date date) {
    method formatElapsedSince (line 37) | @SuppressLint("DiscouragedApi")

FILE: app/src/main/java/com/beemdevelopment/aegis/util/UUIDMap.java
  class UUIDMap (line 22) | public class UUIDMap <T extends UUIDMap.Value> implements Iterable<T>, S...
    method add (line 29) | public void add(T value) {
    method remove (line 42) | public T remove(T value) {
    method wipe (line 51) | public void wipe() {
    method replace (line 61) | public T replace(T newValue) {
    method move (line 70) | public void move(T value1, T value2) {
    method has (line 102) | public boolean has(T value) {
    method has (line 109) | public boolean has(UUID uuid) {
    method getValues (line 116) | public Collection<T> getValues() {
    method getByUUID (line 124) | public T getByUUID(UUID uuid) {
    method iterator (line 132) | @NonNull
    class Value (line 138) | public static abstract class Value implements Serializable {
      method Value (line 141) | protected Value(UUID uuid) {
      method Value (line 145) | protected Value() {
      method getUUID (line 149) | @NonNull
      method resetUUID (line 158) | public final void resetUUID() {
      method equals (line 162) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/Vault.java
  class Vault (line 14) | public class Vault {
    method toJson (line 23) | public JSONObject toJson() {
    method toJson (line 27) | public JSONObject toJson(@Nullable EntryFilter filter) {
    method fromJson (line 54) | public static Vault fromJson(JSONObject obj) throws VaultException {
    method setGroupsMigrationFresh (line 102) | private void setGroupsMigrationFresh() {
    method isGroupsMigrationFresh (line 106) | public boolean isGroupsMigrationFresh() {
    method setIconsOptimized (line 110) | public void setIconsOptimized(boolean optimized) {
    method areIconsOptimized (line 114) | public boolean areIconsOptimized() {
    method migrateOldGroup (line 118) | public boolean migrateOldGroup(VaultEntry entry) {
    method getEntries (line 140) | public UUIDMap<VaultEntry> getEntries() {
    method getGroups (line 144) | public UUIDMap<VaultGroup> getGroups() {
    type EntryFilter (line 148) | public interface EntryFilter {
      method includeEntry (line 149) | boolean includeEntry(VaultEntry entry);

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultBackupManager.java
  class VaultBackupManager (line 36) | public class VaultBackupManager {
    method VaultBackupManager (line 50) | public VaultBackupManager(Context context, AuditLogRepository auditLog...
    method scheduleBackup (line 57) | public void scheduleBackup(File tempFile, BackupsVersioningStrategy st...
    method createBackup (line 70) | private void createBackup(File tempFile, BackupsVersioningStrategy str...
    method createBackup (line 84) | private void createBackup(File tempFile, Uri fileUri)
    method createBackup (line 110) | private void createBackup(File tempFile, Uri dirUri, int versionsToKeep)
    method hasPermissionsAt (line 153) | public boolean hasPermissionsAt(Uri uri) {
    method enforceVersioning (line 163) | private void enforceVersioning(DocumentFile dir, int versionsToKeep) {
    class FileInfo (line 192) | public static class FileInfo {
      method FileInfo (line 197) | public FileInfo(String filename, String extension, Date date) {
      method FileInfo (line 203) | public FileInfo(String filename, Date date) {
      method FileInfo (line 207) | public FileInfo(String filename) {
      method FileInfo (line 211) | public FileInfo(String filename, String extension) {
      method parseFilename (line 215) | public static FileInfo parseFilename(String filename) throws ParseEx...
      method throwBadFormat (line 245) | private static void throwBadFormat(String filename) throws ParseExce...
      method getFilename (line 249) | public String getFilename() {
      method getExtension (line 253) | public String getExtension() {
      method getDate (line 257) | public Date getDate() {
      method toString (line 261) | @NonNull
    class BackupFile (line 268) | private static class BackupFile {
      method BackupFile (line 272) | public BackupFile(DocumentFile file) throws ParseException {
      method getFile (line 277) | public DocumentFile getFile() {
      method getInfo (line 281) | public FileInfo getInfo() {
    class FileComparator (line 286) | private static class FileComparator implements Comparator<BackupFile> {
      method compare (line 287) | @Override
    class StrictDateFormat (line 294) | private static class StrictDateFormat extends SimpleDateFormat {
      method StrictDateFormat (line 295) | public StrictDateFormat(String pattern, Locale locale) {
      method parse (line 300) | @Override

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultBackupPermissionException.java
  class VaultBackupPermissionException (line 3) | public class VaultBackupPermissionException extends Exception {
    method VaultBackupPermissionException (line 4) | public VaultBackupPermissionException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultEntry.java
  class VaultEntry (line 19) | public class VaultEntry extends UUIDMap.Value {
    method VaultEntry (line 31) | private VaultEntry(UUID uuid, OtpInfo info) {
    method VaultEntry (line 36) | public VaultEntry(OtpInfo info) {
    method VaultEntry (line 41) | public VaultEntry(OtpInfo info, String name, String issuer) {
    method VaultEntry (line 47) | public VaultEntry(GoogleAuthInfo info) {
    method toJson (line 51) | public JSONObject toJson() {
    method fromJson (line 77) | public static VaultEntry fromJson(JSONObject obj) throws VaultEntryExc...
    method getName (line 121) | public String getName() {
    method getIssuer (line 125) | public String getIssuer() {
    method getGroups (line 129) | public Set<UUID> getGroups() {
    method getIcon (line 133) | public VaultEntryIcon getIcon() {
    method getInfo (line 137) | public OtpInfo getInfo() {
    method getUsageCount (line 141) | public int getUsageCount() {
    method getLastUsedTimestamp (line 145) | public long getLastUsedTimestamp() {
    method getNote (line 149) | public String getNote() {
    method isFavorite (line 153) | public boolean isFavorite() {
    method setName (line 157) | public void setName(String name) {
    method setIssuer (line 161) | public void setIssuer(String issuer) {
    method addGroup (line 165) | public void addGroup(UUID group) {
    method removeGroup (line 172) | public void removeGroup(UUID group) {
    method setGroups (line 176) | public void setGroups(Set<UUID> groups) {
    method setInfo (line 183) | public void setInfo(OtpInfo info) {
    method setIcon (line 187) | public void setIcon(VaultEntryIcon icon) {
    method hasIcon (line 191) | public boolean hasIcon() {
    method setUsageCount (line 195) | public void setUsageCount(int usageCount) {
    method setLastUsedTimestamp (line 199) | public void setLastUsedTimestamp(long lastUsedTimestamp) { _lastUsedTi...
    method setNote (line 201) | public void setNote(String note) {
    method setIsFavorite (line 205) | public void setIsFavorite(boolean isFavorite) {
    method setOldGroup (line 209) | void setOldGroup(String oldGroup) {
    method getOldGroup (line 213) | String getOldGroup() {
    method equals (line 217) | @Override
    method equivalates (line 232) | public boolean equivalates(VaultEntry entry) {
    method hasSameNameAndIssuer (line 242) | public boolean hasSameNameAndIssuer(VaultEntry entry) {
    method isDefault (line 249) | public boolean isDefault() {
    method getDefault (line 253) | public static VaultEntry getDefault() {

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultEntryException.java
  class VaultEntryException (line 3) | public class VaultEntryException extends Exception {
    method VaultEntryException (line 4) | public VaultEntryException(Throwable cause) {
    method VaultEntryException (line 8) | public VaultEntryException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultEntryIcon.java
  class VaultEntryIcon (line 22) | public class VaultEntryIcon implements Serializable {
    method VaultEntryIcon (line 29) | public VaultEntryIcon(@NonNull byte[] bytes, @NonNull IconType type) {
    method VaultEntryIcon (line 33) | VaultEntryIcon(@NonNull byte[] bytes, @NonNull IconType type, @NonNull...
    method getBytes (line 39) | public @NonNull byte[] getBytes() {
    method getHash (line 43) | public @NonNull byte[] getHash() {
    method getType (line 47) | @NonNull
    method equals (line 52) | @Override
    method hashCode (line 62) | @Override
    method toJson (line 67) | static void toJson(@Nullable VaultEntryIcon icon, @NonNull JSONObject ...
    method fromJson (line 75) | @Nullable
    method generateHash (line 102) | private static @NonNull byte[] generateHash(@NonNull byte[] bytes, @No...

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultEntryIconException.java
  class VaultEntryIconException (line 3) | public class VaultEntryIconException extends Exception {
    method VaultEntryIconException (line 4) | public VaultEntryIconException(Throwable cause) {
    method VaultEntryIconException (line 8) | public VaultEntryIconException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultException.java
  class VaultException (line 3) | public class VaultException extends Exception {
    method VaultException (line 4) | public VaultException(Throwable cause) {
    method VaultException (line 8) | public VaultException(String message) {

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultFile.java
  class VaultFile (line 16) | public class VaultFile {
    method VaultFile (line 22) | public VaultFile() {
    method VaultFile (line 26) | private VaultFile(Object content, Header header) {
    method getHeader (line 31) | public Header getHeader() {
    method isEncrypted (line 35) | public boolean isEncrypted() {
    method toJson (line 39) | public JSONObject toJson() {
    method toBytes (line 51) | public byte[] toBytes() {
    method fromJson (line 62) | public static VaultFile fromJson(JSONObject obj) throws VaultFileExcep...
    method fromBytes (line 79) | public static VaultFile fromBytes(byte[] data) throws VaultFileExcepti...
    method getContent (line 88) | public JSONObject getContent() {
    method getContent (line 92) | public JSONObject getContent(VaultFileCredentials creds) throws VaultF...
    method setContent (line 102) | public void setContent(JSONObject obj) {
    method setContent (line 107) | public void setContent(JSONObject obj, VaultFileCredentials creds) thr...
    method exportable (line 124) | public VaultFile exportable() {
    class Header (line 135) | public static class Header {
      method Header (line 139) | public Header(SlotList slots, CryptParameters params) {
      method fromJson (line 144) | public static Header fromJson(JSONObject obj) throws VaultFileExcept...
      method toJson (line 158) | public JSONObject toJson() {
      method getSlots (line 169) | public SlotList getSlots() {
      method getParams (line 173) | public CryptParameters getParams() {
      method isEmpty (line 177) | public boolean isEmpty() {

FILE: app/src/main/java/com/beemdevelopment/aegis/vault/VaultFileCredentials.java
  class VaultFileCredentials (line 14) | public class VaultFileCredentials implements Serializable {
    method VaultFileCredentials (line 18) | public VaultFileCredentials() {
    method VaultFileCredentials (line 23) | public VaultFileCredentials(MasterKey key, SlotList slots) {
    method encrypt (line 28)
Condensed preview — 579 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,173K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 241,
    "preview": "buy_me_a_coffee: beemdevelopment\ncustom:\n  - \"https://www.blockchain.com/btc/address/bc1q26kyxqjkc6tu477pzy0whagwhs4ypv9"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.yml",
    "chars": 2436,
    "preview": "name: Bug Report\ndescription: Create a report to help us fix a bug\nlabels: [\"bug\"]\nbody:\n  - type: markdown\n    attribut"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.md",
    "chars": 98,
    "preview": "---\nname: \"Feature request\"\nabout: \"Suggest a new feature for this project\"\nlabels: proposal\n---\n\n"
  },
  {
    "path": ".github/workflows/build-app-workflow.yaml",
    "chars": 2235,
    "preview": "name: build\non: [pull_request, push]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout the cod"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 1362,
    "preview": "name: codeql\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n  schedule:\n    - cron: '"
  },
  {
    "path": ".github/workflows/crowdin.yml",
    "chars": 842,
    "preview": "name: crowdin\non:\n  push:\n    branches:\n      - master\n# run sequentially (per branch)\nconcurrency: \"crowdin-upload-${{ "
  },
  {
    "path": ".gitignore",
    "chars": 500,
    "preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated file"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4209,
    "preview": "# Contributing\n\nLooking to contribute to Aegis? That's great! There are a couple of ways to help\nout. This document cont"
  },
  {
    "path": "FAQ.md",
    "chars": 4755,
    "preview": "# FAQ\n\n## General\n\n### How can I contribute?\n\nThere are lots of ways! Please refer to our [contributing\nguide](https://g"
  },
  {
    "path": "LICENSE",
    "chars": 35147,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 7639,
    "preview": "<img align=\"left\" width=\"80\" height=\"80\" src=\"metadata/en-US/images/icon.png\"\nalt=\"App icon\">\n\n# Aegis Authenticator\n\n<b"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 8433,
    "preview": "apply plugin: 'com.android.application'\napply plugin: 'com.google.protobuf'\napply plugin: 'dagger.hilt.android.plugin'\na"
  },
  {
    "path": "app/config/libraries/krop.json",
    "chars": 87,
    "preview": "{\n    \"uniqueId\": \"com.github.avito-tech:krop\",\n    \"licenses\": [\n        \"MIT\"\n    ]\n}"
  },
  {
    "path": "app/config/libraries/libsu.json",
    "chars": 104,
    "preview": "{\n    \"uniqueId\": \"com.github.topjohnwu.libsu:.*::regex\",\n    \"licenses\": [\n        \"Apache-2.0\"\n    ]\n}"
  },
  {
    "path": "app/config/libraries/textdrawable.json",
    "chars": 524,
    "preview": "{\n    \"uniqueId\": \"com.amulyakhare:com.amulyakhare.textdrawable\",\n    \"funding\": [\n        \n    ],\n    \"developers\": [\n "
  },
  {
    "path": "app/config/libraries/trustedintents.json",
    "chars": 973,
    "preview": "{\n    \"uniqueId\": \"info.guardianproject.trustedintents:trustedintents\",\n    \"funding\": [\n        \n    ],\n    \"developers"
  },
  {
    "path": "app/config/licenses/3ca920d1875f7ad7ab04a2a331958577.json",
    "chars": 162,
    "preview": "{\n    \"hash\": \"3ca920d1875f7ad7ab04a2a331958577\",\n    \"url\": \"https://github.com/guardianproject/TrustedIntents/blob/mas"
  },
  {
    "path": "app/lint.xml",
    "chars": 573,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<lint>\n    <issue id=\"MissingTranslation\" severity=\"ignore\" />\n    <issue id=\"Mis"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 403,
    "preview": "-keepattributes LineNumberTable,SourceFile\n-renamesourcefileattribute SourceFile\n-dontobfuscate\n\n-keepclasseswithmembers"
  },
  {
    "path": "app/schemas/com.beemdevelopment.aegis.database.AppDatabase/1.json",
    "chars": 1493,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 1,\n    \"identityHash\": \"392278bdb797d013cb2ada67a3b1cc60\",\n    \"e"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java",
    "chars": 7072,
    "preview": "package com.beemdevelopment.aegis;\n\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\nimport androidx.annot"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestApplication.java",
    "chars": 188,
    "preview": "package com.beemdevelopment.aegis;\n\nimport dagger.hilt.android.testing.CustomTestApplication;\n\n@CustomTestApplication(Ae"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/AegisTestRunner.java",
    "chars": 1329,
    "preview": "package com.beemdevelopment.aegis;\n\nimport android.app.Application;\nimport android.app.Instrumentation;\nimport android.c"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java",
    "chars": 18435,
    "preview": "package com.beemdevelopment.aegis;\n\nimport static androidx.test.espresso.Espresso.onView;\nimport static androidx.test.es"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/DeepLinkTest.java",
    "chars": 2192,
    "preview": "package com.beemdevelopment.aegis;\n\nimport static androidx.test.espresso.Espresso.onView;\nimport static androidx.test.es"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/EmptySecretTest.java",
    "chars": 1829,
    "preview": "package com.beemdevelopment.aegis;\n\nimport static androidx.test.espresso.Espresso.onView;\nimport static androidx.test.es"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/IntroTest.java",
    "chars": 8911,
    "preview": "package com.beemdevelopment.aegis;\n\nimport static androidx.test.espresso.Espresso.onView;\nimport static androidx.test.es"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java",
    "chars": 11770,
    "preview": "package com.beemdevelopment.aegis;\n\nimport static androidx.test.espresso.Espresso.onView;\nimport static androidx.test.es"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/PanicTriggerTest.java",
    "chars": 1931,
    "preview": "package com.beemdevelopment.aegis;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertThr"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/rules/ScreenshotTestRule.java",
    "chars": 1136,
    "preview": "package com.beemdevelopment.aegis.rules;\n\nimport android.graphics.Bitmap;\n\nimport androidx.test.runner.screenshot.BasicS"
  },
  {
    "path": "app/src/androidTest/java/com/beemdevelopment/aegis/vault/VaultRepositoryTest.java",
    "chars": 1370,
    "preview": "package com.beemdevelopment.aegis.vault;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.as"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 7542,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:to"
  },
  {
    "path": "app/src/main/assets/changelog.html",
    "chars": 28564,
    "preview": "<html>\n    <head>\n        <style type=\"text/css\">\n            * {\n            word-wrap: break-word;\n            }\n     "
  },
  {
    "path": "app/src/main/assets/license.html",
    "chars": 270,
    "preview": "<html>\n    <head>\n        <style type=\"text/css\">\n            body {\n                background-color: %2$s;\n           "
  },
  {
    "path": "app/src/main/java/com/amulyakhare/textdrawable/LICENSE",
    "chars": 1080,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Amulya Khare\n\nPermission is hereby granted, free of charge, to any person obta"
  },
  {
    "path": "app/src/main/java/com/amulyakhare/textdrawable/TextDrawable.java",
    "chars": 8220,
    "preview": "package com.amulyakhare.textdrawable;\n\nimport android.graphics.*;\nimport android.graphics.drawable.ShapeDrawable;\nimport"
  },
  {
    "path": "app/src/main/java/com/amulyakhare/textdrawable/util/ColorGenerator.java",
    "chars": 1709,
    "preview": "package com.amulyakhare.textdrawable.util;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Random;\n\n/*"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/AccountNamePosition.java",
    "chars": 296,
    "preview": "package com.beemdevelopment.aegis;\n\npublic enum AccountNamePosition {\n    HIDDEN,\n    END,\n    BELOW;\n\n    private stati"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java",
    "chars": 160,
    "preview": "package com.beemdevelopment.aegis;\n\nimport dagger.hilt.android.HiltAndroidApp;\n\n@HiltAndroidApp\npublic class AegisApplic"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/AegisApplicationBase.java",
    "chars": 4658,
    "preview": "package com.beemdevelopment.aegis;\n\nimport android.app.Application;\nimport android.app.NotificationChannel;\nimport andro"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/AegisBackupAgent.java",
    "chars": 5829,
    "preview": "package com.beemdevelopment.aegis;\n\nimport android.app.backup.BackupAgent;\nimport android.app.backup.BackupDataInput;\nim"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/AegisModule.java",
    "chars": 1736,
    "preview": "package com.beemdevelopment.aegis;\n\nimport android.content.Context;\n\nimport androidx.room.Room;\n\nimport com.beemdevelopm"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/BackupsVersioningStrategy.java",
    "chars": 132,
    "preview": "package com.beemdevelopment.aegis;\n\npublic enum BackupsVersioningStrategy {\n    UNDEFINED,\n    MULTIPLE_BACKUPS,\n    SIN"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/CopyBehavior.java",
    "chars": 284,
    "preview": "package com.beemdevelopment.aegis;\n\npublic enum CopyBehavior {\n    NEVER,\n    SINGLETAP,\n    DOUBLETAP;\n\n    private sta"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/EventType.java",
    "chars": 1333,
    "preview": "package com.beemdevelopment.aegis;\n\npublic enum EventType {\n\n    VAULT_UNLOCKED,\n    VAULT_BACKUP_CREATED,\n    VAULT_AND"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/GroupPlaceholderType.java",
    "chars": 496,
    "preview": "package com.beemdevelopment.aegis;\n\npublic enum GroupPlaceholderType {\n    ALL,\n    NEW_GROUP,\n    NO_GROUP;\n\n    public"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/PassReminderFreq.java",
    "chars": 1406,
    "preview": "package com.beemdevelopment.aegis;\n\nimport androidx.annotation.StringRes;\n\nimport java.util.concurrent.TimeUnit;\n\npublic"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/Preferences.java",
    "chars": 22787,
    "preview": "package com.beemdevelopment.aegis;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport and"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/SortCategory.java",
    "chars": 2577,
    "preview": "package com.beemdevelopment.aegis;\n\nimport com.beemdevelopment.aegis.helpers.comparators.LastUsedComparator;\nimport com."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/Theme.java",
    "chars": 286,
    "preview": "package com.beemdevelopment.aegis;\n\npublic enum Theme {\n    LIGHT,\n    DARK,\n    AMOLED,\n    SYSTEM,\n    SYSTEM_AMOLED;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ThemeMap.java",
    "chars": 399,
    "preview": "package com.beemdevelopment.aegis;\n\nimport com.google.common.collect.ImmutableMap;\n\nimport java.util.Map;\n\npublic class "
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/VibrationPatterns.java",
    "chars": 360,
    "preview": "package com.beemdevelopment.aegis;\n\nimport java.util.Arrays;\n\npublic class VibrationPatterns {\n    public static final l"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ViewMode.java",
    "chars": 1399,
    "preview": "package com.beemdevelopment.aegis;\n\nimport androidx.annotation.LayoutRes;\n\npublic enum ViewMode {\n    NORMAL,\n    COMPAC"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/CryptParameters.java",
    "chars": 1149,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\nimport com.beemdevelopment.aegis.encoding.EncodingException;\nimport com.beemd"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/CryptResult.java",
    "chars": 383,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\npublic class CryptResult {\n    private byte[] _data;\n    private CryptParamet"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/CryptoUtils.java",
    "chars": 5468,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\nimport com.beemdevelopment.aegis.crypto.bc.SCrypt;\n\nimport java.io.ByteArrayO"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/KeyStoreHandle.java",
    "chars": 4584,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\nimport android.security.keystore.KeyGenParameterSpec;\nimport android.security"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/KeyStoreHandleException.java",
    "chars": 268,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\npublic class KeyStoreHandleException extends Exception {\n    public KeyStoreH"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKey.java",
    "chars": 2013,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\nimport java.io.IOException;\nimport java.io.Serializable;\nimport java.security"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKeyException.java",
    "chars": 174,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\npublic class MasterKeyException extends Exception {\n    public MasterKeyExcep"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/SCryptParameters.java",
    "chars": 567,
    "preview": "package com.beemdevelopment.aegis.crypto;\n\nimport java.io.Serializable;\n\npublic class SCryptParameters implements Serial"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/bc/SCrypt.java",
    "chars": 8352,
    "preview": "/*\nCopyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)\n\nPermission is hereby gra"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/bc/Salsa20Engine.java",
    "chars": 4511,
    "preview": "/*\nCopyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)\n\nPermission is hereby gra"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/otp/HOTP.java",
    "chars": 1475,
    "preview": "package com.beemdevelopment.aegis.crypto.otp;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.securi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/otp/MOTP.java",
    "chars": 1612,
    "preview": "package com.beemdevelopment.aegis.crypto.otp;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.VisibleFor"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java",
    "chars": 1149,
    "preview": "package com.beemdevelopment.aegis.crypto.otp;\n\nimport androidx.annotation.NonNull;\n\npublic class OTP {\n    private stati"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/otp/TOTP.java",
    "chars": 749,
    "preview": "package com.beemdevelopment.aegis.crypto.otp;\n\nimport java.security.InvalidKeyException;\nimport java.security.NoSuchAlgo"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/otp/YAOTP.java",
    "chars": 2501,
    "preview": "package com.beemdevelopment.aegis.crypto.otp;\n\nimport androidx.annotation.NonNull;\n\nimport java.io.ByteArrayOutputStream"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/crypto/pins/GuardianProjectFDroidRSA2048.java",
    "chars": 4212,
    "preview": "package com.beemdevelopment.aegis.crypto.pins;\n\nimport info.guardianproject.trustedintents.ApkSignaturePin;\n\npublic fina"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java",
    "chars": 419,
    "preview": "package com.beemdevelopment.aegis.database;\n\nimport android.content.Context;\n\nimport androidx.room.Database;\nimport andr"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/database/AuditLogDao.java",
    "chars": 435,
    "preview": "package com.beemdevelopment.aegis.database;\n\nimport androidx.lifecycle.LiveData;\nimport androidx.room.Dao;\nimport androi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/database/AuditLogEntry.java",
    "chars": 1461,
    "preview": "package com.beemdevelopment.aegis.database;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nim"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/database/AuditLogRepository.java",
    "chars": 2019,
    "preview": "package com.beemdevelopment.aegis.database;\n\nimport androidx.lifecycle.LiveData;\n\nimport com.beemdevelopment.aegis.Event"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/encoding/Base32.java",
    "chars": 737,
    "preview": "package com.beemdevelopment.aegis.encoding;\n\nimport com.google.common.io.BaseEncoding;\n\nimport java.nio.charset.Standard"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/encoding/Base64.java",
    "chars": 671,
    "preview": "package com.beemdevelopment.aegis.encoding;\n\nimport com.google.common.io.BaseEncoding;\n\nimport java.nio.charset.Standard"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/encoding/EncodingException.java",
    "chars": 283,
    "preview": "package com.beemdevelopment.aegis.encoding;\n\nimport java.io.IOException;\n\npublic class EncodingException extends IOExcep"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/encoding/Hex.java",
    "chars": 547,
    "preview": "package com.beemdevelopment.aegis.encoding;\n\nimport com.google.common.io.BaseEncoding;\n\nimport java.util.Locale;\n\npublic"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/AnimationsHelper.java",
    "chars": 1983,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\nimport android.provider.Settings;\nimport and"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/BiometricSlotInitializer.java",
    "chars": 4648,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport androidx.annotation.NonNull;\nimport androidx.biometric.BiometricPromp"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/BiometricsHelper.java",
    "chars": 931,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\n\nimport androidx.biometric.BiometricManager;"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/BitmapHelper.java",
    "chars": 2194,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\n\nimpo"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/CenterVerticalSpan.java",
    "chars": 845,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.graphics.Rect;\nimport android.text.TextPaint;\nimport android."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/ContextHelper.java",
    "chars": 1221,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\nimport android.content.ContextWrapper;\n\nimpo"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/DropdownHelper.java",
    "chars": 868,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\nimport android.widget.ArrayAdapter;\nimport a"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/EditTextHelper.java",
    "chars": 720,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.text.Editable;\nimport android.widget.EditText;\n\nimport java.u"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/FabMenuHelper.java",
    "chars": 5373,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Matrix;\nimpo"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/FabScrollHelper.java",
    "chars": 2221,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListener"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/ItemTouchHelperAdapter.java",
    "chars": 1489,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic interface ItemTouc"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/MetricsHelper.java",
    "chars": 375,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\nimport android.util.DisplayMetrics;\n\npublic "
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/PasswordStrengthHelper.java",
    "chars": 2864,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\nimport android.content.res.ColorStateList;\ni"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/PermissionHelper.java",
    "chars": 1351,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeAnalyzer.java",
    "chars": 1958,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport static android.graphics.ImageFormat.YUV_420_888;\n\nimport android.util"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeHelper.java",
    "chars": 3542,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimpor"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/SafHelper.java",
    "chars": 1480,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport andro"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleAnimationEndListener.java",
    "chars": 716,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.view.animation.Animation;\n\npublic class SimpleAnimationEndLis"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleItemTouchHelperCallback.java",
    "chars": 3524,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport static androidx.recyclerview.widget.RecyclerView.NO_POSITION;\n\nimport"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleTextWatcher.java",
    "chars": 744,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.text.Editable;\nimport android.text.TextWatcher;\n\npublic final"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/TextDrawableHelper.java",
    "chars": 1841,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.view.View;\n\nimport com.amulyakhare.textdrawable.TextDrawable;"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/ThemeHelper.java",
    "chars": 2064,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.res.Configuration;\n\nimport androidx.appcompat.app.App"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/UiRefresher.java",
    "chars": 1795,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.os.Handler;\n\nimport com.beemdevelopment.aegis.VibrationPatter"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/UiThreadExecutor.java",
    "chars": 408,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.os.Handler;\nimport android.os.Looper;\n\nimport androidx.annota"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/VibrationHelper.java",
    "chars": 1516,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport android.content.Context;\nimport android.os.Build;\nimport android.os.V"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/ViewHelper.java",
    "chars": 810,
    "preview": "package com.beemdevelopment.aegis.helpers;\n\nimport androidx.core.graphics.Insets;\nimport androidx.core.view.ViewCompat;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/AccountNameComparator.java",
    "chars": 344,
    "preview": "package com.beemdevelopment.aegis.helpers.comparators;\n\nimport com.beemdevelopment.aegis.vault.VaultEntry;\n\nimport java."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/FavoriteComparator.java",
    "chars": 349,
    "preview": "package com.beemdevelopment.aegis.helpers.comparators;\n\nimport com.beemdevelopment.aegis.vault.VaultEntry;\n\nimport java."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/IssuerNameComparator.java",
    "chars": 348,
    "preview": "package com.beemdevelopment.aegis.helpers.comparators;\n\nimport com.beemdevelopment.aegis.vault.VaultEntry;\n\nimport java."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/LastUsedComparator.java",
    "chars": 362,
    "preview": "package com.beemdevelopment.aegis.helpers.comparators;\n\nimport com.beemdevelopment.aegis.vault.VaultEntry;\n\nimport java."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/helpers/comparators/UsageCountComparator.java",
    "chars": 352,
    "preview": "package com.beemdevelopment.aegis.helpers.comparators;\n\nimport com.beemdevelopment.aegis.vault.VaultEntry;\n\nimport java."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/icons/IconPack.java",
    "chars": 6177,
    "preview": "package com.beemdevelopment.aegis.icons;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimpo"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/icons/IconPackException.java",
    "chars": 249,
    "preview": "package com.beemdevelopment.aegis.icons;\n\npublic class IconPackException extends Exception {\n    public IconPackExceptio"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/icons/IconPackExistsException.java",
    "chars": 384,
    "preview": "package com.beemdevelopment.aegis.icons;\n\npublic class IconPackExistsException extends IconPackException {\n    private I"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/icons/IconPackManager.java",
    "chars": 7752,
    "preview": "package com.beemdevelopment.aegis.icons;\n\nimport android.content.Context;\n\nimport androidx.annotation.Nullable;\n\nimport "
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/icons/IconType.java",
    "chars": 1321,
    "preview": "package com.beemdevelopment.aegis.icons;\n\nimport com.google.common.io.Files;\n\nimport java.util.Locale;\n\npublic enum Icon"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/AegisImporter.java",
    "chars": 7132,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.DialogInterface;\n\ni"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java",
    "chars": 11469,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\n\nimport androidx.appcompat.app.AlertDialog"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/AuthenticatorPlusImporter.java",
    "chars": 2648,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\n\nimport com.beemdevelopment.aegis.ui.dialo"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/AuthyImporter.java",
    "chars": 12062,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/BattleNetImporter.java",
    "chars": 4492,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/BitwardenImporter.java",
    "chars": 4482,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.net.Uri;\n\nimport com.beemde"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseImporter.java",
    "chars": 8439,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseImporterEntryException.java",
    "chars": 448,
    "preview": "package com.beemdevelopment.aegis.importers;\n\npublic class DatabaseImporterEntryException extends Exception {\n    privat"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseImporterException.java",
    "chars": 277,
    "preview": "package com.beemdevelopment.aegis.importers;\n\npublic class DatabaseImporterException extends Exception {\n    public Data"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/DuoImporter.java",
    "chars": 3453,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport static java.nio.charset.StandardCharsets.UTF_8;\n\nimport android.con"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/EnteAuthImporter.java",
    "chars": 959,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\n\nimport com.beemdevelopment.aegis.util.IOU"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java",
    "chars": 19775,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpPlusImporter.java",
    "chars": 1794,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/GoogleAuthImporter.java",
    "chars": 5822,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageInfo;\nimp"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/GoogleAuthUriImporter.java",
    "chars": 2478,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\n\nimport com.beemdevelopment.aegis.otp.Goog"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/MicrosoftAuthImporter.java",
    "chars": 4664,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/ProtonAuthenticatorImporter.java",
    "chars": 3212,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport static java.nio.charset.StandardCharsets.UTF_8;\n\nimport android.con"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/SqlImporterHelper.java",
    "chars": 5258,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport static android.database.sqlite.SQLiteDatabase.OPEN_READONLY;\n\nimpor"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/SteamImporter.java",
    "chars": 4101,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageInfo;\nimp"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/StratumImporter.java",
    "chars": 15458,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/TotpAuthenticatorImporter.java",
    "chars": 8915,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/TwoFASImporter.java",
    "chars": 8365,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\n\nimport com.beemdevelopment.aegis.R;\nimpor"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/importers/WinAuthImporter.java",
    "chars": 1331,
    "preview": "package com.beemdevelopment.aegis.importers;\n\nimport android.content.Context;\n\nimport com.beemdevelopment.aegis.vault.Va"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java",
    "chars": 18351,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport android.net.Uri;\n\nimport androidx.annotation.NonNull;\n\nimport com.beemdev"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfoException.java",
    "chars": 1119,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport android.net.Uri;\n\npublic class GoogleAuthInfoException extends Exception "
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/HotpInfo.java",
    "chars": 2322,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport com.beemdevelopment.aegis.crypto.otp.HOTP;\nimport com.beemdevelopment.aeg"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/MotpInfo.java",
    "chars": 2036,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java",
    "chars": 5016,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport com.beemdevelopment.aegis.encoding.Base32;\nimport com.beemdevelopment.aeg"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfoException.java",
    "chars": 244,
    "preview": "package com.beemdevelopment.aegis.otp;\n\npublic class OtpInfoException extends Exception {\n    public OtpInfoException(Th"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/SteamInfo.java",
    "chars": 1319,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport com.beemdevelopment.aegis.crypto.otp.OTP;\nimport com.beemdevelopment.aegi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/TotpInfo.java",
    "chars": 2646,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport com.beemdevelopment.aegis.crypto.otp.OTP;\nimport com.beemdevelopment.aegi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/Transferable.java",
    "chars": 148,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport android.net.Uri;\n\npublic interface Transferable {\n    Uri getUri() throws"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/otp/YandexInfo.java",
    "chars": 5477,
    "preview": "package com.beemdevelopment.aegis.otp;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/receivers/QsTileRefreshReceiver.java",
    "chars": 1163,
    "preview": "package com.beemdevelopment.aegis.receivers;\n\nimport static android.content.Intent.ACTION_BOOT_COMPLETED;\n\nimport androi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/receivers/VaultLockReceiver.java",
    "chars": 1059,
    "preview": "package com.beemdevelopment.aegis.receivers;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/services/LaunchAppTileService.java",
    "chars": 1419,
    "preview": "package com.beemdevelopment.aegis.services;\n\nimport android.annotation.SuppressLint;\nimport android.app.PendingIntent;\ni"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/services/LaunchScannerTileService.java",
    "chars": 1466,
    "preview": "package com.beemdevelopment.aegis.services;\n\nimport android.annotation.SuppressLint;\nimport android.app.PendingIntent;\ni"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/services/NotificationService.java",
    "chars": 2370,
    "preview": "package com.beemdevelopment.aegis.services;\n\nimport android.annotation.SuppressLint;\nimport android.app.PendingIntent;\ni"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/AboutActivity.java",
    "chars": 6190,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.ClipData;\nimport android.content.ClipboardManager;\nimport "
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java",
    "chars": 8906,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.annotation.SuppressLint;\nimport android.app.Activity;\nimport andro"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/AssignIconsActivity.java",
    "chars": 10603,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.Intent;\nimport android.graphics.Rect;\nimport android.graph"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java",
    "chars": 15996,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java",
    "chars": 41242,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.Intent;\nimport android.content.res.Resources;\nimport andro"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/ExitActivity.java",
    "chars": 759,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.conte"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/GroupManagerActivity.java",
    "chars": 8456,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.os.Bundle;\nimport android.view.Menu;\nimport android.view.MenuItem;"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/ImportEntriesActivity.java",
    "chars": 16994,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport a"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/IntroActivity.java",
    "chars": 5644,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport static com.beemdevelopment.aegis.ui.slides.SecurityPickerSlide.CRYPT_TYPE_"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/LicensesActivity.java",
    "chars": 1375,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.os.Bundle;\n\nimport com.beemdevelopment.aegis.Preferences;\nimport c"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java",
    "chars": 61193,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.Manifest;\nimport android.annotation.SuppressLint;\nimport android.c"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/PanicResponderActivity.java",
    "chars": 1720,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.widget.To"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesActivity.java",
    "chars": 4704,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.os.Bundle;\nimport android.view.MenuItem;\n\nimport androidx.annotati"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java",
    "chars": 8810,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bundle;\n"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/TransferEntriesActivity.java",
    "chars": 8481,
    "preview": "package com.beemdevelopment.aegis.ui;\n\nimport android.content.ClipData;\nimport android.content.ClipDescription;\nimport a"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/components/DropdownCheckBoxes.java",
    "chars": 5846,
    "preview": "package com.beemdevelopment.aegis.ui.components;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/components/NoAutofillEditText.java",
    "chars": 974,
    "preview": "package com.beemdevelopment.aegis.ui.components;\n\nimport android.content.Context;\nimport android.os.Build;\nimport androi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/ChangelogDialog.java",
    "chars": 560,
    "preview": "package com.beemdevelopment.aegis.ui.dialogs;\n\nimport android.content.Context;\n\nimport com.beemdevelopment.aegis.R;\n\npub"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/Dialogs.java",
    "chars": 31840,
    "preview": "package com.beemdevelopment.aegis.ui.dialogs;\n\nimport android.app.Dialog;\nimport android.content.ClipData;\nimport androi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/IconPickerDialog.java",
    "chars": 6203,
    "preview": "package com.beemdevelopment.aegis.ui.dialogs;\n\nimport android.app.Activity;\nimport android.graphics.drawable.Drawable;\ni"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/LicenseDialog.java",
    "chars": 615,
    "preview": "package com.beemdevelopment.aegis.ui.dialogs;\n\nimport android.content.Context;\n\nimport com.beemdevelopment.aegis.R;\n\npub"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/SimpleWebViewDialog.java",
    "chars": 3526,
    "preview": "package com.beemdevelopment.aegis.ui.dialogs;\n\nimport android.annotation.SuppressLint;\nimport android.app.Dialog;\nimport"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AppearancePreferencesFragment.java",
    "chars": 10178,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.content.Intent;\nimport android.os.Build;\nimp"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AuditLogPreferencesFragment.java",
    "chars": 4099,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.graphics.Rect;\nimport android.os.Bundle;\nimp"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BackupsPreferencesFragment.java",
    "chars": 14384,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.app.Activity;\nimport android.content.Intent;"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BehaviorPreferencesFragment.java",
    "chars": 5506,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.os.Bundle;\nimport android.widget.Button;\n\nim"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/IconPacksManagerFragment.java",
    "chars": 8012,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.app.Activity;\nimport android.content.Intent;"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java",
    "chars": 25979,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.app.Activity;\nimport android.content.Intent;"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/MainPreferencesFragment.java",
    "chars": 350,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.os.Bundle;\n\nimport com.beemdevelopment.aegis"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/PreferencesFragment.java",
    "chars": 3586,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nim"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java",
    "chars": 21135,
    "preview": "package com.beemdevelopment.aegis.ui.fragments.preferences;\n\nimport static android.text.TextUtils.isDigitsOnly;\n\nimport "
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/glide/AegisGlideModule.java",
    "chars": 1076,
    "preview": "package com.beemdevelopment.aegis.ui.glide;\n\nimport android.content.Context;\nimport android.graphics.drawable.PictureDra"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/glide/GlideHelper.java",
    "chars": 4318,
    "preview": "package com.beemdevelopment.aegis.ui.glide;\n\nimport android.graphics.drawable.Drawable;\nimport android.os.Build;\nimport "
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/glide/SvgBytesDecoder.java",
    "chars": 1062,
    "preview": "package com.beemdevelopment.aegis.ui.glide;\n\nimport androidx.annotation.NonNull;\n\nimport com.bumptech.glide.load.Options"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/glide/SvgDecoder.java",
    "chars": 1585,
    "preview": "package com.beemdevelopment.aegis.ui.glide;\n\nimport androidx.annotation.NonNull;\n\nimport com.beemdevelopment.aegis.icons"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/glide/SvgDrawableTranscoder.java",
    "chars": 1125,
    "preview": "package com.beemdevelopment.aegis.ui.glide;\n\nimport android.graphics.Picture;\nimport android.graphics.drawable.PictureDr"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/glide/VaultEntryIconKey.java",
    "chars": 698,
    "preview": "package com.beemdevelopment.aegis.ui.glide;\n\nimport androidx.annotation.NonNull;\n\nimport com.beemdevelopment.aegis.vault"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/glide/VaultEntryIconLoader.java",
    "chars": 2337,
    "preview": "package com.beemdevelopment.aegis.ui.glide;\n\nimport androidx.annotation.NonNull;\n\nimport com.beemdevelopment.aegis.icons"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroActivityInterface.java",
    "chars": 703,
    "preview": "package com.beemdevelopment.aegis.ui.intro;\n\nimport android.os.Bundle;\n\nimport androidx.annotation.NonNull;\n\npublic inte"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroBaseActivity.java",
    "chars": 8035,
    "preview": "package com.beemdevelopment.aegis.ui.intro;\n\nimport android.os.Bundle;\nimport android.view.View;\n\nimport androidx.activi"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/intro/SlideFragment.java",
    "chars": 2268,
    "preview": "package com.beemdevelopment.aegis.ui.intro;\n\nimport android.content.Context;\nimport android.os.Bundle;\n\nimport androidx."
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/intro/SlideIndicator.java",
    "chars": 3253,
    "preview": "package com.beemdevelopment.aegis.ui.intro;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimpo"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/models/AssignIconEntry.java",
    "chars": 917,
    "preview": "package com.beemdevelopment.aegis.ui.models;\n\nimport com.beemdevelopment.aegis.icons.IconPack;\nimport com.beemdevelopmen"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/models/AuditLogEntryModel.java",
    "chars": 698,
    "preview": "package com.beemdevelopment.aegis.ui.models;\n\nimport com.beemdevelopment.aegis.database.AuditLogEntry;\nimport com.beemde"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/models/ErrorCardInfo.java",
    "chars": 1031,
    "preview": "package com.beemdevelopment.aegis.ui.models;\n\nimport android.view.View;\n\nimport com.google.common.hash.HashCode;\n\nimport"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/models/ImportEntry.java",
    "chars": 878,
    "preview": "package com.beemdevelopment.aegis.ui.models;\n\nimport com.beemdevelopment.aegis.vault.VaultEntry;\n\nimport java.io.Seriali"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/models/VaultGroupModel.java",
    "chars": 1435,
    "preview": "package com.beemdevelopment.aegis.ui.models;\n\nimport android.content.Context;\n\nimport androidx.annotation.NonNull;\nimpor"
  },
  {
    "path": "app/src/main/java/com/beemdevelopment/aegis/ui/preferences/SwitchPreference.java",
    "chars": 1396,
    "preview": "package com.beemdevelopment.aegis.ui.preferences;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\n\nim"
  }
]

// ... and 379 more files (download for full content)

About this extraction

This page contains the full source code of the beemdevelopment/Aegis GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 579 files (3.8 MB), approximately 1.0M tokens, and a symbol index with 2633 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!