Added option to connect account via VPN only

This commit is contained in:
M66B 2022-09-05 22:41:30 +02:00
parent 7677b34c4e
commit f0939d0069
6 changed files with 55 additions and 18 deletions

View File

@ -128,6 +128,7 @@ public class FragmentAccount extends FragmentBase {
private RadioGroup rgDate;
private CheckBox cbUnicode;
private CheckBox cbUnmetered;
private CheckBox cbVpnOnly;
private Button btnCheck;
private ContentLoadingProgressBar pbCheck;
@ -240,6 +241,7 @@ public class FragmentAccount extends FragmentBase {
rgDate = view.findViewById(R.id.rgDate);
cbUnicode = view.findViewById(R.id.cbUnicode);
cbUnmetered = view.findViewById(R.id.cbUnmeteredOnly);
cbVpnOnly = view.findViewById(R.id.cbVpnOnly);
btnCheck = view.findViewById(R.id.btnCheck);
pbCheck = view.findViewById(R.id.pbCheck);
@ -909,6 +911,7 @@ public class FragmentAccount extends FragmentBase {
args.putBoolean("use_received", rgDate.getCheckedRadioButtonId() == R.id.radio_received_header);
args.putBoolean("unicode", cbUnicode.isChecked());
args.putBoolean("unmetered", cbUnmetered.isChecked());
args.putBoolean("vpn_only", cbVpnOnly.isChecked());
args.putSerializable("drafts", drafts);
args.putSerializable("sent", sent);
@ -982,6 +985,7 @@ public class FragmentAccount extends FragmentBase {
boolean use_received = args.getBoolean("use_received");
boolean unicode = args.getBoolean("unicode");
boolean unmetered = args.getBoolean("unmetered");
boolean vpn_only = args.getBoolean("vpn_only");
EntityFolder drafts = (EntityFolder) args.getSerializable("drafts");
EntityFolder sent = (EntityFolder) args.getSerializable("sent");
@ -1094,6 +1098,8 @@ public class FragmentAccount extends FragmentBase {
return true;
if (unmetered != jconditions.optBoolean("unmetered"))
return true;
if (vpn_only != jconditions.optBoolean("vpn_only"))
return true;
if (account.error != null && account.synchronize)
return true;
@ -1238,6 +1244,7 @@ public class FragmentAccount extends FragmentBase {
account.unicode = unicode;
jconditions.put("unmetered", unmetered);
jconditions.put("vpn_only", vpn_only);
account.conditions = jconditions.toString();
if (!update)
@ -1600,6 +1607,7 @@ public class FragmentAccount extends FragmentBase {
cbIgnoreSize.setChecked(account == null ? false : account.ignore_size);
cbUnicode.setChecked(account == null ? false : account.unicode);
cbUnmetered.setChecked(jcondition.optBoolean("unmetered"));
cbVpnOnly.setChecked(jcondition.optBoolean("vpn_only"));
if (account != null && account.use_date)
rgDate.check(R.id.radio_date_header);

View File

@ -98,6 +98,7 @@ public class FragmentPop extends FragmentBase {
private EditText etMax;
private EditText etInterval;
private CheckBox cbUnmetered;
private CheckBox cbVpnOnly;
private ArrayAdapter<EntityFolder> adapterSwipe;
private Spinner spLeft;
@ -165,6 +166,7 @@ public class FragmentPop extends FragmentBase {
etMax = view.findViewById(R.id.etMax);
etInterval = view.findViewById(R.id.etInterval);
cbUnmetered = view.findViewById(R.id.cbUnmeteredOnly);
cbVpnOnly = view.findViewById(R.id.cbVpnOnly);
spLeft = view.findViewById(R.id.spLeft);
spRight = view.findViewById(R.id.spRight);
@ -332,6 +334,7 @@ public class FragmentPop extends FragmentBase {
args.putString("max", etMax.getText().toString());
args.putString("interval", etInterval.getText().toString());
args.putBoolean("unmetered", cbUnmetered.isChecked());
args.putBoolean("vpn_only", cbVpnOnly.isChecked());
args.putLong("left", ((EntityFolder) spLeft.getSelectedItem()).id);
args.putLong("right", ((EntityFolder) spRight.getSelectedItem()).id);
@ -384,6 +387,7 @@ public class FragmentPop extends FragmentBase {
String max = args.getString("max");
String interval = args.getString("interval");
boolean unmetered = args.getBoolean("unmetered");
boolean vpn_only = args.getBoolean("vpn_only");
long left = args.getLong("left");
long right = args.getLong("right");
@ -476,6 +480,8 @@ public class FragmentPop extends FragmentBase {
return true;
if (unmetered != jconditions.optBoolean("unmetered"))
return true;
if (vpn_only != jconditions.optBoolean("vpn_only"))
return true;
if (!Objects.equals(account.swipe_left, left))
return true;
@ -557,6 +563,7 @@ public class FragmentPop extends FragmentBase {
account.poll_interval = poll_interval;
jconditions.put("unmetered", unmetered);
jconditions.put("vpn_only", vpn_only);
account.conditions = jconditions.toString();
account.swipe_left = left;
@ -755,6 +762,7 @@ public class FragmentPop extends FragmentBase {
etInterval.setText(account == null ? "" : Long.toString(account.poll_interval));
cbUnmetered.setChecked(jcondition.optBoolean("unmetered"));
cbVpnOnly.setChecked(jcondition.optBoolean("vpn_only"));
cbIdentity.setChecked(account == null);
List<EntityFolder> folders = getSwipeActions();

View File

@ -297,7 +297,7 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
}
if (current.accountState.synchronize)
operations += current.accountState.operations;
if (current.accountState.operations > 0 && current.canConnect())
if (current.accountState.operations > 0 && current.canConnect(ServiceSynchronize.this))
runFts = false;
long account = current.command.getLong("account", -1);
@ -313,11 +313,11 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
int index = accountStates.indexOf(current);
if (index < 0) {
if (current.canRun()) {
if (current.canRun(ServiceSynchronize.this)) {
EntityLog.log(ServiceSynchronize.this, EntityLog.Type.Scheduling,
"### new " + current +
" force=" + force +
" start=" + current.canRun() +
" start=" + current.canRun(ServiceSynchronize.this) +
" sync=" + current.accountState.isEnabled(current.enabled) +
" enabled=" + current.accountState.synchronize +
" ondemand=" + current.accountState.ondemand +
@ -347,15 +347,15 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
// Some networks disallow email server connections:
// - reload on network type change when disconnected
if (reload ||
prev.canRun() != current.canRun() ||
prev.canRun(ServiceSynchronize.this) != current.canRun(ServiceSynchronize.this) ||
!prev.accountState.equals(current.accountState)) {
if (prev.canRun() || current.canRun())
if (prev.canRun(ServiceSynchronize.this) || current.canRun(ServiceSynchronize.this))
EntityLog.log(ServiceSynchronize.this, EntityLog.Type.Scheduling,
"### changed " + current +
" reload=" + reload +
" force=" + force +
" stop=" + prev.canRun() +
" start=" + current.canRun() +
" stop=" + prev.canRun(ServiceSynchronize.this) +
" start=" + current.canRun(ServiceSynchronize.this) +
" sync=" + sync +
" enabled=" + current.accountState.isEnabled(current.enabled) +
" should=" + current.accountState.shouldRun(current.enabled) +
@ -367,15 +367,15 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
" tbd=" + current.accountState.tbd +
" state=" + current.accountState.state +
" active=" + prev.networkState.getActive() + "/" + current.networkState.getActive());
if (prev.canRun()) {
if (prev.canRun(ServiceSynchronize.this)) {
event = true;
stop(prev);
}
if (current.canRun()) {
if (current.canRun(ServiceSynchronize.this)) {
event = true;
start(current, current.accountState.isEnabled(current.enabled) || sync, force);
}
} else if (current.canRun() && !state.isAlive()) {
} else if (current.canRun(ServiceSynchronize.this) && !state.isAlive()) {
Log.e(current + " died");
EntityLog.log(ServiceSynchronize.this, "### died " + current);
event = true;

View File

@ -19,6 +19,7 @@ package eu.faircode.email;
Copyright 2018-2022 by Marcel Bokhorst (M66B)
*/
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
@ -61,13 +62,15 @@ public class TupleAccountNetworkState {
this.enabled = false;
}
public boolean canConnect() {
public boolean canConnect(Context context) {
boolean unmetered = jconditions.optBoolean("unmetered");
return (!unmetered || this.networkState.isUnmetered());
boolean vpn_only = jconditions.optBoolean("vpn_only");
return (!unmetered || this.networkState.isUnmetered()) &&
(!vpn_only || ConnectionHelper.vpnActive(context));
}
public boolean canRun() {
if (!canConnect())
public boolean canRun(Context context) {
if (!canConnect(context))
return false;
return (this.networkState.isSuitable() && this.accountState.shouldRun(enabled));

View File

@ -715,6 +715,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbUnicode" />
<CheckBox
android:id="@+id/cbVpnOnly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_vpn_only"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbUnmeteredOnly" />
<!-- check -->
<Button
@ -727,7 +736,7 @@
android:tag="disable"
android:text="@string/title_check"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbUnmeteredOnly" />
app:layout_constraintTop_toBottomOf="@id/cbVpnOnly" />
<eu.faircode.email.ContentLoadingProgressBar
android:id="@+id/pbCheck"
@ -1115,7 +1124,7 @@
cbAutoSeen,
tvInterval,etInterval,tvIntervalRemark,cbNoop,tvNoopRemark,
cbPartialFetch,tvPartialFetchRemark,cbIgnoreSize,rgDate,tvDateRemark,
cbUnicode,cbUnmeteredOnly" />
cbUnicode,cbUnmeteredOnly,cbVpnOnly" />
<androidx.constraintlayout.widget.Group
android:id="@+id/grpFolders"

View File

@ -226,10 +226,10 @@
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
app:drawableTint="?android:attr/textColorLink"
android:text="@string/title_password_storage"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCaseSensitive" />
@ -484,6 +484,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvIntervalRemark" />
<CheckBox
android:id="@+id/cbVpnOnly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_vpn_only"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbUnmeteredOnly" />
<TextView
android:id="@+id/tvLeft"
android:layout_width="wrap_content"
@ -492,7 +501,7 @@
android:text="@string/title_account_left"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cbUnmeteredOnly" />
app:layout_constraintTop_toBottomOf="@+id/cbVpnOnly" />
<Spinner
android:id="@+id/spLeft"