diff options
author | Samuel Holland <samuel@sholland.org> | 2018-01-08 04:33:37 -0600 |
---|---|---|
committer | Samuel Holland <samuel@sholland.org> | 2018-01-08 04:33:54 -0600 |
commit | c4e91f8040968ad51ffccbd2ef9f17d4d322f579 (patch) | |
tree | 2c9a776734c959af09e2f8718f1b49c7e64aa9c7 | |
parent | c40555c1bd25ed1c832004e01438ec170ba93712 (diff) |
Handle tunnel state change errors appropriately
This class should probably be renamed and moved, but I don't know to
what or where.
Signed-off-by: Samuel Holland <samuel@sholland.org>
4 files changed, 77 insertions, 3 deletions
diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelController.java b/app/src/main/java/com/wireguard/android/fragment/TunnelController.java new file mode 100644 index 00000000..668e74c0 --- /dev/null +++ b/app/src/main/java/com/wireguard/android/fragment/TunnelController.java @@ -0,0 +1,71 @@ +package com.wireguard.android.fragment; + +import android.app.AlertDialog; +import android.content.Context; +import android.databinding.DataBindingUtil; +import android.databinding.ViewDataBinding; +import android.system.ErrnoException; +import android.system.OsConstants; +import android.text.Html; +import android.text.method.LinkMovementMethod; +import android.util.Log; +import android.view.View; +import android.widget.TextView; + +import com.commonsware.cwac.crossport.design.widget.Snackbar; +import com.wireguard.android.R; +import com.wireguard.android.databinding.TunnelDetailFragmentBinding; +import com.wireguard.android.databinding.TunnelListItemBinding; +import com.wireguard.android.model.Tunnel; +import com.wireguard.android.model.Tunnel.State; +import com.wireguard.android.util.ExceptionLoggers; + +/** + * Helper method shared by TunnelListFragment and TunnelDetailFragment. + */ + +public final class TunnelController { + private static final String TAG = TunnelController.class.getSimpleName(); + + private TunnelController() { + // Prevent instantiation. + } + + public static void setTunnelState(final View view, final boolean checked) { + final ViewDataBinding binding = DataBindingUtil.findBinding(view); + final Tunnel tunnel; + if (binding instanceof TunnelDetailFragmentBinding) + tunnel = ((TunnelDetailFragmentBinding) binding).getTunnel(); + else if (binding instanceof TunnelListItemBinding) + tunnel = ((TunnelListItemBinding) binding).getItem(); + else + tunnel = null; + if (tunnel == null) { + Log.e(TAG, "setChecked() from a null tunnel", new IllegalStateException()); + return; + } + tunnel.setState(State.of(checked)).whenComplete((state, throwable) -> { + if (throwable == null) + return; + Log.e(TAG, "Cannot set state of tunnel " + tunnel.getName(), throwable); + final Context context = view.getContext(); + if (throwable instanceof ErrnoException + && ((ErrnoException) throwable).errno == OsConstants.ENODEV) { + final String message = context.getString(R.string.not_supported_message); + final AlertDialog dialog = new AlertDialog.Builder(context) + .setMessage(Html.fromHtml(message)) + .setPositiveButton(R.string.ok, null) + .setTitle(R.string.not_supported_title) + .show(); + // Make links work. + ((TextView) dialog.findViewById(android.R.id.message)) + .setMovementMethod(LinkMovementMethod.getInstance()); + } else { + final String message = + context.getString(checked ? R.string.error_up : R.string.error_down) + ": " + + ExceptionLoggers.unwrap(throwable).getMessage(); + Snackbar.make(view, message, Snackbar.LENGTH_LONG).show(); + } + }); + } +} diff --git a/app/src/main/res/layout/tunnel_detail_fragment.xml b/app/src/main/res/layout/tunnel_detail_fragment.xml index e10bc4e1..900d08ed 100644 --- a/app/src/main/res/layout/tunnel_detail_fragment.xml +++ b/app/src/main/res/layout/tunnel_detail_fragment.xml @@ -5,6 +5,8 @@ <data> + <import type="com.wireguard.android.fragment.TunnelController" /> + <import type="com.wireguard.android.model.Tunnel.State" /> <import type="com.wireguard.android.util.ClipboardUtils" /> @@ -52,7 +54,7 @@ android:layout_alignBaseline="@+id/interface_title" android:layout_alignParentEnd="true" app:checked="@{tunnel.state == State.UP}" - app:onBeforeCheckedChanged="@{() -> tunnel.setState(State.TOGGLE)}" /> + app:onBeforeCheckedChanged="@{TunnelController::setTunnelState}" /> <TextView android:id="@+id/interface_name_label" diff --git a/app/src/main/res/layout/tunnel_list_item.xml b/app/src/main/res/layout/tunnel_list_item.xml index 1ed157e9..7fbd61f7 100644 --- a/app/src/main/res/layout/tunnel_list_item.xml +++ b/app/src/main/res/layout/tunnel_list_item.xml @@ -4,6 +4,8 @@ <data> + <import type="com.wireguard.android.fragment.TunnelController" /> + <import type="com.wireguard.android.model.Tunnel" /> <import type="com.wireguard.android.model.Tunnel.State" /> @@ -47,6 +49,6 @@ android:layout_alignBaseline="@+id/tunnel_name" android:layout_alignParentEnd="true" app:checked="@{item.state == State.UP}" - app:onBeforeCheckedChanged="@{() -> item.setState(State.TOGGLE)}" /> + app:onBeforeCheckedChanged="@{TunnelController::setTunnelState}" /> </RelativeLayout> </layout> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f32a9925..f7b4c548 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,7 +16,6 @@ <string name="edit">Edit</string> <string name="endpoint">Endpoint</string> <string name="error_down">Error bringing down WireGuard tunnel</string> - <string name="error_su">WireGuard currently requires root access</string> <string name="error_up">Error bringing up WireGuard tunnel</string> <string name="generate">Generate</string> <string name="hint_automatic">(auto)</string> |