From d1e85633fbe8d871355d2b9feb51e2c9983d8a21 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 5 Sep 2018 20:17:14 -0500 Subject: Remodel the Model - The configuration and crypto model is now entirely independent of Android classes other than Nullable and TextUtils. - Model classes are immutable and use builders that enforce the appropriate optional/required attributes. - The Android config proxies (for Parcelable and databinding) are moved to the Android side of the codebase, and are designed to be safe for two-way databinding. This allows proper observability in TunnelDetailFragment. - Various robustness fixes and documentation updates to helper classes. Signed-off-by: Jason A. Donenfeld --- .../android/databinding/BindingAdapters.java | 52 +++++++++++++++++++--- .../ObservableKeyedRecyclerViewAdapter.java | 2 +- 2 files changed, 48 insertions(+), 6 deletions(-) (limited to 'app/src/main/java/com/wireguard/android/databinding') diff --git a/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java b/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java index 629f99e5..fe01bf10 100644 --- a/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java +++ b/app/src/main/java/com/wireguard/android/databinding/BindingAdapters.java @@ -6,21 +6,30 @@ package com.wireguard.android.databinding; import android.databinding.BindingAdapter; +import android.databinding.DataBindingUtil; import android.databinding.ObservableList; +import android.databinding.ViewDataBinding; import android.databinding.adapters.ListenerUtil; +import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.InputFilter; +import android.view.LayoutInflater; import android.widget.LinearLayout; import android.widget.TextView; +import com.wireguard.android.BR; import com.wireguard.android.R; import com.wireguard.android.databinding.ObservableKeyedRecyclerViewAdapter.RowConfigurationHandler; import com.wireguard.android.util.ObservableKeyedList; import com.wireguard.android.widget.ToggleSwitch; import com.wireguard.android.widget.ToggleSwitch.OnBeforeCheckedChangeListener; +import com.wireguard.config.Attribute; +import com.wireguard.config.InetNetwork; import com.wireguard.util.Keyed; +import java9.util.Optional; + /** * Static methods for use by generated code in the Android data binding library. */ @@ -42,9 +51,10 @@ public final class BindingAdapters { } @BindingAdapter({"items", "layout"}) - public static void setItems(final LinearLayout view, - final ObservableList oldList, final int oldLayoutId, - final ObservableList newList, final int newLayoutId) { + public static + void setItems(final LinearLayout view, + @Nullable final ObservableList oldList, final int oldLayoutId, + @Nullable final ObservableList newList, final int newLayoutId) { if (oldList == newList && oldLayoutId == newLayoutId) return; ItemChangeListener listener = ListenerUtil.getListener(view, R.id.item_change_listener); @@ -66,11 +76,34 @@ public final class BindingAdapters { listener.setList(newList); } + @BindingAdapter({"items", "layout"}) + public static + void setItems(final LinearLayout view, + @Nullable final Iterable oldList, final int oldLayoutId, + @Nullable final Iterable newList, final int newLayoutId) { + if (oldList == newList && oldLayoutId == newLayoutId) + return; + view.removeAllViews(); + if (newList == null) + return; + final LayoutInflater layoutInflater = LayoutInflater.from(view.getContext()); + for (final E item : newList) { + final ViewDataBinding binding = + DataBindingUtil.inflate(layoutInflater, newLayoutId, view, false); + binding.setVariable(BR.collection, newList); + binding.setVariable(BR.item, item); + binding.executePendingBindings(); + view.addView(binding.getRoot()); + } + } + @BindingAdapter(requireAll = false, value = {"items", "layout", "configurationHandler"}) public static > void setItems(final RecyclerView view, - final ObservableKeyedList oldList, final int oldLayoutId, final RowConfigurationHandler oldRowConfigurationHandler, - final ObservableKeyedList newList, final int newLayoutId, final RowConfigurationHandler newRowConfigurationHandler) { + @Nullable final ObservableKeyedList oldList, final int oldLayoutId, + final RowConfigurationHandler oldRowConfigurationHandler, + @Nullable final ObservableKeyedList newList, final int newLayoutId, + final RowConfigurationHandler newRowConfigurationHandler) { if (view.getLayoutManager() == null) view.setLayoutManager(new LinearLayoutManager(view.getContext(), RecyclerView.VERTICAL, false)); @@ -103,4 +136,13 @@ public final class BindingAdapters { view.setOnBeforeCheckedChangeListener(listener); } + @BindingAdapter("android:text") + public static void setText(final TextView view, final Optional text) { + view.setText(text.map(Object::toString).orElse("")); + } + + @BindingAdapter("android:text") + public static void setText(final TextView view, @Nullable final Iterable networks) { + view.setText(networks != null ? Attribute.join(networks) : ""); + } } diff --git a/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java b/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java index 26e7687f..5bfa64f1 100644 --- a/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java +++ b/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java @@ -73,7 +73,7 @@ public class ObservableKeyedRecyclerViewAdapter> holder.binding.executePendingBindings(); if (rowConfigurationHandler != null) { - E item = getItem(position); + final E item = getItem(position); if (item != null) { rowConfigurationHandler.onConfigureRow(holder.binding, item, position); } -- cgit v1.2.3