Not sure when this happens exactly, in particular because the reported
stack traces look like this
java.lang.NullPointerException:
at org.strongswan.android.ui.VpnTileService.updateTile (VpnTileService.java:220)
at org.strongswan.android.ui.VpnTileService.onStartListening (VpnTileService.java:97)
at android.service.quicksettings.TileService$H.handleMessage (TileService.java:407)
which violates the API documentation for getQsTile(), which states:
This tile is only valid for updates between onStartListening() and
onStopListening().
But apparently that's not always the case. There have been two reports
of such a crash, both on Android 8.0 and on Xiaomi Mi 5/6 devices, so
maybe it's a bug in that particular image.
The previous code lost track of the selected profile IDs, but the
widgets maintained their state (i.e. the list item was still selected and the
edit button still enabled). Clicking the edit button then caused a crash when
trying to get the first item in the set.
This reverts commit 064c97afae.
We have to make this optional and more configurable. It seems some
commercial VPN providers use self-signed certificates for their AAA
servers.
This avoids a NullPointerException on Android 8 related to the optional
Autofill functionality. The bug has been fixed in Android 8.1 [1] but there
is no fix for Android 8.
[1] https://issuetracker.google.com/issues/67675432
This is hopefully a bit more efficient for large log files than the previous
single TextView. The ListView widget also provides an auto-scroll mechanism.
Always reset the error state when disconnecting via state service. This
way the error state is also cleared when the connection is terminated
directly via control activity.
For instance, rotating a device will restart it and this previously
could have started the wrong profile or shown the system's VPN
confirmation dialog twice.
As documented, onActivityResult() is called right before onResume() when
the activity is reactivated. However, if the system's VPN confirmation
dialog is shown and the home button is pressed, the activity is stopped
and not just paused, so its state is saved. And onActivityResult() is
actually also called before onStart(). This means that no fragment
transactions may be committed (i.e. no dialog may be shown) when the
activity is later restarted (e.g. because there is another attempt to
connect the VPN) until onStart() has been called. So if we'd try to show
the error dialog in onActivityResult() after returning to the launcher
it would result in an IllegalStateException.
However, showing the dialog for the previous confirmation dialog is not
ideal anyway, so we just ignore that result.
This allows cancelling connecting if e.g. the OCSP server is not
reachable. Previously this caused some delay in disconnecting state but
even worse it cause an ANR if the user tried reconnecting during that
time as the main thread would get struck in setNextProfile() (we could
probably find a better solution there too in the future).
It's reinstalled when reconnecting (or during error recovery) and
eventually uninstalled after disconnecting.
Only on Android 5+, otherwise we'd block our fetcher (and Android 4.4 is
stupid in regards to overlapping TUN devices anyway).
Note that Android 8's blocking feature blocks everything that passes by
the VPN, so this only works when tunneling everything (i.e. neither subnets,
nor apps can be excluded from the VPN if that feature is enabled).
Otherwise, a blocking VPN interface would prevent our fetcher from working
as we currently rely on an interface that doesn't allow access to the
underlying socket/FD, which would be required to call VpnService.protect().
The button to view the log is now below the status info. And since the
IMC results are just below that we don't need a special handling for
that anymore.
This can happen on systems (e.g. Android 7.x) where Always-on VPNs are
triggered right after booting before the KeyChain is unlocked by the user.
Retrieving the certificate chain or private key then fails with
"KeyChainException: IllegalStateException: keystore is LOCKED" until the
user unlocks the screen once.
The built-in client actually also fails in this situation (e.g. with XAuth
RSA), it tries three times then stops and shows an error notification.