The stats might become null between these two checks, when a tunnel
flips off, resulting in a null pointer dereference:
at com.wireguard.android.model.ObservableTunnel.getStatisticsAsync (ObservableTunnel.java:103)
at com.wireguard.android.fragment.TunnelDetailFragment.updateStats (TunnelDetailFragment.java:108)
at com.wireguard.android.fragment.TunnelDetailFragment.access$updateStats (TunnelDetailFragment.java:27)
at com.wireguard.android.fragment.TunnelDetailFragment$onResume$1.run (TunnelDetailFragment.java:74)
at java.util.TimerThread.mainLoop (TimerThread.java:562)
at java.util.TimerThread.run (TimerThread.java:512)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
When tunnel deletion is triggered we don't bother with animation theatrics
because the resulting Snackbar needs this fab to be its anchor, which it can't
do if its outside the screen or busy animating.
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Long press a tunnel item. SIGKILL the app. Reenter it. Boom:
kotlin.KotlinNullPointerException:
at com.wireguard.android.fragment.TunnelListFragment$ActionModeListener.onCreateActionMode (TunnelListFragment.java:347)
at androidx.appcompat.app.AppCompatDelegateImpl$ActionModeCallbackWrapperV9.onCreateActionMode (AppCompatDelegateImpl.java:2442)
at androidx.appcompat.app.WindowDecorActionBar$ActionModeImpl.dispatchOnCreate (WindowDecorActionBar.java:1062)
at androidx.appcompat.app.WindowDecorActionBar.startActionMode (WindowDecorActionBar.java:530)
at androidx.appcompat.app.AppCompatDelegateImpl.startSupportActionMode (AppCompatDelegateImpl.java:1055)
at androidx.appcompat.app.AppCompatActivity.startSupportActionMode (AppCompatActivity.java:316)
at com.wireguard.android.fragment.TunnelListFragment$ActionModeListener.setItemChecked (TunnelListFragment.java:371)
at com.wireguard.android.fragment.TunnelListFragment.onActivityCreated (TunnelListFragment.java:174)
at androidx.fragment.app.Fragment.performActivityCreated (Fragment.java:2717)
at androidx.fragment.app.FragmentStateManager.activityCreated (FragmentStateManager.java:346)
at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1188)
at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:161)
at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:5)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState (FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState (FragmentManager.java:5)
at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1497)
at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:389)
at androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:677)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated (FragmentManager.java:2577)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated (FragmentManager.java:9)
at androidx.fragment.app.FragmentController.dispatchActivityCreated (FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart (FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart (AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart (Instrumentation.java:1440)
at android.app.Activity.performStart (Activity.java:8109)
at android.app.ActivityThread.handleStartActivity (ActivityThread.java:3806)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence (TransactionExecutor.java:235)
at android.app.servertransaction.TransactionExecutor.cycleToPath (TransactionExecutor.java:215)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:187)
at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:105)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2386)
at android.os.Handler.dispatchMessage (Handler.java:107)
at android.os.Looper.loop (Looper.java:213)
at android.app.ActivityThread.main (ActivityThread.java:8178)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1101)
This commit avoids the crash. But it's not clear to me that this is
really the right solution. However, in testing it appears to work.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
When biometric hardware is available, it will be used to authenticate
the user before private keys are shown on screen or when zip exports
are executed.
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
The tunnel/ module still uses it and exposes it as an "api", but nothing
inside of ui/ should be using it now.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>