From 73c6a29ede6ba33a215f347335131ce89a27f146 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 23 Apr 2020 16:19:33 +0100 Subject: [PATCH 01/16] Add transports activity. --- briar-android/src/main/AndroidManifest.xml | 177 +++++------ .../android/activity/ActivityComponent.java | 3 + .../android/navdrawer/NavDrawerActivity.java | 9 +- .../android/navdrawer/PluginViewModel.java | 139 ++++++++- .../android/navdrawer/TransportsActivity.java | 294 ++++++++++++++++++ .../main/res/layout/activity_transports.xml | 10 + .../res/layout/list_item_transport_card.xml | 73 +++++ .../src/main/res/layout/transports_list.xml | 1 - briar-android/src/main/res/values/strings.xml | 32 +- 9 files changed, 640 insertions(+), 98 deletions(-) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java create mode 100644 briar-android/src/main/res/layout/activity_transports.xml create mode 100644 briar-android/src/main/res/layout/list_item_transport_card.xml diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index 5055324bf..8a98d5c0c 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -1,46 +1,46 @@ - + + android:required="false" /> + android:required="false" /> - + android:required="false" /> + - - - - - - - + + + + + + + - - - - + + + + - - - - + + + + - - + + @@ -59,14 +59,13 @@ android:name="org.briarproject.briar.android.BriarService" android:exported="false"> - + - + android:exported="false"> - + android:windowSoftInputMode="adjustResize|stateHidden"> - + android:label="@string/app_name"> - + android:label="@string/app_name"> - + android:windowSoftInputMode="adjustResize|stateAlwaysVisible"> - - + + + @@ -111,17 +107,17 @@ android:launchMode="singleTask" android:theme="@style/BriarTheme.NoActionBar"> - + - - + + - + - - - + + + @@ -133,7 +129,7 @@ android:windowSoftInputMode="adjustResize|stateUnchanged"> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.conversation.ConversationActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity" /> + android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity" /> + android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.conversation.ConversationActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.forum.ForumActivity" /> + android:value="org.briarproject.briar.android.blog.BlogActivity" /> + android:value="org.briarproject.briar.android.forum.ForumActivity" /> + android:value="org.briarproject.briar.android.blog.BlogActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.blog.BlogActivity" /> + android:value="org.briarproject.briar.android.blog.BlogActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> + android:value="org.briarproject.briar.android.conversation.ConversationActivity" /> - + android:label="@string/startup_failed_activity_title"> + android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" /> - - + + + + + + + android:value="org.briarproject.briar.android.settings.SettingsActivity" /> + android:value="org.briarproject.briar.android.settings.SettingsActivity" /> + android:value="org.briarproject.briar.android.settings.SettingsActivity" /> - - + + - + android:theme="@android:style/Theme.NoDisplay"> - + android:theme="@android:style/Theme.NoDisplay"> + android:theme="@style/BriarTheme.NoActionBar" /> + android:windowSoftInputMode="adjustResize|stateHidden" /> + android:theme="@style/BriarTheme" /> diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java index 02c18b341..e71e7d786 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java @@ -47,6 +47,7 @@ import org.briarproject.briar.android.login.OpenDatabaseFragment; import org.briarproject.briar.android.login.PasswordFragment; import org.briarproject.briar.android.login.StartupActivity; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; +import org.briarproject.briar.android.navdrawer.TransportsActivity; import org.briarproject.briar.android.panic.PanicPreferencesActivity; import org.briarproject.briar.android.panic.PanicResponderActivity; import org.briarproject.briar.android.privategroup.conversation.GroupActivity; @@ -163,6 +164,8 @@ public interface ActivityComponent { void inject(SettingsActivity activity); + void inject(TransportsActivity activity); + void inject(TestDataActivity activity); void inject(ChangePasswordActivity activity); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java index 5376dc8f0..e3f37e3b0 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java @@ -97,6 +97,8 @@ public class NavDrawerActivity extends BriarActivity implements public static Uri SIGN_OUT_URI = Uri.parse("briar-content://org.briarproject.briar/sign-out"); + private final List transports = new ArrayList<>(3); + private NavDrawerViewModel navDrawerViewModel; private PluginViewModel pluginViewModel; private ActionBarDrawerToggle drawerToggle; @@ -110,7 +112,6 @@ public class NavDrawerActivity extends BriarActivity implements private DrawerLayout drawerLayout; private NavigationView navigation; - private List transports; private BaseAdapter transportsAdapter; @Override @@ -141,6 +142,10 @@ public class NavDrawerActivity extends BriarActivity implements drawerLayout = findViewById(R.id.drawer_layout); navigation = findViewById(R.id.navigation); GridView transportsView = findViewById(R.id.transportsView); + transportsView.setOnItemClickListener((parent, view, position, id) -> { + LOG.info("Starting transports activity"); + startActivity(new Intent(this, TransportsActivity.class)); + }); setSupportActionBar(toolbar); ActionBar actionBar = requireNonNull(getSupportActionBar()); @@ -380,8 +385,6 @@ public class NavDrawerActivity extends BriarActivity implements } private void initializeTransports() { - transports = new ArrayList<>(3); - transportsAdapter = new BaseAdapter() { @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java index 8badce8c4..a879b087c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java @@ -1,8 +1,18 @@ package org.briarproject.briar.android.navdrawer; +import android.app.Application; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +import org.briarproject.bramble.api.db.DatabaseExecutor; +import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventListener; +import org.briarproject.bramble.api.network.NetworkManager; +import org.briarproject.bramble.api.network.NetworkStatus; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.BluetoothConstants; import org.briarproject.bramble.api.plugin.LanTcpConstants; @@ -12,28 +22,44 @@ import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.event.TransportStateEvent; +import org.briarproject.bramble.api.settings.Settings; +import org.briarproject.bramble.api.settings.SettingsManager; +import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; +import java.util.concurrent.Executor; import java.util.logging.Logger; import javax.inject.Inject; import androidx.annotation.Nullable; +import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; +import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED; +import static android.bluetooth.BluetoothAdapter.EXTRA_STATE; +import static android.bluetooth.BluetoothAdapter.STATE_ON; import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE; import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING; +import static org.briarproject.bramble.util.LogUtils.logDuration; +import static org.briarproject.bramble.util.LogUtils.logException; +import static org.briarproject.bramble.util.LogUtils.now; @NotNullByDefault -public class PluginViewModel extends ViewModel implements EventListener { +public class PluginViewModel extends AndroidViewModel implements EventListener { private static final Logger LOG = getLogger(PluginViewModel.class.getName()); + private final Application app; + private final Executor dbExecutor; + private final SettingsManager settingsManager; private final PluginManager pluginManager; private final EventBus eventBus; + private final BroadcastReceiver receiver; private final MutableLiveData torPluginState = new MutableLiveData<>(); @@ -42,24 +68,65 @@ public class PluginViewModel extends ViewModel implements EventListener { private final MutableLiveData btPluginState = new MutableLiveData<>(); + private final MutableLiveData torEnabledSetting = + new MutableLiveData<>(false); + private final MutableLiveData wifiEnabledSetting = + new MutableLiveData<>(false); + private final MutableLiveData btEnabledSetting = + new MutableLiveData<>(false); + + private final MutableLiveData networkStatus = + new MutableLiveData<>(); + + private final MutableLiveData bluetoothTurnedOn = + new MutableLiveData<>(false); + @Inject - PluginViewModel(PluginManager pluginManager, EventBus eventBus) { + PluginViewModel(Application app, @DatabaseExecutor Executor dbExecutor, + SettingsManager settingsManager, PluginManager pluginManager, + EventBus eventBus, NetworkManager networkManager) { + super(app); + this.app = app; + this.dbExecutor = dbExecutor; + this.settingsManager = settingsManager; this.pluginManager = pluginManager; this.eventBus = eventBus; eventBus.addListener(this); + receiver = new BluetoothStateReceiver(); + app.registerReceiver(receiver, new IntentFilter(ACTION_STATE_CHANGED)); + networkStatus.setValue(networkManager.getNetworkStatus()); torPluginState.setValue(getTransportState(TorConstants.ID)); wifiPluginState.setValue(getTransportState(LanTcpConstants.ID)); btPluginState.setValue(getTransportState(BluetoothConstants.ID)); + loadSettings(); } @Override protected void onCleared() { eventBus.removeListener(this); + app.unregisterReceiver(receiver); } @Override public void eventOccurred(Event e) { - if (e instanceof TransportStateEvent) { + if (e instanceof SettingsUpdatedEvent) { + SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; + if (s.getNamespace().equals(TorConstants.ID.getString())) { + boolean enable = + s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, true); + torEnabledSetting.setValue(enable); + } else if (s.getNamespace() + .equals(LanTcpConstants.ID.getString())) { + boolean enable = + s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, false); + wifiEnabledSetting.setValue(enable); + } else if (s.getNamespace().equals( + BluetoothConstants.ID.getString())) { + boolean enable = + s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, false); + btEnabledSetting.setValue(enable); + } + } else if (e instanceof TransportStateEvent) { TransportStateEvent t = (TransportStateEvent) e; TransportId id = t.getTransportId(); State state = t.getState(); @@ -77,6 +144,48 @@ public class PluginViewModel extends ViewModel implements EventListener { return liveData; } + LiveData getPluginEnabledSetting(TransportId id) { + if (id.equals(TorConstants.ID)) return torEnabledSetting; + else if (id.equals(LanTcpConstants.ID)) return wifiEnabledSetting; + else if (id.equals(BluetoothConstants.ID)) return btEnabledSetting; + else throw new IllegalArgumentException(); + } + + LiveData getNetworkStatus() { + return networkStatus; + } + + LiveData getBluetoothTurnedOn() { + return bluetoothTurnedOn; + } + + void enableTransport(TransportId id, boolean enable) { + Settings s = new Settings(); + s.putBoolean(PREF_PLUGIN_ENABLE, enable); + mergeSettings(s, id.getString()); + } + + private void loadSettings() { + dbExecutor.execute(() -> { + try { + boolean tor = isPluginEnabled(TorConstants.ID, true); + torEnabledSetting.postValue(tor); + boolean wifi = isPluginEnabled(LanTcpConstants.ID, false); + wifiEnabledSetting.postValue(wifi); + boolean bt = isPluginEnabled(BluetoothConstants.ID, false); + btEnabledSetting.postValue(bt); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + }); + } + + private boolean isPluginEnabled(TransportId id, boolean defaultValue) + throws DbException { + Settings s = settingsManager.getSettings(id.getString()); + return s.getBoolean(PREF_PLUGIN_ENABLE, defaultValue); + } + private State getTransportState(TransportId id) { Plugin plugin = pluginManager.getPlugin(id); return plugin == null ? STARTING_STOPPING : plugin.getState(); @@ -89,4 +198,26 @@ public class PluginViewModel extends ViewModel implements EventListener { else if (id.equals(BluetoothConstants.ID)) return btPluginState; else return null; } + + private void mergeSettings(Settings s, String namespace) { + dbExecutor.execute(() -> { + try { + long start = now(); + settingsManager.mergeSettings(s, namespace); + logDuration(LOG, "Merging settings", start); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + }); + } + + private class BluetoothStateReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + int state = intent.getIntExtra(EXTRA_STATE, 0); + if (state == STATE_ON) bluetoothTurnedOn.postValue(true); + else bluetoothTurnedOn.postValue(false); + } + } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java new file mode 100644 index 000000000..f9bb76559 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java @@ -0,0 +1,294 @@ +package org.briarproject.briar.android.navdrawer; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.TextView; + +import org.briarproject.bramble.api.network.NetworkStatus; +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.bramble.api.plugin.BluetoothConstants; +import org.briarproject.bramble.api.plugin.LanTcpConstants; +import org.briarproject.bramble.api.plugin.Plugin.State; +import org.briarproject.bramble.api.plugin.TorConstants; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.activity.BriarActivity; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import androidx.annotation.ColorRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.widget.SwitchCompat; +import androidx.core.content.ContextCompat; +import androidx.lifecycle.ViewModelProvider; +import androidx.lifecycle.ViewModelProviders; + +import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; +import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; +import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING; +import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class TransportsActivity extends BriarActivity { + + @Inject + ViewModelProvider.Factory viewModelFactory; + + private final List transports = new ArrayList<>(3); + + private PluginViewModel viewModel; + private BaseAdapter transportsAdapter; + + @Override + public void onCreate(@Nullable Bundle state) { + super.onCreate(state); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setHomeButtonEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(true); + } + + setContentView(R.layout.activity_transports); + + ViewModelProvider provider = + ViewModelProviders.of(this, viewModelFactory); + viewModel = provider.get(PluginViewModel.class); + + GridView grid = findViewById(R.id.grid); + initializeCards(); + grid.setAdapter(transportsAdapter); + } + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } + return false; + } + + private void initializeCards() { + transportsAdapter = new BaseAdapter() { + + @Override + public int getCount() { + return transports.size(); + } + + @Override + public Transport getItem(int position) { + return transports.get(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, + ViewGroup parent) { + View view; + if (convertView != null) { + view = convertView; + } else { + LayoutInflater inflater = getLayoutInflater(); + view = inflater.inflate(R.layout.list_item_transport_card, + parent, false); + } + + Transport t = getItem(position); + + ImageView icon = view.findViewById(R.id.icon); + icon.setImageDrawable(ContextCompat.getDrawable( + TransportsActivity.this, t.iconDrawable)); + icon.setColorFilter(ContextCompat.getColor( + TransportsActivity.this, t.iconColor)); + + TextView title = view.findViewById(R.id.title); + title.setText(getString(t.title)); + + SwitchCompat switchCompat = + view.findViewById(R.id.switchCompat); + switchCompat.setText(getString(t.switchLabel)); + switchCompat.setOnClickListener(v -> + viewModel.enableTransport(t.id, + switchCompat.isChecked())); + switchCompat.setChecked(t.isSwitchChecked); + + TextView deviceStatus = view.findViewById(R.id.deviceStatus); + deviceStatus.setText(getBulletString(t.deviceStatus)); + + TextView appStatus = view.findViewById(R.id.appStatus); + appStatus.setText(getBulletString(t.pluginStatus)); + + return view; + } + }; + + Transport tor = createTransport(TorConstants.ID, + R.drawable.transport_tor, R.string.transport_tor, + R.string.tor_enable_title, R.string.tor_device_status_offline, + R.string.tor_plugin_status_inactive); + transports.add(tor); + + Transport wifi = createTransport(LanTcpConstants.ID, + R.drawable.transport_lan, R.string.transport_lan_long, + R.string.wifi_setting, R.string.lan_device_status_off, + R.string.lan_plugin_status_inactive); + transports.add(wifi); + + Transport bt = createTransport(BluetoothConstants.ID, + R.drawable.transport_bt, R.string.transport_bt, + R.string.bluetooth_setting, R.string.bt_device_status_off, + R.string.bt_plugin_status_inactive); + transports.add(bt); + + viewModel.getNetworkStatus().observe(this, status -> { + tor.deviceStatus = getTorDeviceStatus(status); + wifi.deviceStatus = getWifiDeviceStatus(status); + transportsAdapter.notifyDataSetChanged(); + }); + + viewModel.getBluetoothTurnedOn().observe(this, on -> { + bt.deviceStatus = getBtDeviceStatus(on); + transportsAdapter.notifyDataSetChanged(); + }); + } + + private String getBulletString(@StringRes int resId) { + return "\u2022 " + getString(resId); + } + + @ColorRes + private int getIconColor(State state) { + if (state == ACTIVE) return R.color.briar_lime_400; + else if (state == ENABLING) return R.color.briar_orange_500; + else return android.R.color.tertiary_text_light; + } + + @StringRes + private int getTorDeviceStatus(NetworkStatus status) { + if (!status.isConnected()) return R.string.tor_device_status_offline; + if (status.isWifi()) return R.string.tor_device_status_online_wifi; + else return R.string.tor_device_status_online_mobile_data; + } + + @StringRes + private int getWifiDeviceStatus(NetworkStatus status) { + if (status.isWifi()) return R.string.lan_device_status_on; + else return R.string.lan_device_status_off; + } + + @StringRes + private int getBtDeviceStatus(boolean on) { + if (on) return R.string.bt_device_status_on; + else return R.string.bt_device_status_off; + } + + @StringRes + private int getPluginStatus(TransportId id, State state) { + if (id.equals(TorConstants.ID)) { + return getTorPluginStatus(state); + } else if (id.equals(LanTcpConstants.ID)) { + return getWifiPluginStatus(state); + } else if (id.equals(BluetoothConstants.ID)) { + return getBtPluginStatus(state); + } else throw new AssertionError(); + } + + @StringRes + private int getTorPluginStatus(State state) { + if (state == ENABLING) return R.string.tor_plugin_status_enabling; + else if (state == ACTIVE) return R.string.tor_plugin_status_active; + else if (state == DISABLED) return R.string.tor_plugin_status_disabled; + else return R.string.tor_plugin_status_inactive; + } + + @StringRes + private int getWifiPluginStatus(State state) { + if (state == ENABLING) return R.string.lan_plugin_status_enabling; + else if (state == ACTIVE) return R.string.lan_plugin_status_active; + else if (state == DISABLED) return R.string.lan_plugin_status_disabled; + else return R.string.lan_plugin_status_inactive; + } + + @StringRes + private int getBtPluginStatus(State state) { + if (state == ENABLING) return R.string.bt_plugin_status_enabling; + else if (state == ACTIVE) return R.string.bt_plugin_status_active; + else if (state == DISABLED) return R.string.bt_plugin_status_disabled; + else return R.string.bt_plugin_status_inactive; + } + + private Transport createTransport(TransportId id, + @DrawableRes int iconDrawable, @StringRes int title, + @StringRes int switchLabel, @StringRes int deviceStatus, + @StringRes int pluginStatus) { + int iconColor = getIconColor(STARTING_STOPPING); + Transport transport = new Transport(id, iconDrawable, iconColor, title, + switchLabel, false, deviceStatus, pluginStatus); + viewModel.getPluginState(id).observe(this, state -> { + transport.iconColor = getIconColor(state); + transport.pluginStatus = getPluginStatus(transport.id, state); + transportsAdapter.notifyDataSetChanged(); + }); + viewModel.getPluginEnabledSetting(id).observe(this, enabled -> { + transport.isSwitchChecked = enabled; + transportsAdapter.notifyDataSetChanged(); + }); + return transport; + } + + private static class Transport { + + private final TransportId id; + + @DrawableRes + private final int iconDrawable; + @StringRes + private final int title, switchLabel; + + @ColorRes + private int iconColor; + @StringRes + private int deviceStatus, pluginStatus; + private boolean isSwitchChecked; + + private Transport(TransportId id, @DrawableRes int iconDrawable, + @ColorRes int iconColor, @StringRes int title, + @StringRes int switchLabel, boolean isSwitchChecked, + @StringRes int deviceStatus, @StringRes int pluginStatus) { + this.id = id; + this.iconDrawable = iconDrawable; + this.iconColor = iconColor; + this.title = title; + this.switchLabel = switchLabel; + this.isSwitchChecked = isSwitchChecked; + this.deviceStatus = deviceStatus; + this.pluginStatus = pluginStatus; + } + } +} diff --git a/briar-android/src/main/res/layout/activity_transports.xml b/briar-android/src/main/res/layout/activity_transports.xml new file mode 100644 index 000000000..11f4f8dba --- /dev/null +++ b/briar-android/src/main/res/layout/activity_transports.xml @@ -0,0 +1,10 @@ + + diff --git a/briar-android/src/main/res/layout/list_item_transport_card.xml b/briar-android/src/main/res/layout/list_item_transport_card.xml new file mode 100644 index 000000000..8144f9e2a --- /dev/null +++ b/briar-android/src/main/res/layout/list_item_transport_card.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/briar-android/src/main/res/layout/transports_list.xml b/briar-android/src/main/res/layout/transports_list.xml index a484522c7..d25d038a4 100644 --- a/briar-android/src/main/res/layout/transports_list.xml +++ b/briar-android/src/main/res/layout/transports_list.xml @@ -12,7 +12,6 @@ android:id="@+id/transportsView" android:layout_width="match_parent" android:layout_height="wrap_content" - android:listSelector="@android:color/transparent" android:numColumns="3" tools:listitem="@layout/list_item_transport" /> diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 482b5ce1a..b4f0fd0e1 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -69,10 +69,37 @@ Settings Sign Out - + Internet - Bluetooth + Internet status: + Your phone has Internet access via Wi-Fi + Your phone has Internet access via mobile data + Your phone does not have Internet access + Briar is connecting to the Internet + Briar can connect to contacts via the Internet + Briar can\'t connect to contacts via the Internet + Briar is configured not to connect to contacts via the Internet + + Wi-Fi + Same Wi-Fi network + Wi-Fi status: + Your phone is connected to Wi-Fi + Your phone is not connected to Wi-Fi + Briar is connecting to the Wi-Fi network + Briar can connect to contacts on the same Wi-Fi network + Briar can\'t connect to contacts on the same Wi-Fi network + Briar is configured not to connect to contacts on the same Wi-Fi network + + + Bluetooth + Bluetooth status: + Your phone\'s Bluetooth is turned on + Your phone\'s Bluetooth is turned off + Briar is connecting to Bluetooth + Briar can connect to contacts via Bluetooth + Briar can\'t connect to contacts via Bluetooth + Briar is configured not to connect to contacts via Bluetooth Signed out of Briar @@ -121,6 +148,7 @@ Help Sorry Unavailable on your system + Status: No contacts to show From 6684fb2e1b2f2a2920eeca68512db83f0e357b13 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 28 Apr 2020 14:55:49 +0100 Subject: [PATCH 02/16] Add settings button to toolbar. --- .../android/navdrawer/TransportsActivity.java | 14 ++++++++++++++ ...ttings_black_24dp.xml => ic_settings_black.xml} | 0 .../src/main/res/drawable/ic_settings_white.xml | 9 +++++++++ .../src/main/res/menu/navigation_drawer.xml | 2 +- .../src/main/res/menu/transports_actions.xml | 12 ++++++++++++ 5 files changed, 36 insertions(+), 1 deletion(-) rename briar-android/src/main/res/drawable/{ic_settings_black_24dp.xml => ic_settings_black.xml} (100%) create mode 100644 briar-android/src/main/res/drawable/ic_settings_white.xml create mode 100644 briar-android/src/main/res/menu/transports_actions.xml diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java index f9bb76559..9e75b777d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java @@ -1,7 +1,10 @@ package org.briarproject.briar.android.navdrawer; +import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -21,6 +24,7 @@ import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BriarActivity; +import org.briarproject.briar.android.settings.SettingsActivity; import java.util.ArrayList; import java.util.List; @@ -85,10 +89,20 @@ public class TransportsActivity extends BriarActivity { if (item.getItemId() == android.R.id.home) { onBackPressed(); return true; + } else if (item.getItemId() == R.id.action_open_settings) { + startActivity(new Intent(this, SettingsActivity.class)); + return true; } return false; } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.transports_actions, menu); + return super.onCreateOptionsMenu(menu); + } + private void initializeCards() { transportsAdapter = new BaseAdapter() { diff --git a/briar-android/src/main/res/drawable/ic_settings_black_24dp.xml b/briar-android/src/main/res/drawable/ic_settings_black.xml similarity index 100% rename from briar-android/src/main/res/drawable/ic_settings_black_24dp.xml rename to briar-android/src/main/res/drawable/ic_settings_black.xml diff --git a/briar-android/src/main/res/drawable/ic_settings_white.xml b/briar-android/src/main/res/drawable/ic_settings_white.xml new file mode 100644 index 000000000..a16d2c075 --- /dev/null +++ b/briar-android/src/main/res/drawable/ic_settings_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/briar-android/src/main/res/menu/navigation_drawer.xml b/briar-android/src/main/res/menu/navigation_drawer.xml index c24131755..ccfa71328 100644 --- a/briar-android/src/main/res/menu/navigation_drawer.xml +++ b/briar-android/src/main/res/menu/navigation_drawer.xml @@ -24,7 +24,7 @@ + + + + + \ No newline at end of file From 5b5d51331647df906ad65a3baeac898e87ef9aa8 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 28 Apr 2020 15:04:41 +0100 Subject: [PATCH 03/16] Shorter explanations. --- briar-android/src/main/res/values/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index b4f0fd0e1..296fb29e2 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -76,9 +76,9 @@ Your phone has Internet access via mobile data Your phone does not have Internet access Briar is connecting to the Internet - Briar can connect to contacts via the Internet - Briar can\'t connect to contacts via the Internet - Briar is configured not to connect to contacts via the Internet + Briar is connected to the Internet + Briar can\'t connect to the Internet + Briar is configured not to use the Internet Wi-Fi @@ -87,9 +87,9 @@ Your phone is connected to Wi-Fi Your phone is not connected to Wi-Fi Briar is connecting to the Wi-Fi network - Briar can connect to contacts on the same Wi-Fi network - Briar can\'t connect to contacts on the same Wi-Fi network - Briar is configured not to connect to contacts on the same Wi-Fi network + Briar is connected to the Wi-Fi network + Briar can\'t connect to the Wi-Fi network + Briar is configured not to use the Wi-Fi network Bluetooth @@ -97,9 +97,9 @@ Your phone\'s Bluetooth is turned on Your phone\'s Bluetooth is turned off Briar is connecting to Bluetooth - Briar can connect to contacts via Bluetooth - Briar can\'t connect to contacts via Bluetooth - Briar is configured not to connect to contacts via Bluetooth + Briar is connected to Bluetooth + Briar can\'t connect to Bluetooth + Briar is configured not to use Bluetooth Signed out of Briar From 57b0641e5fe65ebafe058b0362c02dcf52f07d2d Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 28 Apr 2020 15:23:33 +0100 Subject: [PATCH 04/16] Update network status. --- .../briar/android/navdrawer/PluginViewModel.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java index a879b087c..936199ea4 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java @@ -13,6 +13,7 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.network.NetworkStatus; +import org.briarproject.bramble.api.network.event.NetworkStatusEvent; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.BluetoothConstants; import org.briarproject.bramble.api.plugin.LanTcpConstants; @@ -109,7 +110,9 @@ public class PluginViewModel extends AndroidViewModel implements EventListener { @Override public void eventOccurred(Event e) { - if (e instanceof SettingsUpdatedEvent) { + if (e instanceof NetworkStatusEvent) { + networkStatus.setValue(((NetworkStatusEvent) e).getStatus()); + } else if (e instanceof SettingsUpdatedEvent) { SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; if (s.getNamespace().equals(TorConstants.ID.getString())) { boolean enable = From b189a38f628026e295d6ae5a0032ba53db547bba Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 28 Apr 2020 15:27:10 +0100 Subject: [PATCH 05/16] Only show plugin status when it's relevant. --- .../android/navdrawer/TransportsActivity.java | 62 ++++++++++++------- briar-android/src/main/res/values/strings.xml | 2 +- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java index 9e75b777d..5df5e6b63 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java @@ -41,6 +41,8 @@ import androidx.core.content.ContextCompat; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProviders; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING; @@ -155,8 +157,9 @@ public class TransportsActivity extends BriarActivity { TextView deviceStatus = view.findViewById(R.id.deviceStatus); deviceStatus.setText(getBulletString(t.deviceStatus)); - TextView appStatus = view.findViewById(R.id.appStatus); - appStatus.setText(getBulletString(t.pluginStatus)); + TextView pluginStatus = view.findViewById(R.id.appStatus); + pluginStatus.setText(getBulletString(t.pluginStatus)); + pluginStatus.setVisibility(t.showPluginStatus ? VISIBLE : GONE); return view; } @@ -181,13 +184,13 @@ public class TransportsActivity extends BriarActivity { transports.add(bt); viewModel.getNetworkStatus().observe(this, status -> { - tor.deviceStatus = getTorDeviceStatus(status); - wifi.deviceStatus = getWifiDeviceStatus(status); + updateTorResources(tor, status); + updateWifiResources(wifi, status); transportsAdapter.notifyDataSetChanged(); }); viewModel.getBluetoothTurnedOn().observe(this, on -> { - bt.deviceStatus = getBtDeviceStatus(on); + updateBtResources(bt, on); transportsAdapter.notifyDataSetChanged(); }); } @@ -203,23 +206,38 @@ public class TransportsActivity extends BriarActivity { else return android.R.color.tertiary_text_light; } - @StringRes - private int getTorDeviceStatus(NetworkStatus status) { - if (!status.isConnected()) return R.string.tor_device_status_offline; - if (status.isWifi()) return R.string.tor_device_status_online_wifi; - else return R.string.tor_device_status_online_mobile_data; + private void updateTorResources(Transport tor, NetworkStatus status) { + if (status.isConnected()) { + if (status.isWifi()) { + tor.deviceStatus = R.string.tor_device_status_online_wifi; + } else { + tor.deviceStatus = R.string.tor_device_status_online_mobile; + } + tor.showPluginStatus = true; + } else { + tor.deviceStatus = R.string.tor_device_status_offline; + tor.showPluginStatus = false; + } } - @StringRes - private int getWifiDeviceStatus(NetworkStatus status) { - if (status.isWifi()) return R.string.lan_device_status_on; - else return R.string.lan_device_status_off; + private void updateWifiResources(Transport wifi, NetworkStatus status) { + if (status.isWifi()) { + wifi.deviceStatus = R.string.lan_device_status_on; + wifi.showPluginStatus = true; + } else { + wifi.deviceStatus = R.string.lan_device_status_off; + wifi.showPluginStatus = false; + } } - @StringRes - private int getBtDeviceStatus(boolean on) { - if (on) return R.string.bt_device_status_on; - else return R.string.bt_device_status_off; + private void updateBtResources(Transport bt, boolean on) { + if (on) { + bt.deviceStatus = R.string.bt_device_status_on; + bt.showPluginStatus = true; + } else { + bt.deviceStatus = R.string.bt_device_status_off; + bt.showPluginStatus = false; + } } @StringRes @@ -263,7 +281,7 @@ public class TransportsActivity extends BriarActivity { @StringRes int pluginStatus) { int iconColor = getIconColor(STARTING_STOPPING); Transport transport = new Transport(id, iconDrawable, iconColor, title, - switchLabel, false, deviceStatus, pluginStatus); + switchLabel, false, deviceStatus, pluginStatus, false); viewModel.getPluginState(id).observe(this, state -> { transport.iconColor = getIconColor(state); transport.pluginStatus = getPluginStatus(transport.id, state); @@ -289,12 +307,13 @@ public class TransportsActivity extends BriarActivity { private int iconColor; @StringRes private int deviceStatus, pluginStatus; - private boolean isSwitchChecked; + private boolean isSwitchChecked, showPluginStatus; private Transport(TransportId id, @DrawableRes int iconDrawable, @ColorRes int iconColor, @StringRes int title, @StringRes int switchLabel, boolean isSwitchChecked, - @StringRes int deviceStatus, @StringRes int pluginStatus) { + @StringRes int deviceStatus, @StringRes int pluginStatus, + boolean showPluginStatus) { this.id = id; this.iconDrawable = iconDrawable; this.iconColor = iconColor; @@ -303,6 +322,7 @@ public class TransportsActivity extends BriarActivity { this.isSwitchChecked = isSwitchChecked; this.deviceStatus = deviceStatus; this.pluginStatus = pluginStatus; + this.showPluginStatus = showPluginStatus; } } } diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 296fb29e2..db94b03be 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -73,7 +73,7 @@ Internet Internet status: Your phone has Internet access via Wi-Fi - Your phone has Internet access via mobile data + Your phone has Internet access via mobile data Your phone does not have Internet access Briar is connecting to the Internet Briar is connected to the Internet From 08a8a0b281eb4b86065fe5a436fb0cf8d4e67af6 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 28 Apr 2020 15:44:38 +0100 Subject: [PATCH 06/16] Show reason why Tor is disabled. --- .../bramble/plugin/PluginManagerImpl.java | 5 ++++ .../android/navdrawer/PluginViewModel.java | 5 ++++ .../android/navdrawer/TransportsActivity.java | 25 ++++++++++++++++--- briar-android/src/main/res/values/strings.xml | 3 +++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java index 856103e18..ef03a78fd 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java @@ -53,6 +53,7 @@ import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; +import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING; import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logException; @@ -354,6 +355,10 @@ class PluginManagerImpl implements PluginManager, Service { } else if (oldState == ACTIVE) { eventBus.broadcast(new TransportInactiveEvent(id)); } + } else if (newState == DISABLED) { + // Broadcast an event even though the state hasn't changed, as + // the reasons for the plugin being disabled may have changed + eventBus.broadcast(new TransportStateEvent(id, newState)); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java index 936199ea4..e26d59eba 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java @@ -162,6 +162,11 @@ public class PluginViewModel extends AndroidViewModel implements EventListener { return bluetoothTurnedOn; } + int getReasonsTorDisabled() { + Plugin plugin = pluginManager.getPlugin(TorConstants.ID); + return plugin == null ? 0 : plugin.getReasonsDisabled(); + } + void enableTransport(TransportId id, boolean enable) { Settings s = new Settings(); s.putBoolean(PREF_PLUGIN_ENABLE, enable); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java index 5df5e6b63..cf7caef88 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java @@ -47,6 +47,9 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING; import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING; +import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY; +import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED; +import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -253,10 +256,24 @@ public class TransportsActivity extends BriarActivity { @StringRes private int getTorPluginStatus(State state) { - if (state == ENABLING) return R.string.tor_plugin_status_enabling; - else if (state == ACTIVE) return R.string.tor_plugin_status_active; - else if (state == DISABLED) return R.string.tor_plugin_status_disabled; - else return R.string.tor_plugin_status_inactive; + if (state == ENABLING) { + return R.string.tor_plugin_status_enabling; + } else if (state == ACTIVE) { + return R.string.tor_plugin_status_active; + } else if (state == DISABLED) { + int reasons = viewModel.getReasonsTorDisabled(); + if ((reasons & REASON_MOBILE_DATA) != 0) { + return R.string.tor_plugin_status_disabled_mobile_data; + } else if ((reasons & REASON_BATTERY) != 0) { + return R.string.tor_plugin_status_disabled_battery; + } else if ((reasons & REASON_COUNTRY_BLOCKED) != 0) { + return R.string.tor_plugin_status_disabled_country_blocked; + } else { + return R.string.tor_plugin_status_disabled; + } + } else { + return R.string.tor_plugin_status_inactive; + } } @StringRes diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index db94b03be..ed2c392ab 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -79,6 +79,9 @@ Briar is connected to the Internet Briar can\'t connect to the Internet Briar is configured not to use the Internet + Briar is configured not to use mobile data + Briar is configured not to use the Internet when running on battery + Briar is configured not to use the Internet in this country Wi-Fi From 02cf6bfcaa8d6100265d534dac1347038be1cbb6 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 29 Jun 2020 12:24:55 +0100 Subject: [PATCH 07/16] Use constants for default settings. --- .../android/navdrawer/PluginViewModel.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java index e26d59eba..165a3b41a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java @@ -115,18 +115,18 @@ public class PluginViewModel extends AndroidViewModel implements EventListener { } else if (e instanceof SettingsUpdatedEvent) { SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; if (s.getNamespace().equals(TorConstants.ID.getString())) { - boolean enable = - s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, true); + boolean enable = s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, + TorConstants.DEFAULT_PREF_PLUGIN_ENABLE); torEnabledSetting.setValue(enable); - } else if (s.getNamespace() - .equals(LanTcpConstants.ID.getString())) { - boolean enable = - s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, false); + } else if (s.getNamespace().equals( + LanTcpConstants.ID.getString())) { + boolean enable = s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, + LanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE); wifiEnabledSetting.setValue(enable); } else if (s.getNamespace().equals( BluetoothConstants.ID.getString())) { - boolean enable = - s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, false); + boolean enable = s.getSettings().getBoolean(PREF_PLUGIN_ENABLE, + BluetoothConstants.DEFAULT_PREF_PLUGIN_ENABLE); btEnabledSetting.setValue(enable); } } else if (e instanceof TransportStateEvent) { @@ -176,11 +176,14 @@ public class PluginViewModel extends AndroidViewModel implements EventListener { private void loadSettings() { dbExecutor.execute(() -> { try { - boolean tor = isPluginEnabled(TorConstants.ID, true); + boolean tor = isPluginEnabled(TorConstants.ID, + TorConstants.DEFAULT_PREF_PLUGIN_ENABLE); torEnabledSetting.postValue(tor); - boolean wifi = isPluginEnabled(LanTcpConstants.ID, false); + boolean wifi = isPluginEnabled(LanTcpConstants.ID, + LanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE); wifiEnabledSetting.postValue(wifi); - boolean bt = isPluginEnabled(BluetoothConstants.ID, false); + boolean bt = isPluginEnabled(BluetoothConstants.ID, + BluetoothConstants.DEFAULT_PREF_PLUGIN_ENABLE); btEnabledSetting.postValue(bt); } catch (DbException e) { logException(LOG, WARNING, e); From 392bc0d339326eee106db3ab519e6af346fa3101 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 29 Jun 2020 14:04:01 +0100 Subject: [PATCH 08/16] Use resource for title of transports activity. --- briar-android/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index 8a98d5c0c..a54a99b34 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -364,7 +364,7 @@ Date: Mon, 29 Jun 2020 14:26:59 +0100 Subject: [PATCH 09/16] Use Briar card style (sets background colour for dark theme). --- briar-android/src/main/res/layout/list_item_transport_card.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/briar-android/src/main/res/layout/list_item_transport_card.xml b/briar-android/src/main/res/layout/list_item_transport_card.xml index 8144f9e2a..35c00f979 100644 --- a/briar-android/src/main/res/layout/list_item_transport_card.xml +++ b/briar-android/src/main/res/layout/list_item_transport_card.xml @@ -1,6 +1,7 @@ From 5ba0728abca9a18fd3c0492915e308e5383e3ca1 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 29 Jun 2020 14:28:30 +0100 Subject: [PATCH 10/16] Add onboarding for transports activity. --- .../android/navdrawer/NavDrawerActivity.java | 43 +++++++++++++++++-- .../android/navdrawer/NavDrawerViewModel.java | 39 +++++++++++++++++ briar-android/src/main/res/values/strings.xml | 1 + 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java index e3f37e3b0..a5dd6f97f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java @@ -56,8 +56,10 @@ import androidx.core.content.ContextCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProviders; +import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt; import static android.view.View.GONE; import static android.view.View.VISIBLE; @@ -75,6 +77,8 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD; import static org.briarproject.briar.android.navdrawer.IntentRouter.handleExternalIntent; import static org.briarproject.briar.android.util.UiUtils.getDaysUntilExpiry; +import static org.briarproject.briar.android.util.UiUtils.observeOnce; +import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -98,6 +102,7 @@ public class NavDrawerActivity extends BriarActivity implements Uri.parse("briar-content://org.briarproject.briar/sign-out"); private final List transports = new ArrayList<>(3); + private final MutableLiveData torIcon = new MutableLiveData<>(); private NavDrawerViewModel navDrawerViewModel; private PluginViewModel pluginViewModel; @@ -154,13 +159,23 @@ public class NavDrawerActivity extends BriarActivity implements drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.nav_drawer_open_description, - R.string.nav_drawer_close_description); + R.string.nav_drawer_close_description) { + @Override + public void onDrawerOpened(View drawerView) { + super.onDrawerOpened(drawerView); + navDrawerViewModel.checkTransportsOnboarding(); + } + }; drawerLayout.addDrawerListener(drawerToggle); navigation.setNavigationItemSelectedListener(this); initializeTransports(); transportsView.setAdapter(transportsAdapter); + observeOnce(navDrawerViewModel.showTransportsOnboarding(), this, show -> + observeOnce(torIcon, this, imageView -> + showTransportsOnboarding(show, imageView))); + lockManager.isLockable().observe(this, this::setLockVisible); if (lifecycleManager.getLifecycleState().isAfter(RUNNING)) { @@ -425,6 +440,8 @@ public class NavDrawerActivity extends BriarActivity implements TextView text = view.findViewById(R.id.textView); text.setText(getString(t.label)); + if (t.id.equals(TorConstants.ID)) torIcon.setValue(icon); + return view; } }; @@ -447,7 +464,7 @@ public class NavDrawerActivity extends BriarActivity implements private Transport createTransport(TransportId id, @DrawableRes int iconDrawable, @StringRes int label) { int iconColor = getIconColor(STARTING_STOPPING); - Transport transport = new Transport(iconDrawable, label, iconColor); + Transport transport = new Transport(id, iconDrawable, label, iconColor); pluginViewModel.getPluginState(id).observe(this, state -> { transport.iconColor = getIconColor(state); transportsAdapter.notifyDataSetChanged(); @@ -455,8 +472,25 @@ public class NavDrawerActivity extends BriarActivity implements return transport; } + private void showTransportsOnboarding(boolean show, ImageView imageView) { + if (show) { + int color = resolveColorAttribute(this, R.attr.colorControlNormal); + new MaterialTapTargetPrompt.Builder(NavDrawerActivity.this, + R.style.OnboardingDialogTheme).setTarget(imageView) + .setPrimaryText(R.string.network_settings_title) + .setSecondaryText(R.string.transports_onboarding_text) + .setIcon(R.drawable.transport_tor) + .setIconDrawableColourFilter(color) + .setBackgroundColour( + ContextCompat.getColor(this, R.color.briar_primary)) + .show(); + navDrawerViewModel.transportsOnboardingShown(); + } + } + private static class Transport { + private final TransportId id; @DrawableRes private final int iconDrawable; @StringRes @@ -465,8 +499,9 @@ public class NavDrawerActivity extends BriarActivity implements @ColorRes private int iconColor; - private Transport(@DrawableRes int iconDrawable, @StringRes int label, - @ColorRes int iconColor) { + private Transport(TransportId id, @DrawableRes int iconDrawable, + @StringRes int label, @ColorRes int iconColor) { + this.id = id; this.iconDrawable = iconDrawable; this.label = label; this.iconColor = iconColor; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java index 1d031d35d..c354e0f66 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java @@ -34,6 +34,8 @@ public class NavDrawerViewModel extends AndroidViewModel { getLogger(NavDrawerViewModel.class.getName()); private static final String EXPIRY_DATE_WARNING = "expiryDateWarning"; + private static final String SHOW_TRANSPORTS_ONBOARDING = + "showTransportsOnboarding"; @DatabaseExecutor private final Executor dbExecutor; @@ -43,6 +45,8 @@ public class NavDrawerViewModel extends AndroidViewModel { new MutableLiveData<>(); private final MutableLiveData shouldAskForDozeWhitelisting = new MutableLiveData<>(); + private final MutableLiveData showTransportsOnboarding = + new MutableLiveData<>(); @Inject NavDrawerViewModel(Application app, @DatabaseExecutor Executor dbExecutor, @@ -128,4 +132,39 @@ public class NavDrawerViewModel extends AndroidViewModel { } }); } + + @UiThread + LiveData showTransportsOnboarding() { + return showTransportsOnboarding; + } + + @UiThread + void checkTransportsOnboarding() { + if (showTransportsOnboarding.getValue() != null) return; + dbExecutor.execute(() -> { + try { + Settings settings = + settingsManager.getSettings(SETTINGS_NAMESPACE); + boolean show = + settings.getBoolean(SHOW_TRANSPORTS_ONBOARDING, true); + showTransportsOnboarding.postValue(show); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + }); + } + + @UiThread + void transportsOnboardingShown() { + showTransportsOnboarding.setValue(false); + dbExecutor.execute(() -> { + try { + Settings settings = new Settings(); + settings.putBoolean(SHOW_TRANSPORTS_ONBOARDING, false); + settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + }); + } } diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index ed2c392ab..c8c214987 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -68,6 +68,7 @@ Lock App Settings Sign Out + Tap here to control how Briar connects to your contacts. Internet From 82e85bdb39d2014fc111f7e42762a6296f3a2e2f Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 14 Aug 2020 11:42:07 +0100 Subject: [PATCH 11/16] Remove redundant separator. --- briar-android/src/main/res/layout/navigation_menu.xml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/briar-android/src/main/res/layout/navigation_menu.xml b/briar-android/src/main/res/layout/navigation_menu.xml index 4a7a32c4f..38d257a2c 100644 --- a/briar-android/src/main/res/layout/navigation_menu.xml +++ b/briar-android/src/main/res/layout/navigation_menu.xml @@ -26,21 +26,13 @@ app:layout_constraintTop_toTopOf="parent" app:menu="@menu/navigation_drawer" /> - - Date: Fri, 14 Aug 2020 11:57:52 +0100 Subject: [PATCH 12/16] Add help button to transports activity. --- .../briar/android/navdrawer/TransportsActivity.java | 10 +++++----- .../src/main/res/menu/transports_actions.xml | 12 ------------ briar-android/src/main/res/values/strings.xml | 6 +++--- 3 files changed, 8 insertions(+), 20 deletions(-) delete mode 100644 briar-android/src/main/res/menu/transports_actions.xml diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java index cf7caef88..aa1adedb9 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java @@ -1,6 +1,5 @@ package org.briarproject.briar.android.navdrawer; -import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; @@ -24,7 +23,6 @@ import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BriarActivity; -import org.briarproject.briar.android.settings.SettingsActivity; import java.util.ArrayList; import java.util.List; @@ -50,6 +48,7 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY; import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED; import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA; +import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -94,8 +93,9 @@ public class TransportsActivity extends BriarActivity { if (item.getItemId() == android.R.id.home) { onBackPressed(); return true; - } else if (item.getItemId() == R.id.action_open_settings) { - startActivity(new Intent(this, SettingsActivity.class)); + } else if (item.getItemId() == R.id.action_help) { + String text = getString(R.string.transports_help_text); + showOnboardingDialog(this, text); return true; } return false; @@ -104,7 +104,7 @@ public class TransportsActivity extends BriarActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.transports_actions, menu); + inflater.inflate(R.menu.help_action, menu); return super.onCreateOptionsMenu(menu); } diff --git a/briar-android/src/main/res/menu/transports_actions.xml b/briar-android/src/main/res/menu/transports_actions.xml deleted file mode 100644 index 9a02f53e6..000000000 --- a/briar-android/src/main/res/menu/transports_actions.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index c8c214987..8951beb2a 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -72,7 +72,6 @@ Internet - Internet status: Your phone has Internet access via Wi-Fi Your phone has Internet access via mobile data Your phone does not have Internet access @@ -87,7 +86,6 @@ Wi-Fi Same Wi-Fi network - Wi-Fi status: Your phone is connected to Wi-Fi Your phone is not connected to Wi-Fi Briar is connecting to the Wi-Fi network @@ -97,7 +95,6 @@ Bluetooth - Bluetooth status: Your phone\'s Bluetooth is turned on Your phone\'s Bluetooth is turned off Briar is connecting to Bluetooth @@ -603,6 +600,9 @@ Briar is locked Tap to unlock + + Briar can connect to your contacts via the Internet, Wi-Fi or Bluetooth.\n\nAll Internet connections go through the Tor network for privacy.\n\nIf a contact can be reached by multiple methods, Briar uses them in parallel. + From 7fcb3394ca93b225e21bc104d778e0b8b5763870 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 14 Aug 2020 12:32:30 +0100 Subject: [PATCH 13/16] Add optional summary text to transport cards. --- .../android/navdrawer/TransportsActivity.java | 37 +++++++++++++------ .../res/layout/list_item_transport_card.xml | 21 +++++++++-- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java index aa1adedb9..688700cb9 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/TransportsActivity.java @@ -157,6 +157,14 @@ public class TransportsActivity extends BriarActivity { switchCompat.isChecked())); switchCompat.setChecked(t.isSwitchChecked); + TextView summary = view.findViewById(R.id.summary); + if (t.summary == 0) { + summary.setVisibility(GONE); + } else { + summary.setText(t.summary); + summary.setVisibility(VISIBLE); + } + TextView deviceStatus = view.findViewById(R.id.deviceStatus); deviceStatus.setText(getBulletString(t.deviceStatus)); @@ -170,19 +178,20 @@ public class TransportsActivity extends BriarActivity { Transport tor = createTransport(TorConstants.ID, R.drawable.transport_tor, R.string.transport_tor, - R.string.tor_enable_title, R.string.tor_device_status_offline, + R.string.tor_enable_title, R.string.tor_enable_summary, + R.string.tor_device_status_offline, R.string.tor_plugin_status_inactive); transports.add(tor); Transport wifi = createTransport(LanTcpConstants.ID, R.drawable.transport_lan, R.string.transport_lan_long, - R.string.wifi_setting, R.string.lan_device_status_off, + R.string.wifi_setting, 0, R.string.lan_device_status_off, R.string.lan_plugin_status_inactive); transports.add(wifi); Transport bt = createTransport(BluetoothConstants.ID, R.drawable.transport_bt, R.string.transport_bt, - R.string.bluetooth_setting, R.string.bt_device_status_off, + R.string.bluetooth_setting, 0, R.string.bt_device_status_off, R.string.bt_plugin_status_inactive); transports.add(bt); @@ -294,11 +303,11 @@ public class TransportsActivity extends BriarActivity { private Transport createTransport(TransportId id, @DrawableRes int iconDrawable, @StringRes int title, - @StringRes int switchLabel, @StringRes int deviceStatus, - @StringRes int pluginStatus) { + @StringRes int switchLabel, @StringRes int summary, + @StringRes int deviceStatus, @StringRes int pluginStatus) { int iconColor = getIconColor(STARTING_STOPPING); Transport transport = new Transport(id, iconDrawable, iconColor, title, - switchLabel, false, deviceStatus, pluginStatus, false); + switchLabel, false, summary, deviceStatus, pluginStatus, false); viewModel.getPluginState(id).observe(this, state -> { transport.iconColor = getIconColor(state); transport.pluginStatus = getPluginStatus(transport.id, state); @@ -318,7 +327,7 @@ public class TransportsActivity extends BriarActivity { @DrawableRes private final int iconDrawable; @StringRes - private final int title, switchLabel; + private final int title, switchLabel, summary; @ColorRes private int iconColor; @@ -326,10 +335,15 @@ public class TransportsActivity extends BriarActivity { private int deviceStatus, pluginStatus; private boolean isSwitchChecked, showPluginStatus; - private Transport(TransportId id, @DrawableRes int iconDrawable, - @ColorRes int iconColor, @StringRes int title, - @StringRes int switchLabel, boolean isSwitchChecked, - @StringRes int deviceStatus, @StringRes int pluginStatus, + private Transport(TransportId id, + @DrawableRes int iconDrawable, + @ColorRes int iconColor, + @StringRes int title, + @StringRes int switchLabel, + boolean isSwitchChecked, + @StringRes int summary, + @StringRes int deviceStatus, + @StringRes int pluginStatus, boolean showPluginStatus) { this.id = id; this.iconDrawable = iconDrawable; @@ -337,6 +351,7 @@ public class TransportsActivity extends BriarActivity { this.title = title; this.switchLabel = switchLabel; this.isSwitchChecked = isSwitchChecked; + this.summary = summary; this.deviceStatus = deviceStatus; this.pluginStatus = pluginStatus; this.showPluginStatus = showPluginStatus; diff --git a/briar-android/src/main/res/layout/list_item_transport_card.xml b/briar-android/src/main/res/layout/list_item_transport_card.xml index 35c00f979..638ef70a8 100644 --- a/briar-android/src/main/res/layout/list_item_transport_card.xml +++ b/briar-android/src/main/res/layout/list_item_transport_card.xml @@ -15,7 +15,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" - android:orientation="horizontal"> + android:orientation="horizontal" + tools:ignore="UseCompoundDrawables"> @@ -41,13 +42,27 @@ android:id="@+id/switchCompat" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="8dp" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/text_size_medium" + android:widgetLayout="@layout/preference_switch_compat" tools:checked="true" tools:text="@string/tor_enable_title" /> + + From bbcb183c2485a575730f752ede25c89a7ff022ec Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 14 Aug 2020 15:23:21 +0100 Subject: [PATCH 14/16] Use a single click target that covers all transport indicators. --- .../android/navdrawer/NavDrawerActivity.java | 4 +- .../widget/TouchInterceptingLinearLayout.java | 41 +++++++++++++++++++ .../src/main/res/layout/transports_list.xml | 6 ++- 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/widget/TouchInterceptingLinearLayout.java diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java index a5dd6f97f..3d89bb421 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java @@ -11,6 +11,7 @@ import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import com.google.android.material.navigation.NavigationView; @@ -147,7 +148,8 @@ public class NavDrawerActivity extends BriarActivity implements drawerLayout = findViewById(R.id.drawer_layout); navigation = findViewById(R.id.navigation); GridView transportsView = findViewById(R.id.transportsView); - transportsView.setOnItemClickListener((parent, view, position, id) -> { + LinearLayout transportsLayout = findViewById(R.id.transports); + transportsLayout.setOnClickListener(v -> { LOG.info("Starting transports activity"); startActivity(new Intent(this, TransportsActivity.class)); }); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/widget/TouchInterceptingLinearLayout.java b/briar-android/src/main/java/org/briarproject/briar/android/widget/TouchInterceptingLinearLayout.java new file mode 100644 index 000000000..8e3955c0b --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/widget/TouchInterceptingLinearLayout.java @@ -0,0 +1,41 @@ +package org.briarproject.briar.android.widget; + +import android.annotation.TargetApi; +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.LinearLayout; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import androidx.annotation.Nullable; + +@NotNullByDefault +public class TouchInterceptingLinearLayout extends LinearLayout { + + public TouchInterceptingLinearLayout(Context context) { + super(context); + } + + public TouchInterceptingLinearLayout(Context context, + @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public TouchInterceptingLinearLayout(Context context, + @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @TargetApi(21) + public TouchInterceptingLinearLayout(Context context, AttributeSet attrs, + int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent e) { + onTouchEvent(e); + return false; + } +} diff --git a/briar-android/src/main/res/layout/transports_list.xml b/briar-android/src/main/res/layout/transports_list.xml index d25d038a4..67e40fb07 100644 --- a/briar-android/src/main/res/layout/transports_list.xml +++ b/briar-android/src/main/res/layout/transports_list.xml @@ -1,8 +1,9 @@ - @@ -12,7 +13,8 @@ android:id="@+id/transportsView" android:layout_width="match_parent" android:layout_height="wrap_content" + android:listSelector="@android:color/transparent" android:numColumns="3" tools:listitem="@layout/list_item_transport" /> - + From a1e3c81bdacfd383f41bd77e5a433449e5df4562 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 14 Aug 2020 15:45:34 +0100 Subject: [PATCH 15/16] Remove unused drawable. --- .../src/main/res/drawable/ic_settings_white.xml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 briar-android/src/main/res/drawable/ic_settings_white.xml diff --git a/briar-android/src/main/res/drawable/ic_settings_white.xml b/briar-android/src/main/res/drawable/ic_settings_white.xml deleted file mode 100644 index a16d2c075..000000000 --- a/briar-android/src/main/res/drawable/ic_settings_white.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - From 2cf146a104fa35bca9babeed5d5b224579b45ea5 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 14 Aug 2020 16:13:29 +0100 Subject: [PATCH 16/16] Initialise Bluetooth state when view model is created. --- .../briar/android/navdrawer/PluginViewModel.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java index 165a3b41a..cc2c5ef7f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java @@ -1,6 +1,7 @@ package org.briarproject.briar.android.navdrawer; import android.app.Application; +import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -99,6 +100,7 @@ public class PluginViewModel extends AndroidViewModel implements EventListener { torPluginState.setValue(getTransportState(TorConstants.ID)); wifiPluginState.setValue(getTransportState(LanTcpConstants.ID)); btPluginState.setValue(getTransportState(BluetoothConstants.ID)); + initialiseBluetoothState(); loadSettings(); } @@ -173,6 +175,12 @@ public class PluginViewModel extends AndroidViewModel implements EventListener { mergeSettings(s, id.getString()); } + private void initialiseBluetoothState() { + BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); + if (bt == null) bluetoothTurnedOn.setValue(false); + else bluetoothTurnedOn.setValue(bt.getState() == STATE_ON); + } + private void loadSettings() { dbExecutor.execute(() -> { try {