This commit should fix the problem where VPN connection is viewed as metered connections on Android P DP1. However as I only have an emulator to test, I can't tell if it really works but it should.
An interesting observation is that the developer can call setUnderlyingNetworks(arrayOfNulls(1)) to make the VPN connection always unmetered. This is more of a quick hack instead of a real fix. Source: https://android.googlesource.com/platform/frameworks/base/+/adbf1d0/services/core/java/com/android/server/connectivity/Vpn.java#312
One may ask whether it's possible to fix this issue for Android 8.1. The short answer is not that I know of.
After some intensive source code reading, I found out that this is the commit that "breaks" whether VPN is metered for Android 8.1: https://android.googlesource.com/platform/frameworks/base/+/43d2a1700b6eb1d804924c6a1e5e0161a13a5348%5E%21/
The key is that isActiveNetworkMetered() used to return getActiveNetworkInfo().isMetered() and now it uses the more up-to-date API getActiveNetwork(). However, getActiveNetworkInfo() ignores VPN connections while getActiveNetwork() prefers VPN connection. And since NetworkCapabilities for VPN Network is always metered by default, this ultimately causes the bug. One might be able to get around this bug by somehow calling NetworkAgent.sendNetworkCapabilities in the correct context.
Fix#1666.
It should run 9x faster than before now.
Past mistakes:
* InetAddress.parseNumericAddress throws TWO exceptions underthehood if the string passed is invalid. This caused a huge overhead;
* CharSequence.split in Kotlin is EXTREMELY SLOW.
To do direct boot, important files need to be moved to device storage (i.e. not as safe storage). The only thing sensitive is user credentials (server settings in each profile) and the config file passed to libss-*.so. In order to implement direct boot, at least the active profile has to be moved/copied to device storage.
This commit keeps profile information (and temporary data used by ProfileConfigFragment) and Shadowsocks config in credential storage and move everything else to device storage. In order to make direct boot work, active profile is also copied into device storage and Shadowsocks config file is created in device storage during direct boot. Cleanup of those information is also implemented.
Fixes#1457.
NB:
* `android:directBootAware` can't be used on application element. That seems to be used by system apps.
* Works fine with multi-user;
* Old GSM files are not migrated (see App.kt) to device storage.