From 4d6837ea53cc5f3ab92d65c51db25993f6597031 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 26 Mar 2020 22:26:53 -0600 Subject: ObservableTunnel: port to kotlin Signed-off-by: Jason A. Donenfeld --- .../java/com/wireguard/android/QuickTileService.kt | 2 +- .../android/activity/TunnelToggleActivity.kt | 2 +- .../com/wireguard/android/fragment/BaseFragment.kt | 2 +- .../android/fragment/TunnelEditorFragment.kt | 6 +- .../wireguard/android/model/ObservableTunnel.java | 143 --------------------- .../wireguard/android/model/ObservableTunnel.kt | 114 ++++++++++++++++ .../preference/KernelModuleDisablerPreference.kt | 2 +- 7 files changed, 121 insertions(+), 150 deletions(-) delete mode 100644 ui/src/main/java/com/wireguard/android/model/ObservableTunnel.java create mode 100644 ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt (limited to 'ui/src/main') diff --git a/ui/src/main/java/com/wireguard/android/QuickTileService.kt b/ui/src/main/java/com/wireguard/android/QuickTileService.kt index cd95f12d..6e17531a 100644 --- a/ui/src/main/java/com/wireguard/android/QuickTileService.kt +++ b/ui/src/main/java/com/wireguard/android/QuickTileService.kt @@ -54,7 +54,7 @@ class QuickTileService : TileService() { tile.icon = if (tile.icon == iconOn) iconOff else iconOn tile.updateTile() } - tunnel!!.setState(Tunnel.State.TOGGLE).whenComplete { _, t -> + tunnel!!.setStateAsync(Tunnel.State.TOGGLE).whenComplete { _, t -> if (t == null) { updateTile() } else { diff --git a/ui/src/main/java/com/wireguard/android/activity/TunnelToggleActivity.kt b/ui/src/main/java/com/wireguard/android/activity/TunnelToggleActivity.kt index 928a1108..e53ff5d3 100644 --- a/ui/src/main/java/com/wireguard/android/activity/TunnelToggleActivity.kt +++ b/ui/src/main/java/com/wireguard/android/activity/TunnelToggleActivity.kt @@ -23,7 +23,7 @@ class TunnelToggleActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val tunnel = Application.getTunnelManager().lastUsedTunnel ?: return - tunnel.setState(Tunnel.State.TOGGLE).whenComplete { _, t -> + tunnel.setStateAsync(Tunnel.State.TOGGLE).whenComplete { _, t -> TileService.requestListeningState(this, ComponentName(this, QuickTileService::class.java)) onToggleFinished(t) finishAffinity() diff --git a/ui/src/main/java/com/wireguard/android/fragment/BaseFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/BaseFragment.kt index 35ebc462..0f7c5802 100644 --- a/ui/src/main/java/com/wireguard/android/fragment/BaseFragment.kt +++ b/ui/src/main/java/com/wireguard/android/fragment/BaseFragment.kt @@ -85,7 +85,7 @@ abstract class BaseFragment : Fragment(), OnSelectedTunnelChangedListener { } private fun setTunnelStateWithPermissionsResult(tunnel: ObservableTunnel, checked: Boolean) { - tunnel.setState(Tunnel.State.of(checked)).whenComplete { _, throwable -> + tunnel.setStateAsync(Tunnel.State.of(checked)).whenComplete { _, throwable -> if (throwable == null) return@whenComplete val error = ErrorMessages.get(throwable) val messageResId = if (checked) R.string.error_up else R.string.error_down diff --git a/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt index 691731d3..a6139933 100644 --- a/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt +++ b/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt @@ -130,12 +130,12 @@ class TunnelEditorFragment : BaseFragment(), AppExclusionListener { } tunnel!!.name != binding!!.name -> { Log.d(TAG, "Attempting to rename tunnel to " + binding!!.name) - tunnel!!.setName(binding!!.name!!) + tunnel!!.setNameAsync(binding!!.name!!) .whenComplete { _, t -> onTunnelRenamed(tunnel!!, newConfig, t) } } else -> { Log.d(TAG, "Attempting to save config of " + tunnel!!.name) - tunnel!!.setConfig(newConfig) + tunnel!!.setConfigAsync(newConfig) .whenComplete { _, t -> onConfigSaved(tunnel!!, t) } } } @@ -198,7 +198,7 @@ class TunnelEditorFragment : BaseFragment(), AppExclusionListener { Log.d(TAG, message) // Now save the rest of configuration changes. Log.d(TAG, "Attempting to save config of renamed tunnel " + tunnel!!.name) - renamedTunnel.setConfig(newConfig).whenComplete { _, t -> onConfigSaved(renamedTunnel, t) } + renamedTunnel.setConfigAsync(newConfig).whenComplete { _, t -> onConfigSaved(renamedTunnel, t) } } else { val error = ErrorMessages.get(throwable) message = getString(R.string.tunnel_rename_error, error) diff --git a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.java b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.java deleted file mode 100644 index b0f8387b..00000000 --- a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright © 2017-2019 WireGuard LLC. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.wireguard.android.model; - -import com.wireguard.android.BR; -import com.wireguard.android.backend.Statistics; -import com.wireguard.android.backend.Tunnel; -import com.wireguard.android.util.ExceptionLoggers; -import com.wireguard.config.Config; -import com.wireguard.util.Keyed; -import com.wireguard.util.NonNullForAll; - -import androidx.annotation.Nullable; -import androidx.databinding.BaseObservable; -import androidx.databinding.Bindable; -import java9.util.concurrent.CompletableFuture; -import java9.util.concurrent.CompletionStage; - -/** - * Encapsulates the volatile and nonvolatile state of a WireGuard tunnel. - */ - -@NonNullForAll -public class ObservableTunnel extends BaseObservable implements Keyed, Tunnel { - private final TunnelManager manager; - @Nullable private Config config; - private String name; - private State state; - @Nullable private Statistics statistics; - - ObservableTunnel(final TunnelManager manager, final String name, - @Nullable final Config config, final State state) { - this.name = name; - this.manager = manager; - this.config = config; - this.state = state; - } - - public CompletionStage delete() { - return manager.delete(this); - } - - @Bindable - @Nullable - public Config getConfig() { - if (config == null) - manager.getTunnelConfig(this).whenComplete(ExceptionLoggers.E); - return config; - } - - public CompletionStage getConfigAsync() { - if (config == null) - return manager.getTunnelConfig(this); - return CompletableFuture.completedFuture(config); - } - - @Override - public String getKey() { - return name; - } - - @Override - @Bindable - public String getName() { - return name; - } - - @Bindable - public State getState() { - return state; - } - - public CompletionStage getStateAsync() { - return TunnelManager.getTunnelState(this); - } - - @Bindable - @Nullable - public Statistics getStatistics() { - if (statistics == null || statistics.isStale()) - TunnelManager.getTunnelStatistics(this).whenComplete(ExceptionLoggers.E); - return statistics; - } - - public CompletionStage getStatisticsAsync() { - if (statistics == null || statistics.isStale()) - return TunnelManager.getTunnelStatistics(this); - return CompletableFuture.completedFuture(statistics); - } - - Config onConfigChanged(final Config config) { - this.config = config; - notifyPropertyChanged(BR.config); - return config; - } - - String onNameChanged(final String name) { - this.name = name; - notifyPropertyChanged(BR.name); - return name; - } - - @Override - public void onStateChange(final State newState) { - onStateChanged(newState); - } - - State onStateChanged(final State state) { - if (state != State.UP) - onStatisticsChanged(null); - this.state = state; - notifyPropertyChanged(BR.state); - return state; - } - - @Nullable - Statistics onStatisticsChanged(@Nullable final Statistics statistics) { - this.statistics = statistics; - notifyPropertyChanged(BR.statistics); - return statistics; - } - - public CompletionStage setConfig(final Config config) { - if (!config.equals(this.config)) - return manager.setTunnelConfig(this, config); - return CompletableFuture.completedFuture(this.config); - } - - public CompletionStage setName(final String name) { - if (!name.equals(this.name)) - return manager.setTunnelName(this, name); - return CompletableFuture.completedFuture(this.name); - } - - public CompletionStage setState(final State state) { - if (state != this.state) - return manager.setTunnelState(this, state); - return CompletableFuture.completedFuture(this.state); - } -} diff --git a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt new file mode 100644 index 00000000..838ad7f9 --- /dev/null +++ b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt @@ -0,0 +1,114 @@ +/* + * Copyright © 2017-2019 WireGuard LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package com.wireguard.android.model + +import androidx.databinding.BaseObservable +import androidx.databinding.Bindable +import com.wireguard.android.BR +import com.wireguard.android.backend.Statistics +import com.wireguard.android.backend.Tunnel +import com.wireguard.android.util.ExceptionLoggers +import com.wireguard.config.Config +import com.wireguard.util.Keyed +import java9.util.concurrent.CompletableFuture +import java9.util.concurrent.CompletionStage + +/** + * Encapsulates the volatile and nonvolatile state of a WireGuard tunnel. + */ +class ObservableTunnel internal constructor( + private val manager: TunnelManager, + private var name: String, + config: Config?, + state: Tunnel.State +) : BaseObservable(), Keyed, Tunnel { + override fun getKey() = name + + + @Bindable + override fun getName() = name + + fun setNameAsync(name: String): CompletionStage = if (name != this.name) + manager.setTunnelName(this, name) + else + CompletableFuture.completedFuture(this.name) + + fun onNameChanged(name: String): String { + this.name = name + notifyPropertyChanged(BR.name) + return name + } + + + @get:Bindable + var state = state + private set + + override fun onStateChange(newState: Tunnel.State) { + onStateChanged(newState) + } + + fun onStateChanged(state: Tunnel.State): Tunnel.State { + if (state != Tunnel.State.UP) onStatisticsChanged(null) + this.state = state + notifyPropertyChanged(BR.state) + return state + } + + fun setStateAsync(state: Tunnel.State): CompletionStage = if (state != this.state) + manager.setTunnelState(this, state) + else + CompletableFuture.completedFuture(this.state) + + + @get:Bindable + var config = config + get() { + if (config == null) + manager.getTunnelConfig(this).whenComplete(ExceptionLoggers.E) + return config + } + private set + + val configAsync: CompletionStage = if (config == null) + manager.getTunnelConfig(this) + else + CompletableFuture.completedFuture(config) + + fun setConfigAsync(config: Config): CompletionStage = if (config != this.config) + manager.setTunnelConfig(this, config) + else + CompletableFuture.completedFuture(this.config) + + fun onConfigChanged(config: Config?): Config? { + this.config = config + notifyPropertyChanged(BR.config) + return config + } + + + @get:Bindable + var statistics: Statistics? = null + get() { + if (field == null || field!!.isStale) + TunnelManager.getTunnelStatistics(this).whenComplete(ExceptionLoggers.E) + return field + } + private set + + val statisticsAsync: CompletionStage = if (statistics == null || statistics!!.isStale) + TunnelManager.getTunnelStatistics(this) + else + CompletableFuture.completedFuture(statistics) + + fun onStatisticsChanged(statistics: Statistics?): Statistics? { + this.statistics = statistics + notifyPropertyChanged(BR.statistics) + return statistics + } + + + fun delete(): CompletionStage = manager.delete(this) +} diff --git a/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.kt b/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.kt index 0bb728df..1762fa58 100644 --- a/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.kt +++ b/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.kt @@ -35,7 +35,7 @@ class KernelModuleDisablerPreference(context: Context, attrs: AttributeSet?) : P } Application.getAsyncWorker().runAsync { Application.getTunnelManager().tunnels.thenApply { observableTunnels -> - val downings = observableTunnels.values().map { it.setState(Tunnel.State.DOWN).toCompletableFuture() }.toTypedArray() + val downings = observableTunnels.values().map { it.setStateAsync(Tunnel.State.DOWN).toCompletableFuture() }.toTypedArray() CompletableFuture.allOf(*downings).thenRun { val restartIntent = Intent(context, SettingsActivity::class.java) restartIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) -- cgit v1.2.3