[android] make transport plugin toggles functional

This commit is contained in:
Torsten Grote
2020-01-24 11:10:54 -03:00
committed by akwizgran
parent 93ec646634
commit 82bfb4d95e
11 changed files with 261 additions and 257 deletions

View File

@@ -36,6 +36,7 @@ import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.android.account.LockManagerImpl;
import org.briarproject.briar.android.keyagreement.ContactExchangeModule;
import org.briarproject.briar.android.navdrawer.NavDrawerModule;
import org.briarproject.briar.android.viewmodel.ViewModelModule;
import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.android.DozeWatchdog;
@@ -64,7 +65,11 @@ import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_ONIO
import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_PUBLIC_KEY_HEX;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
@Module(includes = {ContactExchangeModule.class, ViewModelModule.class})
@Module(includes = {
NavDrawerModule.class,
ContactExchangeModule.class,
ViewModelModule.class
})
public class AppModule {
static class EagerSingletons {

View File

@@ -10,8 +10,6 @@ import org.briarproject.briar.android.controller.DbController;
import org.briarproject.briar.android.controller.DbControllerImpl;
import org.briarproject.briar.android.login.ChangePasswordController;
import org.briarproject.briar.android.login.ChangePasswordControllerImpl;
import org.briarproject.briar.android.navdrawer.NavDrawerController;
import org.briarproject.briar.android.navdrawer.NavDrawerControllerImpl;
import dagger.Module;
import dagger.Provides;
@@ -67,14 +65,6 @@ public class ActivityModule {
return dbController;
}
@ActivityScope
@Provides
NavDrawerController provideNavDrawerController(
NavDrawerControllerImpl navDrawerController) {
activity.addLifecycleController(navDrawerController);
return navDrawerController;
}
@ActivityScope
@Provides
BriarServiceConnection provideBriarServiceConnection() {

View File

@@ -19,14 +19,11 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.Plugin.State;
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.blog.FeedFragment;
import org.briarproject.briar.android.contact.ContactListFragment;
import org.briarproject.briar.android.controller.handler.UiResultHandler;
import org.briarproject.briar.android.forum.ForumListFragment;
import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
@@ -47,6 +44,8 @@ import androidx.core.app.ActivityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
@@ -65,8 +64,7 @@ import static org.briarproject.briar.android.util.UiUtils.getDaysUntilExpiry;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class NavDrawerActivity extends BriarActivity implements
BaseFragmentListener, TransportStateListener,
OnNavigationItemSelectedListener {
BaseFragmentListener, OnNavigationItemSelectedListener {
private static final Logger LOG =
getLogger(NavDrawerActivity.class.getName());
@@ -84,10 +82,11 @@ public class NavDrawerActivity extends BriarActivity implements
public static Uri SIGN_OUT_URI =
Uri.parse("briar-content://org.briarproject.briar/sign-out");
private NavDrawerViewModel viewModel;
private ActionBarDrawerToggle drawerToggle;
@Inject
NavDrawerController controller;
ViewModelProvider.Factory viewModelFactory;
@Inject
LifecycleManager lifecycleManager;
@@ -106,6 +105,14 @@ public class NavDrawerActivity extends BriarActivity implements
exitIfStartupFailed(getIntent());
setContentView(R.layout.activity_nav_drawer);
viewModel = ViewModelProviders.of(this, viewModelFactory)
.get(NavDrawerViewModel.class);
viewModel.showExpiryWarning().observe(this, this::showExpiryWarning);
viewModel.shouldAskForDozeWhitelisting().observe(this, ask -> {
if (ask) showDozeDialog(getString(R.string.setup_doze_intro));
});
drawerScrollView = findViewById(R.id.drawerScrollView);
drawerScrollView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@@ -122,6 +129,7 @@ public class NavDrawerActivity extends BriarActivity implements
.removeOnGlobalLayoutListener(this);
}
});
new PluginViewController(drawerScrollView, this, viewModel);
Toolbar toolbar = findViewById(R.id.toolbar);
drawerLayout = findViewById(R.id.drawer_layout);
@@ -156,12 +164,7 @@ public class NavDrawerActivity extends BriarActivity implements
public void onStart() {
super.onStart();
lockManager.checkIfLockable();
controller.showExpiryWarning(new UiResultHandler<Boolean>(this) {
@Override
public void onResultUi(Boolean expiry) {
if (expiry) showExpiryWarning();
}
});
viewModel.checkExpiryWarning();
}
@Override
@@ -169,16 +172,7 @@ public class NavDrawerActivity extends BriarActivity implements
@Nullable Intent data) {
super.onActivityResult(request, result, data);
if (request == REQUEST_PASSWORD && result == RESULT_OK) {
controller.shouldAskForDozeWhitelisting(this,
new UiResultHandler<Boolean>(this) {
@Override
public void onResultUi(Boolean ask) {
if (ask) {
showDozeDialog(
getString(R.string.setup_doze_intro));
}
}
});
viewModel.checkDozeWhitelisting();
}
}
@@ -348,33 +342,31 @@ public class NavDrawerActivity extends BriarActivity implements
if (item != null) item.setVisible(visible);
}
private void showExpiryWarning() {
private void showExpiryWarning(boolean show) {
int daysUntilExpiry = getDaysUntilExpiry();
if (daysUntilExpiry < 0) signOut();
if (daysUntilExpiry < 0) {
signOut();
return;
}
// show expiry warning text
ViewGroup expiryWarning = findViewById(R.id.expiryWarning);
TextView expiryWarningText =
expiryWarning.findViewById(R.id.expiryWarningText);
// make close button functional
ImageView expiryWarningClose =
expiryWarning.findViewById(R.id.expiryWarningClose);
expiryWarningText.setText(getResources()
.getQuantityString(R.plurals.expiry_warning,
daysUntilExpiry, daysUntilExpiry));
expiryWarningClose.setOnClickListener(v -> {
controller.expiryWarningDismissed();
if (show) {
// show expiry warning text
TextView expiryWarningText =
expiryWarning.findViewById(R.id.expiryWarningText);
String text = getResources().getQuantityString(
R.plurals.expiry_warning, daysUntilExpiry, daysUntilExpiry);
expiryWarningText.setText(text);
// make close button functional
ImageView expiryWarningClose =
expiryWarning.findViewById(R.id.expiryWarningClose);
expiryWarningClose.setOnClickListener(v ->
viewModel.expiryWarningDismissed()
);
expiryWarning.setVisibility(VISIBLE);
} else {
expiryWarning.setVisibility(GONE);
});
expiryWarning.setVisibility(VISIBLE);
}
@Override
public void stateUpdate(TransportId id, State state) {
// TODO
}
}
}

View File

@@ -1,23 +0,0 @@
package org.briarproject.briar.android.navdrawer;
import android.content.Context;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Plugin.State;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.briar.android.controller.ActivityLifecycleController;
import org.briarproject.briar.android.controller.handler.ResultHandler;
@NotNullByDefault
public interface NavDrawerController extends ActivityLifecycleController {
State getTransportState(TransportId transportId);
void showExpiryWarning(ResultHandler<Boolean> handler);
void expiryWarningDismissed();
void shouldAskForDozeWhitelisting(Context ctx,
ResultHandler<Boolean> handler);
}

View File

@@ -0,0 +1,19 @@
package org.briarproject.briar.android.navdrawer;
import org.briarproject.briar.android.viewmodel.ViewModelKey;
import androidx.lifecycle.ViewModel;
import dagger.Binds;
import dagger.Module;
import dagger.multibindings.IntoMap;
@Module
public abstract class NavDrawerModule {
@Binds
@IntoMap
@ViewModelKey(NavDrawerViewModel.class)
abstract ViewModel bindNavDrawerViewModel(
NavDrawerViewModel navDrawerViewModel);
}

View File

@@ -1,31 +1,35 @@
package org.briarproject.briar.android.navdrawer;
import android.app.Activity;
import android.content.Context;
import android.app.Application;
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.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.BluetoothConstants;
import org.briarproject.bramble.api.plugin.LanTcpConstants;
import org.briarproject.bramble.api.plugin.Plugin;
import org.briarproject.bramble.api.plugin.Plugin.State;
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.briar.android.controller.DbControllerImpl;
import org.briarproject.briar.android.controller.handler.ResultHandler;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
@@ -38,52 +42,53 @@ import static org.briarproject.briar.android.controller.BriarControllerImpl.DOZE
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class NavDrawerControllerImpl extends DbControllerImpl
implements NavDrawerController, EventListener {
@NotNullByDefault
public class NavDrawerViewModel extends AndroidViewModel
implements EventListener {
private static final Logger LOG =
getLogger(NavDrawerControllerImpl.class.getName());
getLogger(NavDrawerViewModel.class.getName());
private static final String EXPIRY_DATE_WARNING = "expiryDateWarning";
static final TransportId[] TRANSPORT_IDS =
{TorConstants.ID, LanTcpConstants.ID, BluetoothConstants.ID};
private final PluginManager pluginManager;
@DatabaseExecutor
private final Executor dbExecutor;
private final SettingsManager settingsManager;
private final PluginManager pluginManager;
private final EventBus eventBus;
// UI thread
private TransportStateListener listener;
private final MutableLiveData<Boolean> showExpiryWarning =
new MutableLiveData<>();
private final MutableLiveData<Boolean> shouldAskForDozeWhitelisting =
new MutableLiveData<>();
private final MutableLiveData<Plugin.State> torPluginState =
new MutableLiveData<>();
private final MutableLiveData<Plugin.State> wifiPluginState =
new MutableLiveData<>();
private final MutableLiveData<Plugin.State> btPluginState =
new MutableLiveData<>();
@Inject
NavDrawerControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager, PluginManager pluginManager,
SettingsManager settingsManager, EventBus eventBus) {
super(dbExecutor, lifecycleManager);
this.pluginManager = pluginManager;
NavDrawerViewModel(Application app, @DatabaseExecutor Executor dbExecutor,
SettingsManager settingsManager, PluginManager pluginManager,
EventBus eventBus) {
super(app);
this.dbExecutor = dbExecutor;
this.settingsManager = settingsManager;
this.pluginManager = pluginManager;
this.eventBus = eventBus;
}
@Override
public void onActivityCreate(Activity activity) {
listener = (TransportStateListener) activity;
}
@Override
public void onActivityStart() {
eventBus.addListener(this);
updatePluginStates();
}
@Override
public void onActivityStop() {
protected void onCleared() {
eventBus.removeListener(this);
}
@Override
public void onActivityDestroy() {
}
@Override
public void eventOccurred(Event e) {
if (e instanceof TransportStateEvent) {
@@ -93,17 +98,22 @@ public class NavDrawerControllerImpl extends DbControllerImpl
if (LOG.isLoggable(INFO)) {
LOG.info("TransportStateEvent: " + id + " is " + state);
}
listener.stateUpdate(id, state);
MutableLiveData<Plugin.State> liveData = getPluginLiveData(id);
if (liveData != null) liveData.postValue(state);
}
}
@Override
public void showExpiryWarning(ResultHandler<Boolean> handler) {
LiveData<Boolean> showExpiryWarning() {
return showExpiryWarning;
}
@UiThread
void checkExpiryWarning() {
if (!IS_DEBUG_BUILD) {
handler.onResult(false);
showExpiryWarning.setValue(false);
return;
}
runOnDbThread(() -> {
dbExecutor.execute(() -> {
try {
Settings settings =
settingsManager.getSettings(SETTINGS_NAMESPACE);
@@ -111,7 +121,7 @@ public class NavDrawerControllerImpl extends DbControllerImpl
if (warningInt == 0) {
// we have not warned before
handler.onResult(true);
showExpiryWarning.postValue(true);
} else {
long warningLong = warningInt * 1000L;
long now = System.currentTimeMillis();
@@ -121,12 +131,12 @@ public class NavDrawerControllerImpl extends DbControllerImpl
(EXPIRY_DATE - now) / DAYS.toMillis(1);
if (daysSinceLastWarning >= 30) {
handler.onResult(true);
showExpiryWarning.postValue(true);
} else if (daysBeforeExpiry <= 3 &&
daysSinceLastWarning > 0) {
handler.onResult(true);
showExpiryWarning.postValue(true);
} else {
handler.onResult(false);
showExpiryWarning.postValue(false);
}
}
} catch (DbException e) {
@@ -135,9 +145,10 @@ public class NavDrawerControllerImpl extends DbControllerImpl
});
}
@Override
public void expiryWarningDismissed() {
runOnDbThread(() -> {
@UiThread
void expiryWarningDismissed() {
showExpiryWarning.setValue(false);
dbExecutor.execute(() -> {
try {
Settings settings = new Settings();
int date = (int) (System.currentTimeMillis() / 1000L);
@@ -149,31 +160,64 @@ public class NavDrawerControllerImpl extends DbControllerImpl
});
}
@Override
public void shouldAskForDozeWhitelisting(Context ctx,
ResultHandler<Boolean> handler) {
LiveData<Boolean> shouldAskForDozeWhitelisting() {
return shouldAskForDozeWhitelisting;
}
@UiThread
void checkDozeWhitelisting() {
// check this first, to hit the DbThread only when really necessary
if (!needsDozeWhitelisting(ctx)) {
handler.onResult(false);
if (!needsDozeWhitelisting(getApplication())) {
shouldAskForDozeWhitelisting.setValue(false);
return;
}
runOnDbThread(() -> {
dbExecutor.execute(() -> {
try {
Settings settings =
settingsManager.getSettings(SETTINGS_NAMESPACE);
boolean ask = settings.getBoolean(DOZE_ASK_AGAIN, true);
handler.onResult(ask);
shouldAskForDozeWhitelisting.postValue(ask);
} catch (DbException e) {
logException(LOG, WARNING, e);
handler.onResult(true);
shouldAskForDozeWhitelisting.postValue(true);
}
});
}
@Override
public State getTransportState(TransportId transportId) {
Plugin plugin = pluginManager.getPlugin(transportId);
private void updatePluginStates() {
for (TransportId t : TRANSPORT_IDS) {
MutableLiveData<Plugin.State> liveData = getPluginLiveData(t);
if (liveData == null) throw new AssertionError();
liveData.setValue(getTransportState(t));
}
}
private State getTransportState(TransportId id) {
Plugin plugin = pluginManager.getPlugin(id);
return plugin == null ? DISABLED : plugin.getState();
}
@Nullable
private MutableLiveData<State> getPluginLiveData(TransportId t) {
if (t.equals(TorConstants.ID)) {
return torPluginState;
} else if (t.equals(LanTcpConstants.ID)) {
return wifiPluginState;
} else if (t.equals(BluetoothConstants.ID)) {
return btPluginState;
} else {
return null;
}
}
LiveData<State> getPluginState(TransportId t) {
LiveData<Plugin.State> liveData = getPluginLiveData(t);
if (liveData == null) throw new AssertionError();
return liveData;
}
void setPluginEnabled(TransportId t, boolean enabled) {
pluginManager.setPluginEnabled(t, enabled);
}
}

View File

@@ -0,0 +1,86 @@
package org.briarproject.briar.android.navdrawer;
import android.view.View;
import android.widget.ImageView;
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 androidx.appcompat.widget.SwitchCompat;
import androidx.lifecycle.LifecycleOwner;
import static androidx.core.content.ContextCompat.getColor;
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.briar.android.navdrawer.NavDrawerViewModel.TRANSPORT_IDS;
class PluginViewController {
private final ImageView torIcon, wifiIcon, btIcon;
private final SwitchCompat torSwitch, wifiSwitch, btSwitch;
PluginViewController(View v, LifecycleOwner owner,
NavDrawerViewModel viewModel) {
torIcon = v.findViewById(R.id.torIcon);
wifiIcon = v.findViewById(R.id.wifiIcon);
btIcon = v.findViewById(R.id.btIcon);
torSwitch = v.findViewById(R.id.torSwitch);
wifiSwitch = v.findViewById(R.id.wifiSwitch);
btSwitch = v.findViewById(R.id.btSwitch);
for (TransportId t : TRANSPORT_IDS) {
// a OnCheckedChangeListener would get triggered on programmatic updates
SwitchCompat switchCompat = getSwitch(t);
switchCompat.setOnClickListener(buttonView ->
// TODO check reason first and change settings if needed
viewModel.setPluginEnabled(t, switchCompat.isChecked())
);
viewModel.getPluginState(t)
.observe(owner, state -> stateUpdate(t, state));
}
}
private void stateUpdate(TransportId id, State state) {
updateIcon(getIcon(id), state);
updateSwitch(getSwitch(id), state);
}
private SwitchCompat getSwitch(TransportId id) {
if (id == TorConstants.ID) return torSwitch;
if (id == BluetoothConstants.ID) return btSwitch;
if (id == LanTcpConstants.ID) return wifiSwitch;
throw new AssertionError();
}
private void updateSwitch(SwitchCompat switchCompat, State state) {
switchCompat.setChecked(state != DISABLED);
}
private ImageView getIcon(TransportId id) {
if (id == TorConstants.ID) return torIcon;
if (id == BluetoothConstants.ID) return btIcon;
if (id == LanTcpConstants.ID) return wifiIcon;
throw new AssertionError();
}
private void updateIcon(ImageView icon, State state) {
int colorRes;
if (state == ACTIVE) {
colorRes = R.color.briar_green_light;
} else if (state == ENABLING) {
colorRes = R.color.briar_yellow;
} else {
colorRes = android.R.color.tertiary_text_light;
}
int color = getColor(icon.getContext(), colorRes);
icon.setColorFilter(color);
}
}

View File

@@ -1,12 +0,0 @@
package org.briarproject.briar.android.navdrawer;
import org.briarproject.bramble.api.plugin.Plugin.State;
import org.briarproject.bramble.api.plugin.TransportId;
import androidx.annotation.UiThread;
interface TransportStateListener {
@UiThread
void stateUpdate(TransportId id, State state);
}

View File

@@ -20,8 +20,6 @@ import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
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.TorConstants;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.SettingsManager;
@@ -42,6 +40,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.core.text.TextUtilsCompat;
@@ -73,7 +72,6 @@ import static android.widget.Toast.LENGTH_SHORT;
import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
@@ -112,15 +110,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
"pref_key_lock_timeout";
public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in";
private static final String BT_NAMESPACE =
BluetoothConstants.ID.getString();
private static final String BT_ENABLE = "pref_key_bluetooth";
private static final String WIFI_NAMESPACE = LanTcpConstants.ID.getString();
private static final String WIFI_ENABLE = "pref_key_wifi";
private static final String TOR_NAMESPACE = TorConstants.ID.getString();
private static final String TOR_ENABLE = "pref_key_tor_enable";
private static final String TOR_NETWORK = "pref_key_tor_network";
private static final String TOR_MOBILE = "pref_key_tor_mobile_data";
private static final String TOR_ONLY_WHEN_CHARGING =
@@ -131,9 +121,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
private SettingsActivity listener;
private ListPreference language;
private SwitchPreference enableBluetooth;
private SwitchPreference enableWifi;
private SwitchPreference enableTor;
private ListPreference torNetwork;
private SwitchPreference torMobile;
private SwitchPreference torOnlyWhenCharging;
@@ -148,7 +135,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
private Preference notifySound;
// Fields that are accessed from background threads must be volatile
private volatile Settings settings, btSettings, wifiSettings, torSettings;
private volatile Settings settings, torSettings;
private volatile boolean settingsLoaded = false;
@Inject
@@ -177,9 +164,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
language = findPreference(LANGUAGE);
setLanguageEntries();
ListPreference theme = findPreference("pref_key_theme");
enableBluetooth = findPreference(BT_ENABLE);
enableWifi = findPreference(WIFI_ENABLE);
enableTor = findPreference(TOR_ENABLE);
torNetwork = findPreference(TOR_NETWORK);
torMobile = findPreference(TOR_MOBILE);
torOnlyWhenCharging = findPreference(TOR_ONLY_WHEN_CHARGING);
@@ -211,9 +195,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
}
return true;
});
enableBluetooth.setOnPreferenceChangeListener(this);
enableWifi.setOnPreferenceChangeListener(this);
enableTor.setOnPreferenceChangeListener(this);
torNetwork.setOnPreferenceChangeListener(this);
torMobile.setOnPreferenceChangeListener(this);
torOnlyWhenCharging.setOnPreferenceChangeListener(this);
@@ -256,8 +237,9 @@ public class SettingsFragment extends PreferenceFragmentCompat
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
ColorDrawable divider = new ColorDrawable(
ContextCompat.getColor(requireContext(), R.color.divider));
@@ -359,8 +341,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
try {
long start = now();
settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
btSettings = settingsManager.getSettings(BT_NAMESPACE);
wifiSettings = settingsManager.getSettings(WIFI_NAMESPACE);
torSettings = settingsManager.getSettings(TOR_NAMESPACE);
settingsLoaded = true;
logDuration(LOG, "Loading settings", start);
@@ -376,18 +356,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
// due to events, we might try to display before a load completed
if (!settingsLoaded) return;
boolean btEnabledSetting =
btSettings.getBoolean(PREF_PLUGIN_ENABLE, false);
enableBluetooth.setChecked(btEnabledSetting);
boolean wifiEnabledSetting =
wifiSettings.getBoolean(PREF_PLUGIN_ENABLE, false);
enableWifi.setChecked(wifiEnabledSetting);
boolean torEnabledSetting =
torSettings.getBoolean(PREF_PLUGIN_ENABLE, true);
enableTor.setChecked(torEnabledSetting);
int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK,
PREF_TOR_NETWORK_AUTOMATIC);
torNetwork.setValue(Integer.toString(torNetworkSetting));
@@ -459,9 +427,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
// preferences partly needed here, because they have their own logic
// - pref_key_lock (screenLock -> displayScreenLockSetting())
// - pref_key_lock_timeout (screenLockTimeout)
enableBluetooth.setEnabled(enabled);
enableWifi.setEnabled(enabled);
enableTor.setEnabled(enabled);
torNetwork.setEnabled(enabled);
torMobile.setEnabled(enabled);
torOnlyWhenCharging.setEnabled(enabled);
@@ -563,15 +528,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
if (!language.getValue().equals(newValue))
languageChanged((String) newValue);
return false;
} else if (preference == enableBluetooth) {
boolean btSetting = (Boolean) newValue;
storeBluetoothSetting(btSetting);
} else if (preference == enableWifi) {
boolean wifiSetting = (Boolean) newValue;
storeWifiSetting(wifiSetting);
} else if (preference == enableTor) {
boolean torEnabledSetting = (Boolean) newValue;
storeTorEnabledSetting(torEnabledSetting);
} else if (preference == torNetwork) {
int torNetworkSetting = Integer.valueOf((String) newValue);
storeTorNetworkSetting(torNetworkSetting);
@@ -635,12 +591,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
builder.show();
}
private void storeTorEnabledSetting(boolean torEnabledSetting) {
Settings s = new Settings();
s.putBoolean(PREF_PLUGIN_ENABLE, torEnabledSetting);
mergeSettings(s, TOR_NAMESPACE);
}
private void storeTorNetworkSetting(int torNetworkSetting) {
Settings s = new Settings();
s.putInt(PREF_TOR_NETWORK, torNetworkSetting);
@@ -659,18 +609,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
mergeSettings(s, TOR_NAMESPACE);
}
private void storeBluetoothSetting(boolean btSetting) {
Settings s = new Settings();
s.putBoolean(PREF_PLUGIN_ENABLE, btSetting);
mergeSettings(s, BT_NAMESPACE);
}
private void storeWifiSetting(boolean wifiSetting) {
Settings s = new Settings();
s.putBoolean(PREF_PLUGIN_ENABLE, wifiSetting);
mergeSettings(s, WIFI_NAMESPACE);
}
private void storeSettings(Settings s) {
mergeSettings(s, SETTINGS_NAMESPACE);
}
@@ -729,14 +667,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
LOG.info("Settings updated");
settings = s.getSettings();
displaySettings();
} else if (namespace.equals(BT_NAMESPACE)) {
LOG.info("Bluetooth settings updated");
btSettings = s.getSettings();
displaySettings();
} else if (namespace.equals(WIFI_NAMESPACE)) {
LOG.info("Wifi settings updated");
wifiSettings = s.getSettings();
displaySettings();
} else if (namespace.equals(TOR_NAMESPACE)) {
LOG.info("Tor settings updated");
torSettings = s.getSettings();

View File

@@ -14,12 +14,12 @@
android:layout_marginBottom="8dp"
android:background="@color/divider"
android:src="@drawable/chevron_down_white"
app:tint="?attr/colorControlNormal"
app:layout_constraintBottom_toTopOf="@+id/longRangeLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/navigation"
app:layout_constraintVertical_bias="1.0"
app:tint="?attr/colorControlNormal"
tools:ignore="ContentDescription"
tools:visibility="visible" />
@@ -54,8 +54,8 @@
app:layout_constraintBottom_toBottomOf="@+id/torSwitch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/torSwitch"
app:tint="@color/briar_green"
tools:ignore="ContentDescription" />
tools:ignore="ContentDescription"
tools:tint="@color/briar_green" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/torSwitch"
@@ -94,9 +94,9 @@
app:layout_constraintBottom_toBottomOf="@+id/wifiSwitch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/wifiSwitch"
app:tint="@color/briar_green"
tools:checked="true"
tools:ignore="ContentDescription" />
tools:ignore="ContentDescription"
tools:tint="@color/briar_green" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/wifiSwitch"
@@ -123,9 +123,9 @@
app:layout_constraintBottom_toBottomOf="@+id/btSwitch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/btSwitch"
app:tint="@color/briar_green"
tools:checked="true"
tools:ignore="ContentDescription" />
tools:ignore="ContentDescription"
tools:tint="@color/briar_green" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/btSwitch"

View File

@@ -29,33 +29,8 @@
android:layout="@layout/preferences_category"
android:title="@string/network_settings_title">
<SwitchPreference
android:defaultValue="false"
android:key="pref_key_bluetooth"
android:persistent="false"
android:title="@string/bluetooth_setting"
android:widgetLayout="@layout/preference_switch_compat"
app:iconSpaceReserved="false"/>
<SwitchPreference
android:defaultValue="false"
android:key="pref_key_wifi"
android:persistent="false"
android:title="@string/wifi_setting"
android:widgetLayout="@layout/preference_switch_compat"
app:iconSpaceReserved="false"/>
<SwitchPreference
android:defaultValue="true"
android:key="pref_key_tor_enable"
android:persistent="false"
android:title="@string/tor_enable_title"
android:widgetLayout="@layout/preference_switch_compat"
app:iconSpaceReserved="false"/>
<ListPreference
android:defaultValue="0"
android:dependency="pref_key_tor_enable"
android:entries="@array/tor_network_setting_names"
android:entryValues="@array/tor_network_setting_values"
android:key="pref_key_tor_network"
@@ -66,7 +41,6 @@
<SwitchPreference
android:defaultValue="true"
android:dependency="pref_key_tor_enable"
android:key="pref_key_tor_mobile_data"
android:persistent="false"
android:title="@string/tor_mobile_data_title"
@@ -75,7 +49,6 @@
<SwitchPreference
android:defaultValue="false"
android:dependency="pref_key_tor_enable"
android:key="pref_key_tor_only_when_charging"
android:persistent="false"
android:title="@string/tor_only_when_charging_title"