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.
This enables some minification and optimization options to shrink the size of
our APK. A release APK would previously be 12 MB in size, but would now be 8.2
MB.
To test, check if *all* of the functionality of the app still works,
particularly parts that refer to dependencies. You'll know if ProGuard broke
something when the app crashes with a ``ClassNotFoundException`` or similar
exception. I think I've covered all of the cases where ProGuard removed too much
in the rule file.
Also, I was curious why our APK had gotten so large to begin with. I did some
digging and found that this is caused by the SQLCipher dependency. The APK
shrinks down to 2.7 MB without it! We should consider whether having support for
importing from Authenticator Plus is worth the extra 5.5 MB in size.
I noticed a strange crash in the Play Console:
```
android.view.WindowManager$BadTokenException:
at android.view.ViewRootImpl.setView (ViewRootImpl.java:828)
at android.view.WindowManagerGlobal.addView (WindowManagerGlobal.jav>
at android.view.WindowManagerImpl.addView (WindowManagerImpl.java:93)
at android.widget.PopupWindow.invokePopup (PopupWindow.java:1434)
at android.widget.PopupWindow.showAsDropDown (PopupWindow.java:1284)
at android.widget.PopupWindow.showAsDropDown (PopupWindow.java:1240)
at android.widget.PopupWindow.showAsDropDown (PopupWindow.java:1219)
at com.beemdevelopment.aegis.ui.AuthActivity.lambda$showPasswordRemi>
at com.beemdevelopment.aegis.ui.-$$Lambda$AuthActivity$WWHxRKllBPcyH>
at android.os.Handler.handleCallback (Handler.java:873)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loop (Looper.java:220)
at android.app.ActivityThread.main (ActivityThread.java:6929)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (Runt>
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:870)
```
I can't reproduce this on my device, and we haven't received any reports from
users, but it would be pretty bad if Aegis crashes on some devices when showing
the password reminder popup. This patch is an attempt to fix that (see:
https://stackoverflow.com/a/33809860/12972657).
added two new theme options:
SYSTEM: dynamically switches between light and dark
SYSTEM_AMOLED: dynamically switches between light and amoled
reversed workaround for amoled themed preferences
launch screen now always follows the system theme
Changed selection color for black theme
Changed indicator color to black secondary
Fix indicator flickering when scrolling
Applied patch
Fix unsharp selection icon
Add selection indicators to small and compact view
The APK released to the Play Store has versionCode set to 29 instead of 28,
because the update had to be resubmitted due to an erroneous rejection by
Google.
Adds support for importing TOTP and Microsoft accounts from Microsoft
Authenticator. Microsoft accounts also use TOTP, but with 8 digits instead
of 6.
This implementation suffers from the same bug (#82) as Google Authenticator, but I
haven't thought of a nice way to solve it yet. We should fix that before
including this feature in a release, though.
This adds a recovery mechanism for (probably extremely rare) cases where the app
may be killed before it is finished writing the vault file to disk. In the
example below, we see that AtomicFile moved ``aegis.json`` to ``aegis.json.bak``
before writing to ``aegis.json``.
```
bonito:/ # ls -lah /data/data/com.beemdevelopment.aegis.debug/files
total 27M
drwxrwx--x 2 u0_a306 u0_a306 3.4K 2020-02-02 13:22 .
drwx------ 6 u0_a306 u0_a306 3.4K 2020-02-01 19:51 ..
-rw------- 1 u0_a306 u0_a306 19M 2020-02-02 13:22 aegis.json
-rw------- 1 u0_a306 u0_a306 34M 2020-02-02 13:21 aegis.json.bak
```
Because the app was killed before it could
finish writing, it is only 19M in size, instead of the expected 34M. The next
time the app starts, AtomicFile will notice that the .bak file is still present,
and use that instead of the corrupted ``aegis.json`` file.
I kept the classes in the encoding package and turned them into wrappers for
Guava. I also changed the functions in the Base32 class to take and return
strings insteads if character arrays.
Instead of showing the reminder after x unlocks, I decided to show the reminder
2 weeks after the vault was last unlocked with the password. Let me know if you
agree with that.

We noticed after the v1.1 release that we need to switch our external storage
access code over to use the Storage Access Framework. The export functionality
was the only piece of code that still used the deprecated method and this patch
addresses that.
The Storage Access Framework is a little annoying to work with, but I don't
think it'll be too painful for our usecase. This switch comes with some nice
benefits for users as well. Users are now able to select a custom storage
location, which can be local or in the cloud.
This also removes ``requestLegacyExternalStorage`` from the manifest, as we
don't need it anymore.
We decided on calling the state file the "vault" a while back. This patch makes
the naming consistent across the codebase. I left "DatabaseImporter" classes
alone, because I'm not sure what a better name for those would be.
This patch replaces the usage of the deprecated FingerprintManager API with
BiometricPrompt. This uses the Android X library, so we get the native biometric
prompt on recent versions of Android and a Google-made one on older versions. By
not working with custom prompts for biometric authentication like we do now, we
can be sure that any issues like #70, #81, #237 are not actually our fault.
Here's what it looks like:

As a nice aside, this also adds support for the new facial recognition as an
authentication method on Pixel 4 phones.
This is still a draft, but early feedback is welcome.
I think this makes the highlight/reveal functionality feel a bit more
consistent, by not allowing multiple entries to be revealed at the same time,
just like you can't have multiple highlighted entries. Here's video of what it
looks like: https://alexbakker.me/u/3a9dhplrj2.mp4.