If the animator scale setting is set to 0, the progress bar refresher would run
in a tight loop. This issue was introduced by
93cc945a2c and caused the UI tests to fail.
Apparently onResume of MainActivity is sometimes called even if it's not the top
level activity, causing IntroActivity or AuthActivity to be launched twice. This
patch (uglily) prevents that from happening.
This is a different take on what db681273e6 was
trying to accomplish, with the additional benefit that the prompt will now no
longer be shown on auto-lock.
This removes the dependency on ``me.dm7.barcodescanner:zxing`` and replaces it
with our own QR code scanner implementation using CameraX and ZXing. The main
reason for this change is to hopefully get better compatibility with obscure
devices. The barcodescanner library we were previously using seems unmaintained,
while Google is apparently putting a lot of effort into CameraX.
ScannerActivity has been almost entirely rewritten, but the functionality is
exactly the same as before.
We're looking for android.security.KeyStoreException as the cause of
ProviderException, not java.security.KeyStoreException. Unfortunately this is a
hidden class, so all we can do is check the class name.
We don't actually need this, and I have a feeling that it may be causing some of
the inexplicable crashes we're seeing in the Play Console. For example:
apparently the app sometimes gets itself into a state where the vault is
unlocked, but the user is still shown AuthActivity (possibly due to it being
launched twice). I can't prove that "singleTask" causes this, as I can't
reproduce the issue on my device or an emulator, but it's the only odd thing we
have in our activity lifecycle handling.
Test plan:
- Go through the intro, add an entry, change some settings, etc
- See if the app shortcuts still work. Scenarios:
- The app is terminated.
- The app is locked.
- MainActivity is open.
- Some other activity is open.
- See if auto-locking still works. Scenarios:
- The app is locked.
- MainActivity is open.
- Some other activity is open.
- Turn on "Don't keep activities" in developer options and repeat the above
steps.
We previously stopped/started the biometric prompt every time in
onPause/onResume, but that's apparently not necessary (and discouraged according
to the documentation). This caused issues where the prompt would get stuck on
some devices. While working on this I ran into another issue where AuthActivity
was closed and reopened for no reason after rotation of the device, compounding
the issue. This patch also fixes that.
This patch ensures that we also copy over any files related to the SQLite
database (databases-shm, databases-wal, databases-journal) when copying it from
an app's internal storage.
This patch improves our backup functionality in a number of ways:
- Only backup the vault when important changes are made, not when the order of
entries is changed, for instance.
- Don't bubble up backup errors when saving the vault.
- Instead, show an error bar in the main view if the most recent backup attempt
failed.
<img src="https://alexbakker.me/u/kbhhj2hcgx.png" width="300" />
Clicking on the error bar will take the user to the backup settings.
This patch adds an initial set of UI tests for Aegis built using Espresso. It
covers a fair bit of the essential functionality of the app, but there are lots
more tests we could add later on.
This also reconfigures our Travis CI build manifest to run the tests on API 21,
23, 27 and 28 emulators. It was a real pain to get this to work well, but let's
hope it's stable now.
I had to downgrade ``com.google.android.material`` to 1.0.0, because 1.1.0
introduced an issue where the test would hang.
This fixes a number of issues that can happen when navigating back to previous
slides, by disabling back navigation entirely. One such issue is that when
navigating back from the last slide, one would always land on the
password/biometrics setup slide, even if "none" was selected on the security
picker slide.
These larger numbers of iterations cause the key derivation process to take
longer, so I also moved that task to the background. andOTP now also has a
proper "issuer" field, so we make use of that as well.
Also fixes an issue where padded base32 could not be decoded. This issue is only
present for the andOTP importer as far as I know, so that's why that change is
included here.
Also fixes another issue where previously, if a user made it to the last intro
slide and then navigated back to change the security options, any changes would
be ignored.
This improves the entry icon editing flow as suggested in #252:
- Add an "Edit icon" menu item
- Save the icon even if the checkmark was not clicked
- Exit icon edit mode with the back button
Close#252.
We only use Bouncy Castle for scrypt, so replacing the security provider was a
nice to have. It's causing issues because Proguard removes Bouncy Castle
classes. As we just released a beta, this is a quick fix and we may revisit this
later.
SpongyCastle is a fork of BouncyCastle. We originally used this fork to 1) have
access to scrypt and 2) prevent a package name collision with the bundled
BouncyCastle. We don't actually need to use the fork anymore, because the
package name of the bundled BouncyCastle was changed in Android. SpongyCastle
has also gotten quite outdated in recent years.
The built-in version of BouncyCastle is replaced with the one bundled with the
app at runtime, so that we have a recent version even on older Android versions.
This also updates Gradle and the Gradle Android plugin, to fix a build error I
was running into when I added the dependency to BouncyCastle.
This fixes an issue where the existing PreferencesFragment was discarded when
restoring PreferencesActivity from instance state. This issue caused the
PreferencesFragment to no longer receive activity results. Most notably, this
resulted in 0 byte vault files being created when exporting the vault.
This'll display a warning to users who don't have automatic time synchronization
enabled on their device. Aegis will try to take the user to the right settings
menu if they tap "Yes". Users also have the option to silence the warning.
[<img width=300 src="https://alexbakker.me/u/jf1o8087lr.png">](https://alexbakker.me/u/jf1o8087lr.png)
The main goals of this patch are to:
- Improve the exception handling in Aegis and the way we present errors messages
to the user when they occur.
- Write exception stack traces to the log in more places, so that the ADB logs
we ask for from our users when reporting bugs become more useful.
- Reduce the amount of times we throw a RuntimeException, particularly when an
Android Keystore operation fails.
Achieving the above goals ended up resulting in a very large refactor. The
intro and unlock flow of the app need to be retested entirely.
This makes it so that EditEntryActivity directly saves entries to the vault,
instead of passing them back to MainActivity through an Intent first. This
prevents crashes that can occur when an entry has a large icon and the Bundle
inside the Intent becomes too large.
This is the first part of a series of patches I plan on submitting, where I try
to repair the damage done by my misguided obsession of only touching the global
state in certain places.