summaryrefslogtreecommitdiffhomepage
path: root/ui/src/main/java
AgeCommit message (Collapse)Author
2023-05-26ui: add basic double update guardJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-26ui: remove debug keysJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-11ui: use modal corruption alert instead of snackbarJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-11ui: use applicationScope helper when possibleJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-11ui: cleanup quick tile and modernizeJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-10ui: add shortcut for adding quick settings tileJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-10ui: bifurcate only parts of release but nag about wrong contextJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-08ui: use debug key in debug buildsJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-08ui: only register contracts in constructorsJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-08gradle: restore play runtime detectionJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-05ui: reformat all codeJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-05ui: collect logs from IO thread onlyJason A. Donenfeld
Otherwise the pop() from the producer might causes an OOB read in the consumer: Exception java.lang.ArrayIndexOutOfBoundsException: at androidx.collection.CircularArray.get (CircularArray.java) at com.wireguard.android.activity.LogViewerActivity.rawLogBytes (LogViewerActivity.java) at com.wireguard.android.activity.LogViewerActivity.onCreate$lambda$3 (LogViewerActivity.java:133) at android.view.View.performClick (View.java:6935) at android.view.View$PerformClick.run (View.java:26214) at android.os.Handler.handleCallback (Handler.java:790) at android.os.Handler.dispatchMessage (Handler.java:99) at android.os.Looper.loop (Looper.java:164) at android.app.ActivityThread.main (ActivityThread.java:7000) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:441) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1408) Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-04gradle: remove runtime detection of play storeJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-03ui: update cleanupsJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-05ui: use .seconds instead of .toDurationJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-01ui: handle update signaturesJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-24ui: display latest handshake timeJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-13ui: LogViewerActivity: cleanup ret valJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-12ui: further reduce log viewer memory usageJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-11tunnel: defer enabling strict mode until laterJason A. Donenfeld
Startup code can be synchronous. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-07ui: always show visible localized error messagesJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-07ui: set app list button text on main threadJason A. Donenfeld
Hopefully will fix, "Only the original thread that creted a view hierarchy can touch its views." Reported-by: Damir <2k1dmg@gmail.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-05ui: allow vetoing tunnel selection changesJason A. Donenfeld
These changes can happen at the wrong time, so we need to be able to walk them back. Fixes: Exception java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at androidx.fragment.app.FragmentManager.checkStateLoss (FragmentManager.java:1610) at androidx.fragment.app.FragmentManager.enqueueAction (FragmentManager.java:1650) at androidx.fragment.app.BackStackRecord.commitInternal (BackStackRecord.java:341) at androidx.fragment.app.BackStackRecord.commit (BackStackRecord.java:306) at androidx.fragment.app.FragmentManagerKt.commit$default (FragmentManager.kt:35) at com.wireguard.android.activity.MainActivity.onSelectedTunnelChanged (MainActivity.kt:113) at com.wireguard.android.activity.BaseActivity.setSelectedTunnel (BaseActivity.kt:25) at com.wireguard.android.activity.BaseActivity$onCreate$1.invokeSuspend (BaseActivity.kt:44) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33) at kotlinx.coroutines.internal.DispatchedContinuation.resumeUndispatchedWith (DispatchedContinuation.java:256) at kotlinx.coroutines.DispatchedTaskKt.resume (DispatchedTask.kt:177) at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core (CancellableContinuationImpl.kt:190) at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined (DispatchedTask.kt:190) at kotlinx.coroutines.DispatchedTaskKt.dispatch (DispatchedTask.kt:161) at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume (CancellableContinuationImpl.kt:397) at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl (CancellableContinuationImpl.kt:431) at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default (CancellableContinuationImpl.kt:420) at kotlinx.coroutines.CancellableContinuationImpl.resumeWith (CancellableContinuationImpl.kt:328) at kotlinx.coroutines.ResumeAwaitOnCompletion.invoke (JobSupport.kt:1413) at kotlinx.coroutines.JobSupport.notifyHandlers (JobSupport.kt:368) at kotlinx.coroutines.JobSupport.notifyCompletion (JobSupport.kt:362) at kotlinx.coroutines.JobSupport.completeStateFinalization (JobSupport.kt:323) at kotlinx.coroutines.JobSupport.finalizeFinishingState (JobSupport.kt:240) at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath (JobSupport.kt:906) at kotlinx.coroutines.JobSupport.tryMakeCompleting (JobSupport.kt:863) at kotlinx.coroutines.JobSupport.makeCompleting$kotlinx_coroutines_core (JobSupport.kt:806) at kotlinx.coroutines.CompletableDeferredImpl.complete (CompletableDeferredImpl.java:92) at com.wireguard.android.model.TunnelManager$onTunnelsLoaded$1.invokeSuspend (TunnelManager.kt:120) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106) at android.os.Handler.handleCallback (Handler.java:938) at android.os.Handler.dispatchMessage (Handler.java:99) at android.os.Looper.loop (Looper.java:237) at android.app.ActivityThread.main (ActivityThread.java:8163) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:656) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:967) Exception java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at androidx.fragment.app.FragmentManager.checkStateLoss (FragmentManager.java:1610) at androidx.fragment.app.FragmentManager.enqueueAction (FragmentManager.java:1650) at androidx.fragment.app.BackStackRecord.commitInternal (BackStackRecord.java:341) at androidx.fragment.app.BackStackRecord.commit (BackStackRecord.java:306) at androidx.fragment.app.FragmentManagerKt.commit$default (FragmentManager.kt:35) at com.wireguard.android.activity.MainActivity.onSelectedTunnelChanged (MainActivity.kt:113) at com.wireguard.android.activity.BaseActivity.setSelectedTunnel (BaseActivity.kt:25) at com.wireguard.android.activity.BaseActivity$onCreate$1.invokeSuspend (BaseActivity.kt:44) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33) at kotlinx.coroutines.internal.DispatchedContinuation.resumeUndispatchedWith (DispatchedContinuation.java:256) at kotlinx.coroutines.DispatchedTaskKt.resume (DispatchedTask.kt:177) at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core (CancellableContinuationImpl.kt:190) at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined (DispatchedTask.kt:190) at kotlinx.coroutines.DispatchedTaskKt.dispatch (DispatchedTask.kt:161) at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume (CancellableContinuationImpl.kt:397) at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl (CancellableContinuationImpl.kt:431) at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default (CancellableContinuationImpl.kt:420) at kotlinx.coroutines.CancellableContinuationImpl.resumeWith (CancellableContinuationImpl.kt:328) at kotlinx.coroutines.ResumeAwaitOnCompletion.invoke (JobSupport.kt:1413) at kotlinx.coroutines.JobSupport.notifyHandlers (JobSupport.kt:368) at kotlinx.coroutines.JobSupport.notifyCompletion (JobSupport.kt:362) at kotlinx.coroutines.JobSupport.completeStateFinalization (JobSupport.kt:323) at kotlinx.coroutines.JobSupport.finalizeFinishingState (JobSupport.kt:240) at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath (JobSupport.kt:906) at kotlinx.coroutines.JobSupport.tryMakeCompleting (JobSupport.kt:863) at kotlinx.coroutines.JobSupport.makeCompleting$kotlinx_coroutines_core (JobSupport.kt:806) at kotlinx.coroutines.CompletableDeferredImpl.complete (CompletableDeferredImpl.java:92) at com.wireguard.android.model.TunnelManager$onTunnelsLoaded$1.invokeSuspend (TunnelManager.kt:120) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106) at android.os.Handler.handleCallback (Handler.java:938) at android.os.Handler.dispatchMessage (Handler.java:99) at android.os.Looper.loopOnce (Looper.java:210) at android.os.Looper.loop (Looper.java:299) at android.app.ActivityThread.main (ActivityThread.java:8302) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:556) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1037) Exception java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at androidx.fragment.app.FragmentManager.checkStateLoss (FragmentManager.java:1610) at androidx.fragment.app.FragmentManager.ensureExecReady (FragmentManager.java:1711) at androidx.fragment.app.FragmentManager.execPendingActions (FragmentManager.java:1754) at androidx.fragment.app.FragmentManager.popBackStackImmediate (FragmentManager.java:854) at androidx.fragment.app.FragmentManager.popBackStackImmediate (FragmentManager.java:778) at com.wireguard.android.activity.MainActivity.onSelectedTunnelChanged (MainActivity.kt:110) at com.wireguard.android.activity.BaseActivity.setSelectedTunnel (BaseActivity.kt:25) at com.wireguard.android.activity.BaseActivity$onCreate$1.invokeSuspend (BaseActivity.kt:44) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106) at kotlinx.coroutines.EventLoop.processUnconfinedEvent (EventLoop.common.kt:69) at kotlinx.coroutines.DispatchedTaskKt.runUnconfinedEventLoop (DispatchedTask.kt:204) at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith (DispatchedContinuation.kt:282) at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable (Cancellable.kt:30) at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default (Cancellable.kt:25) at kotlinx.coroutines.CoroutineStart.invoke (CoroutineStart.java:110) at kotlinx.coroutines.AbstractCoroutine.start (AbstractCoroutine.kt:126) at kotlinx.coroutines.BuildersKt.launch$default (Builders.kt) at com.wireguard.android.model.TunnelManager.onTunnelsLoaded (TunnelManager.java:114) at com.wireguard.android.model.TunnelManager.access$onTunnelsLoaded (TunnelManager.java:40) at com.wireguard.android.model.TunnelManager$onCreate$1.invokeSuspend (TunnelManager.kt:104) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106) at android.os.Handler.handleCallback (Handler.java:942) at android.os.Handler.dispatchMessage (Handler.java:99) at android.os.Looper.loopOnce (Looper.java:226) at android.os.Looper.loop (Looper.java:313) at android.app.ActivityThread.main (ActivityThread.java:8757) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067) Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-05ui: no need to manually recreate activities after night changeJason A. Donenfeld
Since version 1.1.0, setDefaultNightMode now takes care of that. Also, set the initial mode in a blocking fashion to prevent flashing white. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-05ui: distinguish play store installs at runtime for reproducible buildsJason A. Donenfeld
This change lets us use the same build for F-Droid, Play Store, self builds, and elsewhere, which makes everything more easily publicly verifiable, since the build system is reproducible. That means that all APKs will have the same code and be completely interchangeable, no matter where they come from. It does this by removing the build-time branch for special Play Store builds, and replacing it with a simple runtime check using the PackageManager APIs that return the name of the installer. If the app is installed by "com.android.vending", then it's a Play Store install. It's possible to test this with: $ pm install -i com.android.vending path/to/package.apk And it appears to work well. One potential concern is that it's unclear whether the Play Store reviewers install the app using utilities that set com.android.vending like this. If not, that might be a problem. However, it looks like various banking apps also use the installer package name check in the same way, and refuse to start if it's not right. That suggests that it would be impossible for Play Store reviewers to even review those banking apps if they did not set com.android.vending properly. Out of an abundance of caution, though, and in order to avoid a Play Store suspension that's harder to appeal, I sent a support request today (which just managed to fit exactly in the 1000 character limit): Hi, My app pays special attention to Google Play Store guidelines. For that reason, there is some code in the app that looks like this: if (BuildConfig.IS_GOOGLE_PLAY) ... else ... This means that I compile two versions of my app, one for Google Play, and another for other app stores. This has worked well for many years and it satisfies Google's policy requirements. However, compiling two versions of my app is a bit of a pain. Instead, I would like to do this check at runtime, with code like this: if (pm.getInstallSourceInfo(package).installingPackageName == "com.android.vending") ... else ... I have tested that this code works well, and I've installed my app with: $ pm install -i com.android.vending ui-release.apk This works and successfully satisfies the policy requirements. My question is how this works during the review process. Are reviewed apps installed with the necessary -i com.android.vending switch to make this work? Thanks. They responded fairly quickly: Hi Jason, Thanks for contacting the Google Play team. Unfortunately I'm not able to comment on your planned implementation. If you think your app is in compliance, please submit your app for review. You may want to review the Developer Program Policies for additional policy guidance. We recommend reviewing the details listed in this blog post and update your app accordingly to comply with the changes. Thanks for your understanding and continued support. Regards, Mia Google Play Developer Support So I'll interpret that as a, "if you think it's okay, submit it and see, and then we'll let you know." So here we go. Hopefully if it is rejected, the update will only be blocked, and I'll just revert this commit and resubmit. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: always use MaterialAlertDialogBuilderJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: force dark theme in TV modeJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: use real M3 themeing on TVJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: redirect to play store if no file manager on tvJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: detect tv framework stubs when getting contentJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: use ErrorMessages consistentlyJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: do not crash if tunnel preparation failsJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: do not OOM when leaving log window open for a whileJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: show bottom sheet sync to prevent double addJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: do not return to detail page when restoring stateJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: never access CREATOR directlyJason A. Donenfeld
All of the parcelers have their own type prefix. So we have to actually use the legit methods. This is a bit annoying, as there's no fully compatible way across all API versions, so we have to branch. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-04-04ui: never throw on link clicksJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-30ui: do not allow double clicking fab to show menu twiceJason A. Donenfeld
Exception java.lang.IllegalStateException: at androidx.fragment.app.FragmentStore.addFragment (FragmentStore.java:92) at androidx.fragment.app.FragmentManager.addFragment (FragmentManager.java:1481) at androidx.fragment.app.BackStackRecord.executeOps (BackStackRecord.java:387) at androidx.fragment.app.FragmentManager.executeOps (FragmentManager.java:1965) at androidx.fragment.app.FragmentManager.executeOpsTogether (FragmentManager.java:1873) at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute (FragmentManager.java:1823) at androidx.fragment.app.FragmentManager.execPendingActions (FragmentManager.java:1760) at androidx.fragment.app.FragmentManager$5.run (FragmentManager.java:547) at android.os.Handler.handleCallback (Handler.java:938) at android.os.Handler.dispatchMessage (Handler.java:99) at android.os.Looper.loop (Looper.java:268) at android.app.ActivityThread.main (ActivityThread.java:8101) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:627) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:997) Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-30ui: remove unneeded @JvmStatic annotationsJason A. Donenfeld
These are only needed on methods called from databindings, since those compile to java. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-30ui: use app resources instead of ctx for strings in callbackJason A. Donenfeld
Exception java.lang.IllegalStateException: at androidx.fragment.app.Fragment.requireContext (Fragment.java:967) at com.wireguard.android.fragment.TunnelListFragment$tunnelFileImportResultLauncher$1$1.invokeSuspend (TunnelListFragment.kt:64) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:104) at android.os.Handler.handleCallback (Handler.java:761) at android.os.Handler.dispatchMessage (Handler.java:98) at android.os.Looper.loop (Looper.java:156) at android.app.ActivityThread.main (ActivityThread.java:6617) at java.lang.reflect.Method.invoke at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:942) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:832) Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-30ui: use M3 theme for TV to prevent crashJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-28ui: add log items in buffered batchesJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-28ui: color verbose logs the same as debug logsJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-28ui: don't call getColor on already resolved attributeJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-27ui: cancel actionmode when pressing back buttonJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-27ui: simplify actionmode castJason A. Donenfeld
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-27ui: introduce a fresh set of Material3 themes and migrate to themHarsh Shandilya
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2023-03-27ui: use AndroidX `BundleCompat` for extracting parcelableHarsh Shandilya
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2023-03-25ui: switch from SwitchMaterial to MaterialSwitchJason A. Donenfeld
This required some weird changes to prevent clipping on the top, because apparently the new switch is a bit fatter. I think this actually looks a bit uglier than before, but it seems like that's what Material design wants. Maybe we can improve it? Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-03-24ui: bring back donation buttonJason A. Donenfeld
For Google Play Store builds, we'll display an alert box. This was inspired by the discussion around StreetComplete; hopefully we'll have a similar okay outcome. Link: https://github.com/streetcomplete/streetcomplete/issues/3768 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>