mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-02 01:01:17 +00:00
Add individual sync conditions for devices (#96)
* SyncConditionsActivity - Rename "folder" to "object" as it can mean a folder or device. * Implement per-device sync conditions * Default custom wifi whitelist to "all enabled" * Update APK version to 0.14.51.7 / 4170 * Add checkbox "use Wi-Fi whitelist" in global run conditions * Rename variable
This commit is contained in:
parent
b84d4da34f
commit
f8692f02ef
13 changed files with 277 additions and 64 deletions
|
@ -35,8 +35,8 @@ android {
|
||||||
applicationId "com.github.catfriend1.syncthingandroid"
|
applicationId "com.github.catfriend1.syncthingandroid"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
versionCode 4169
|
versionCode 4170
|
||||||
versionName "0.14.51.6"
|
versionName "0.14.51.7"
|
||||||
testApplicationId 'com.github.catfriend1.syncthingandroid.test'
|
testApplicationId 'com.github.catfriend1.syncthingandroid.test'
|
||||||
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
|
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
|
||||||
playAccountConfig = playAccountConfigs.defaultAccountConfig
|
playAccountConfig = playAccountConfigs.defaultAccountConfig
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.nutomic.syncthingandroid;
|
package com.nutomic.syncthingandroid;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.activities.DeviceActivity;
|
||||||
import com.nutomic.syncthingandroid.activities.FirstStartActivity;
|
import com.nutomic.syncthingandroid.activities.FirstStartActivity;
|
||||||
import com.nutomic.syncthingandroid.activities.FolderActivity;
|
import com.nutomic.syncthingandroid.activities.FolderActivity;
|
||||||
import com.nutomic.syncthingandroid.activities.FolderPickerActivity;
|
import com.nutomic.syncthingandroid.activities.FolderPickerActivity;
|
||||||
|
@ -26,6 +27,7 @@ public interface DaggerComponent {
|
||||||
void inject(SyncthingApp app);
|
void inject(SyncthingApp app);
|
||||||
void inject(MainActivity activity);
|
void inject(MainActivity activity);
|
||||||
void inject(FirstStartActivity activity);
|
void inject(FirstStartActivity activity);
|
||||||
|
void inject(DeviceActivity activity);
|
||||||
void inject(FolderActivity activity);
|
void inject(FolderActivity activity);
|
||||||
void inject(FolderPickerActivity activity);
|
void inject(FolderPickerActivity activity);
|
||||||
void inject(SyncConditionsActivity activity);
|
void inject(SyncConditionsActivity activity);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
@ -24,10 +25,14 @@ import android.widget.Toast;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
import com.google.zxing.integration.android.IntentResult;
|
import com.google.zxing.integration.android.IntentResult;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.model.Connections;
|
import com.nutomic.syncthingandroid.model.Connections;
|
||||||
import com.nutomic.syncthingandroid.model.Device;
|
import com.nutomic.syncthingandroid.model.Device;
|
||||||
|
import com.nutomic.syncthingandroid.service.Constants;
|
||||||
|
import com.nutomic.syncthingandroid.service.RestApi;
|
||||||
import com.nutomic.syncthingandroid.service.SyncthingService;
|
import com.nutomic.syncthingandroid.service.SyncthingService;
|
||||||
|
import com.nutomic.syncthingandroid.SyncthingApp;
|
||||||
import com.nutomic.syncthingandroid.util.Compression;
|
import com.nutomic.syncthingandroid.util.Compression;
|
||||||
import com.nutomic.syncthingandroid.util.TextWatcherAdapter;
|
import com.nutomic.syncthingandroid.util.TextWatcherAdapter;
|
||||||
import com.nutomic.syncthingandroid.util.Util;
|
import com.nutomic.syncthingandroid.util.Util;
|
||||||
|
@ -36,6 +41,8 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static android.text.TextUtils.isEmpty;
|
import static android.text.TextUtils.isEmpty;
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
@ -46,7 +53,11 @@ import static com.nutomic.syncthingandroid.util.Compression.METADATA;
|
||||||
/**
|
/**
|
||||||
* Shows device details and allows changing them.
|
* Shows device details and allows changing them.
|
||||||
*/
|
*/
|
||||||
public class DeviceActivity extends SyncthingActivity implements View.OnClickListener {
|
public class DeviceActivity extends SyncthingActivity
|
||||||
|
implements
|
||||||
|
View.OnClickListener,
|
||||||
|
SyncthingActivity.OnServiceConnectedListener,
|
||||||
|
SyncthingService.OnServiceStateChangeListener {
|
||||||
|
|
||||||
public static final String EXTRA_NOTIFICATION_ID =
|
public static final String EXTRA_NOTIFICATION_ID =
|
||||||
"com.nutomic.syncthingandroid.activities.DeviceActivity.NOTIFICATION_ID";
|
"com.nutomic.syncthingandroid.activities.DeviceActivity.NOTIFICATION_ID";
|
||||||
|
@ -84,10 +95,19 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
|
|
||||||
private SwitchCompat mDevicePaused;
|
private SwitchCompat mDevicePaused;
|
||||||
|
|
||||||
|
private SwitchCompat mCustomSyncConditionsSwitch;
|
||||||
|
|
||||||
|
private TextView mCustomSyncConditionsDescription;
|
||||||
|
|
||||||
|
private TextView mCustomSyncConditionsDialog;
|
||||||
|
|
||||||
private TextView mSyncthingVersionView;
|
private TextView mSyncthingVersionView;
|
||||||
|
|
||||||
private View mCompressionContainer;
|
private View mCompressionContainer;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SharedPreferences mPreferences;
|
||||||
|
|
||||||
private boolean mIsCreateMode;
|
private boolean mIsCreateMode;
|
||||||
|
|
||||||
private boolean mDeviceNeedsToUpdate;
|
private boolean mDeviceNeedsToUpdate;
|
||||||
|
@ -154,6 +174,12 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
mDevice.paused = isChecked;
|
mDevice.paused = isChecked;
|
||||||
mDeviceNeedsToUpdate = true;
|
mDeviceNeedsToUpdate = true;
|
||||||
break;
|
break;
|
||||||
|
case R.id.customSyncConditionsSwitch:
|
||||||
|
mCustomSyncConditionsDescription.setEnabled(isChecked);
|
||||||
|
mCustomSyncConditionsDialog.setEnabled(isChecked);
|
||||||
|
// This is needed to display the "discard changes dialog".
|
||||||
|
mDeviceNeedsToUpdate = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -161,11 +187,12 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
((SyncthingApp) getApplication()).component().inject(this);
|
||||||
setContentView(R.layout.fragment_device);
|
setContentView(R.layout.fragment_device);
|
||||||
|
|
||||||
mIsCreateMode = getIntent().getBooleanExtra(EXTRA_IS_CREATE, false);
|
mIsCreateMode = getIntent().getBooleanExtra(EXTRA_IS_CREATE, false);
|
||||||
registerOnServiceConnectedListener(this::onServiceConnected);
|
|
||||||
setTitle(mIsCreateMode ? R.string.add_device : R.string.edit_device);
|
setTitle(mIsCreateMode ? R.string.add_device : R.string.edit_device);
|
||||||
|
registerOnServiceConnectedListener(this);
|
||||||
|
|
||||||
mIdContainer = findViewById(R.id.idContainer);
|
mIdContainer = findViewById(R.id.idContainer);
|
||||||
mIdView = findViewById(R.id.id);
|
mIdView = findViewById(R.id.id);
|
||||||
|
@ -177,9 +204,13 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
mCompressionValueView = findViewById(R.id.compressionValue);
|
mCompressionValueView = findViewById(R.id.compressionValue);
|
||||||
mIntroducerView = findViewById(R.id.introducer);
|
mIntroducerView = findViewById(R.id.introducer);
|
||||||
mDevicePaused = findViewById(R.id.devicePause);
|
mDevicePaused = findViewById(R.id.devicePause);
|
||||||
|
mCustomSyncConditionsSwitch = findViewById(R.id.customSyncConditionsSwitch);
|
||||||
|
mCustomSyncConditionsDescription = findViewById(R.id.customSyncConditionsDescription);
|
||||||
|
mCustomSyncConditionsDialog = findViewById(R.id.customSyncConditionsDialog);
|
||||||
mSyncthingVersionView = findViewById(R.id.syncthingVersion);
|
mSyncthingVersionView = findViewById(R.id.syncthingVersion);
|
||||||
|
|
||||||
mQrButton.setOnClickListener(this);
|
mQrButton.setOnClickListener(this);
|
||||||
|
mCustomSyncConditionsDialog.setOnClickListener(view -> onCustomSyncConditionsDialogClick());
|
||||||
mCompressionContainer.setOnClickListener(this);
|
mCompressionContainer.setOnClickListener(this);
|
||||||
|
|
||||||
if (savedInstanceState != null){
|
if (savedInstanceState != null){
|
||||||
|
@ -198,6 +229,19 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked after user clicked on the {@link mCustomSyncConditionsDialog} label.
|
||||||
|
*/
|
||||||
|
private void onCustomSyncConditionsDialogClick() {
|
||||||
|
startActivityForResult(
|
||||||
|
SyncConditionsActivity.createIntent(
|
||||||
|
this, Constants.PREF_OBJECT_PREFIX_DEVICE + mDevice.deviceID, mDevice.name
|
||||||
|
),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
private void restoreDialogStates(Bundle savedInstanceState) {
|
private void restoreDialogStates(Bundle savedInstanceState) {
|
||||||
if (savedInstanceState.getBoolean(IS_SHOWING_COMPRESSION_DIALOG)){
|
if (savedInstanceState.getBoolean(IS_SHOWING_COMPRESSION_DIALOG)){
|
||||||
showCompressionDialog();
|
showCompressionDialog();
|
||||||
|
@ -257,20 +301,32 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
Util.dismissDialogSafe(mDeleteDialog, this);
|
Util.dismissDialogSafe(mDeleteDialog, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onServiceConnected() {
|
/**
|
||||||
|
* Register for service state change events.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected() {
|
||||||
Log.v(TAG, "onServiceConnected");
|
Log.v(TAG, "onServiceConnected");
|
||||||
SyncthingService syncthingService = (SyncthingService) getService();
|
SyncthingService syncthingService = (SyncthingService) getService();
|
||||||
syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0));
|
syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0));
|
||||||
syncthingService.registerOnServiceStateChangeListener(this::onServiceStateChange);
|
syncthingService.registerOnServiceStateChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets version and current address of the device.
|
* Sets version and current address of the device.
|
||||||
* <p/>
|
|
||||||
* NOTE: This is only called once on startup, should be called more often to properly display
|
* NOTE: This is only called once on startup, should be called more often to properly display
|
||||||
* version/address changes.
|
* version/address changes.
|
||||||
*/
|
*/
|
||||||
private void onReceiveConnections(Connections connections) {
|
private void onReceiveConnections(Connections connections) {
|
||||||
|
if (connections == null || connections.connections == null) {
|
||||||
|
Log.e(TAG, "onReceiveConnections: connections == null || connections.connections == null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mDevice == null) {
|
||||||
|
Log.e(TAG, "onReceiveConnections: mDevice == null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean viewsExist = mSyncthingVersionView != null && mCurrentAddressView != null;
|
boolean viewsExist = mSyncthingVersionView != null && mCurrentAddressView != null;
|
||||||
if (viewsExist && connections.connections.containsKey(mDevice.deviceID)) {
|
if (viewsExist && connections.connections.containsKey(mDevice.deviceID)) {
|
||||||
mCurrentAddressView.setVisibility(VISIBLE);
|
mCurrentAddressView.setVisibility(VISIBLE);
|
||||||
|
@ -280,18 +336,21 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onServiceStateChange(SyncthingService.State currentState) {
|
@Override
|
||||||
|
public void onServiceStateChange(SyncthingService.State currentState) {
|
||||||
if (currentState != ACTIVE) {
|
if (currentState != ACTIVE) {
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mIsCreateMode) {
|
if (!mIsCreateMode) {
|
||||||
List<Device> devices = getApi().getDevices(false);
|
RestApi restApi = getApi(); // restApi != null because of State.ACTIVE
|
||||||
|
List<Device> devices = restApi.getDevices(false);
|
||||||
|
String passedId = getIntent().getStringExtra(EXTRA_DEVICE_ID);
|
||||||
mDevice = null;
|
mDevice = null;
|
||||||
for (Device device : devices) {
|
for (Device currentDevice : devices) {
|
||||||
if (device.deviceID.equals(getIntent().getStringExtra(EXTRA_DEVICE_ID))) {
|
if (currentDevice.deviceID.equals(passedId)) {
|
||||||
mDevice = device;
|
mDevice = currentDevice;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,10 +359,10 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (restApi != null) {
|
||||||
|
restApi.getConnections(this::onReceiveConnections);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getApi().getConnections(this::onReceiveConnections);
|
|
||||||
|
|
||||||
updateViewsAndSetListeners();
|
updateViewsAndSetListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +372,7 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
mAddressesView.removeTextChangedListener(mAddressesTextWatcher);
|
mAddressesView.removeTextChangedListener(mAddressesTextWatcher);
|
||||||
mIntroducerView.setOnCheckedChangeListener(null);
|
mIntroducerView.setOnCheckedChangeListener(null);
|
||||||
mDevicePaused.setOnCheckedChangeListener(null);
|
mDevicePaused.setOnCheckedChangeListener(null);
|
||||||
|
mCustomSyncConditionsSwitch.setOnCheckedChangeListener(null);
|
||||||
|
|
||||||
// Update views
|
// Update views
|
||||||
mIdView.setText(mDevice.deviceID);
|
mIdView.setText(mDevice.deviceID);
|
||||||
|
@ -322,12 +382,26 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
mIntroducerView.setChecked(mDevice.introducer);
|
mIntroducerView.setChecked(mDevice.introducer);
|
||||||
mDevicePaused.setChecked(mDevice.paused);
|
mDevicePaused.setChecked(mDevice.paused);
|
||||||
|
|
||||||
|
// Update views - custom sync conditions.
|
||||||
|
mCustomSyncConditionsSwitch.setChecked(false);
|
||||||
|
if (mIsCreateMode) {
|
||||||
|
findViewById(R.id.customSyncConditionsContainer).setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
mCustomSyncConditionsSwitch.setChecked(mPreferences.getBoolean(
|
||||||
|
Constants.DYN_PREF_OBJECT_CUSTOM_SYNC_CONDITIONS(Constants.PREF_OBJECT_PREFIX_DEVICE + mDevice.deviceID), false
|
||||||
|
));
|
||||||
|
}
|
||||||
|
mCustomSyncConditionsSwitch.setEnabled(!mIsCreateMode);
|
||||||
|
mCustomSyncConditionsDescription.setEnabled(mCustomSyncConditionsSwitch.isChecked());
|
||||||
|
mCustomSyncConditionsDialog.setEnabled(mCustomSyncConditionsSwitch.isChecked());
|
||||||
|
|
||||||
// Keep state updated
|
// Keep state updated
|
||||||
mIdView.addTextChangedListener(mIdTextWatcher);
|
mIdView.addTextChangedListener(mIdTextWatcher);
|
||||||
mNameView.addTextChangedListener(mNameTextWatcher);
|
mNameView.addTextChangedListener(mNameTextWatcher);
|
||||||
mAddressesView.addTextChangedListener(mAddressesTextWatcher);
|
mAddressesView.addTextChangedListener(mAddressesTextWatcher);
|
||||||
mIntroducerView.setOnCheckedChangeListener(mCheckedListener);
|
mIntroducerView.setOnCheckedChangeListener(mCheckedListener);
|
||||||
mDevicePaused.setOnCheckedChangeListener(mCheckedListener);
|
mDevicePaused.setOnCheckedChangeListener(mCheckedListener);
|
||||||
|
mCustomSyncConditionsSwitch.setOnCheckedChangeListener(mCheckedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -423,11 +497,34 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the updated device info if in edit mode.
|
* Sends the updated device info if in edit mode.
|
||||||
|
* Preconditions: mDeviceNeedsToUpdate == true
|
||||||
*/
|
*/
|
||||||
private void updateDevice() {
|
private void updateDevice() {
|
||||||
if (!mIsCreateMode && mDeviceNeedsToUpdate && mDevice != null) {
|
if (mIsCreateMode) {
|
||||||
getApi().editDevice(mDevice);
|
// If we are about to create this folder, we cannot update via restApi.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (mDevice == null) {
|
||||||
|
Log.e(TAG, "updateDevice: mDevice == null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save device specific preferences.
|
||||||
|
Log.v(TAG, "updateDevice: mDevice.deviceID = \'" + mDevice.deviceID + "\'");
|
||||||
|
SharedPreferences.Editor editor = mPreferences.edit();
|
||||||
|
editor.putBoolean(
|
||||||
|
Constants.DYN_PREF_OBJECT_CUSTOM_SYNC_CONDITIONS(Constants.PREF_OBJECT_PREFIX_DEVICE + mDevice.deviceID),
|
||||||
|
mCustomSyncConditionsSwitch.isChecked()
|
||||||
|
);
|
||||||
|
editor.apply();
|
||||||
|
|
||||||
|
// Update device via restApi and send the config to REST endpoint.
|
||||||
|
RestApi restApi = getApi();
|
||||||
|
if (restApi == null) {
|
||||||
|
Log.e(TAG, "updateDevice: restApi == null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
restApi.updateDevice(mDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> persistableAddresses(CharSequence userInput) {
|
private List<String> persistableAddresses(CharSequence userInput) {
|
||||||
|
|
|
@ -263,7 +263,6 @@ public class FolderActivity extends SyncthingActivity
|
||||||
/**
|
/**
|
||||||
* Invoked after user clicked on the {@link mCustomSyncConditionsDialog} label.
|
* Invoked after user clicked on the {@link mCustomSyncConditionsDialog} label.
|
||||||
*/
|
*/
|
||||||
@SuppressLint("InlinedAPI")
|
|
||||||
private void onCustomSyncConditionsDialogClick() {
|
private void onCustomSyncConditionsDialogClick() {
|
||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
SyncConditionsActivity.createIntent(
|
SyncConditionsActivity.createIntent(
|
||||||
|
@ -367,7 +366,7 @@ public class FolderActivity extends SyncthingActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save current settings in case we are in create mode and they aren't yet stored in the config.
|
* Register for service state change events.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected() {
|
public void onServiceConnected() {
|
||||||
|
@ -701,11 +700,19 @@ public class FolderActivity extends SyncthingActivity
|
||||||
deviceView.setOnCheckedChangeListener(mCheckedListener);
|
deviceView.setOnCheckedChangeListener(mCheckedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the updated folder info if in edit mode.
|
||||||
|
* Preconditions: mFolderNeedsToUpdate == true
|
||||||
|
*/
|
||||||
private void updateFolder() {
|
private void updateFolder() {
|
||||||
if (mIsCreateMode) {
|
if (mIsCreateMode) {
|
||||||
// If we are about to create this folder, we cannot update via restApi.
|
// If we are about to create this folder, we cannot update via restApi.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mFolder == null) {
|
||||||
|
Log.e(TAG, "updateFolder: mFolder == null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Save folder specific preferences.
|
// Save folder specific preferences.
|
||||||
Log.v(TAG, "updateFolder: mFolder.id = \'" + mFolder.id + "\'");
|
Log.v(TAG, "updateFolder: mFolder.id = \'" + mFolder.id + "\'");
|
||||||
|
@ -716,18 +723,13 @@ public class FolderActivity extends SyncthingActivity
|
||||||
);
|
);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
|
|
||||||
// Update folder via restApi.
|
// Update folder via restApi and send the config to REST endpoint.
|
||||||
RestApi restApi = getApi();
|
RestApi restApi = getApi();
|
||||||
/**
|
|
||||||
* RestApi is guaranteed not to be null as {@link onServiceStateChange}
|
|
||||||
* immediately finishes this activity if SyncthingService shuts down.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
if (restApi == null) {
|
if (restApi == null) {
|
||||||
Log.e(TAG, "updateFolder: restApi == null");
|
Log.e(TAG, "updateFolder: restApi == null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// Update ignore list.
|
// Update ignore list.
|
||||||
String[] ignore = mEditIgnoreListContent.getText().toString().split("\n");
|
String[] ignore = mEditIgnoreListContent.getText().toString().split("\n");
|
||||||
restApi.postFolderIgnoreList(mFolder.id, ignore);
|
restApi.postFolderIgnoreList(mFolder.id, ignore);
|
||||||
|
|
|
@ -105,6 +105,7 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
private CheckBoxPreference mRunOnMobileData;
|
private CheckBoxPreference mRunOnMobileData;
|
||||||
private CheckBoxPreference mRunOnWifi;
|
private CheckBoxPreference mRunOnWifi;
|
||||||
private CheckBoxPreference mRunOnMeteredWifi;
|
private CheckBoxPreference mRunOnMeteredWifi;
|
||||||
|
private CheckBoxPreference mUseWifiWhitelist;
|
||||||
private WifiSsidPreference mWifiSsidWhitelist;
|
private WifiSsidPreference mWifiSsidWhitelist;
|
||||||
private CheckBoxPreference mRunInFlightMode;
|
private CheckBoxPreference mRunInFlightMode;
|
||||||
|
|
||||||
|
@ -173,6 +174,8 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
(CheckBoxPreference) findPreference(Constants.PREF_RUN_ON_WIFI);
|
(CheckBoxPreference) findPreference(Constants.PREF_RUN_ON_WIFI);
|
||||||
mRunOnMeteredWifi =
|
mRunOnMeteredWifi =
|
||||||
(CheckBoxPreference) findPreference(Constants.PREF_RUN_ON_METERED_WIFI);
|
(CheckBoxPreference) findPreference(Constants.PREF_RUN_ON_METERED_WIFI);
|
||||||
|
mUseWifiWhitelist =
|
||||||
|
(CheckBoxPreference) findPreference(Constants.PREF_USE_WIFI_SSID_WHITELIST);
|
||||||
mWifiSsidWhitelist =
|
mWifiSsidWhitelist =
|
||||||
(WifiSsidPreference) findPreference(Constants.PREF_WIFI_SSID_WHITELIST);
|
(WifiSsidPreference) findPreference(Constants.PREF_WIFI_SSID_WHITELIST);
|
||||||
mRunInFlightMode =
|
mRunInFlightMode =
|
||||||
|
@ -225,7 +228,8 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
Preference appVersion = screen.findPreference("app_version");
|
Preference appVersion = screen.findPreference("app_version");
|
||||||
|
|
||||||
mRunOnMeteredWifi.setEnabled(mRunOnWifi.isChecked());
|
mRunOnMeteredWifi.setEnabled(mRunOnWifi.isChecked());
|
||||||
mWifiSsidWhitelist.setEnabled(mRunOnWifi.isChecked());
|
mUseWifiWhitelist.setEnabled(mRunOnWifi.isChecked());
|
||||||
|
mWifiSsidWhitelist.setEnabled(mRunOnWifi.isChecked() && mUseWifiWhitelist.isChecked());
|
||||||
/* Experimental options */
|
/* Experimental options */
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
/* Wakelocks are only valid on Android 5 or lower. */
|
/* Wakelocks are only valid on Android 5 or lower. */
|
||||||
|
@ -262,7 +266,7 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
screen.findPreference(Constants.PREF_POWER_SOURCE).setSummary(mPowerSource.getEntry());
|
screen.findPreference(Constants.PREF_POWER_SOURCE).setSummary(mPowerSource.getEntry());
|
||||||
String wifiSsidSummary = TextUtils.join(", ", mPreferences.getStringSet(Constants.PREF_WIFI_SSID_WHITELIST, new HashSet<>()));
|
String wifiSsidSummary = TextUtils.join(", ", mPreferences.getStringSet(Constants.PREF_WIFI_SSID_WHITELIST, new HashSet<>()));
|
||||||
screen.findPreference(Constants.PREF_WIFI_SSID_WHITELIST).setSummary(TextUtils.isEmpty(wifiSsidSummary) ?
|
screen.findPreference(Constants.PREF_WIFI_SSID_WHITELIST).setSummary(TextUtils.isEmpty(wifiSsidSummary) ?
|
||||||
getString(R.string.run_on_all_wifi_networks) :
|
getString(R.string.wifi_ssid_whitelist_empty) :
|
||||||
getString(R.string.run_on_whitelisted_wifi_networks, wifiSsidSummary)
|
getString(R.string.run_on_whitelisted_wifi_networks, wifiSsidSummary)
|
||||||
);
|
);
|
||||||
handleSocksProxyPreferenceChange(screen.findPreference(Constants.PREF_SOCKS_PROXY_ADDRESS), mPreferences.getString(Constants.PREF_SOCKS_PROXY_ADDRESS, ""));
|
handleSocksProxyPreferenceChange(screen.findPreference(Constants.PREF_SOCKS_PROXY_ADDRESS), mPreferences.getString(Constants.PREF_SOCKS_PROXY_ADDRESS, ""));
|
||||||
|
@ -366,12 +370,16 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
break;
|
break;
|
||||||
case Constants.PREF_RUN_ON_WIFI:
|
case Constants.PREF_RUN_ON_WIFI:
|
||||||
mRunOnMeteredWifi.setEnabled((Boolean) o);
|
mRunOnMeteredWifi.setEnabled((Boolean) o);
|
||||||
|
mUseWifiWhitelist.setEnabled((Boolean) o);
|
||||||
|
mWifiSsidWhitelist.setEnabled((Boolean) o && mUseWifiWhitelist.isChecked());
|
||||||
|
break;
|
||||||
|
case Constants.PREF_USE_WIFI_SSID_WHITELIST:
|
||||||
mWifiSsidWhitelist.setEnabled((Boolean) o);
|
mWifiSsidWhitelist.setEnabled((Boolean) o);
|
||||||
break;
|
break;
|
||||||
case Constants.PREF_WIFI_SSID_WHITELIST:
|
case Constants.PREF_WIFI_SSID_WHITELIST:
|
||||||
String wifiSsidSummary = TextUtils.join(", ", (Set<String>) o);
|
String wifiSsidSummary = TextUtils.join(", ", (Set<String>) o);
|
||||||
preference.setSummary(TextUtils.isEmpty(wifiSsidSummary) ?
|
preference.setSummary(TextUtils.isEmpty(wifiSsidSummary) ?
|
||||||
getString(R.string.run_on_all_wifi_networks) :
|
getString(R.string.wifi_ssid_whitelist_empty) :
|
||||||
getString(R.string.run_on_whitelisted_wifi_networks, wifiSsidSummary)
|
getString(R.string.run_on_whitelisted_wifi_networks, wifiSsidSummary)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -386,7 +394,7 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
case "deviceName":
|
case "deviceName":
|
||||||
Device localDevice = mRestApi.getLocalDevice();
|
Device localDevice = mRestApi.getLocalDevice();
|
||||||
localDevice.name = (String) o;
|
localDevice.name = (String) o;
|
||||||
mRestApi.editDevice(localDevice);
|
mRestApi.updateDevice(localDevice);
|
||||||
break;
|
break;
|
||||||
case "listenAddresses":
|
case "listenAddresses":
|
||||||
mOptions.listenAddresses = Iterables.toArray(splitter.split((String) o), String.class);
|
mOptions.listenAddresses = Iterables.toArray(splitter.split((String) o), String.class);
|
||||||
|
|
|
@ -60,7 +60,8 @@ public class SyncConditionsActivity extends SyncthingActivity
|
||||||
private SwitchCompat mSyncOnMobileData;
|
private SwitchCompat mSyncOnMobileData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared preferences names for custom per-folder settings.
|
* Shared preferences names for custom object settings.
|
||||||
|
* Object can e.g. be a folder or device.
|
||||||
*/
|
*/
|
||||||
private String mObjectPrefixAndId;
|
private String mObjectPrefixAndId;
|
||||||
private String mPrefSyncOnWifi;
|
private String mPrefSyncOnWifi;
|
||||||
|
@ -108,7 +109,7 @@ public class SyncConditionsActivity extends SyncthingActivity
|
||||||
mObjectPrefixAndId = intent.getStringExtra(EXTRA_OBJECT_PREFIX_AND_ID);
|
mObjectPrefixAndId = intent.getStringExtra(EXTRA_OBJECT_PREFIX_AND_ID);
|
||||||
Log.v(TAG, "Prefix is \'" + mObjectPrefixAndId + "\' (" + mObjectReadableName + ")");
|
Log.v(TAG, "Prefix is \'" + mObjectPrefixAndId + "\' (" + mObjectReadableName + ")");
|
||||||
mPrefSyncOnWifi = Constants.DYN_PREF_OBJECT_SYNC_ON_WIFI(mObjectPrefixAndId);
|
mPrefSyncOnWifi = Constants.DYN_PREF_OBJECT_SYNC_ON_WIFI(mObjectPrefixAndId);
|
||||||
mPrefSyncOnWhitelistedWifi = Constants.DYN_PREF_OBJECT_SYNC_ON_WHITELISTED_WIFI(mObjectPrefixAndId);
|
mPrefSyncOnWhitelistedWifi = Constants.DYN_PREF_OBJECT_USE_WIFI_SSID_WHITELIST(mObjectPrefixAndId);
|
||||||
mPrefSelectedWhitelistSsid = Constants.DYN_PREF_OBJECT_SELECTED_WHITELIST_SSID(mObjectPrefixAndId);
|
mPrefSelectedWhitelistSsid = Constants.DYN_PREF_OBJECT_SELECTED_WHITELIST_SSID(mObjectPrefixAndId);
|
||||||
mPrefSyncOnMeteredWifi = Constants.DYN_PREF_OBJECT_SYNC_ON_METERED_WIFI(mObjectPrefixAndId);
|
mPrefSyncOnMeteredWifi = Constants.DYN_PREF_OBJECT_SYNC_ON_METERED_WIFI(mObjectPrefixAndId);
|
||||||
mPrefSyncOnMobileData = Constants.DYN_PREF_OBJECT_SYNC_ON_MOBILE_DATA(mObjectPrefixAndId);
|
mPrefSyncOnMobileData = Constants.DYN_PREF_OBJECT_SYNC_ON_MOBILE_DATA(mObjectPrefixAndId);
|
||||||
|
@ -117,14 +118,13 @@ public class SyncConditionsActivity extends SyncthingActivity
|
||||||
* Load global run conditions.
|
* Load global run conditions.
|
||||||
*/
|
*/
|
||||||
Boolean globalRunOnWifiEnabled = mPreferences.getBoolean(Constants.PREF_RUN_ON_WIFI, true);
|
Boolean globalRunOnWifiEnabled = mPreferences.getBoolean(Constants.PREF_RUN_ON_WIFI, true);
|
||||||
Boolean globalWhitelistEnabled = !mPreferences.getStringSet(Constants.PREF_WIFI_SSID_WHITELIST, new HashSet<>())
|
|
||||||
.isEmpty();
|
|
||||||
Set<String> globalWhitelistedSsid = mPreferences.getStringSet(Constants.PREF_WIFI_SSID_WHITELIST, new HashSet<>());
|
Set<String> globalWhitelistedSsid = mPreferences.getStringSet(Constants.PREF_WIFI_SSID_WHITELIST, new HashSet<>());
|
||||||
|
Boolean globalWhitelistEnabled = mPreferences.getBoolean(Constants.PREF_USE_WIFI_SSID_WHITELIST, false);
|
||||||
Boolean globalRunOnMeteredWifiEnabled = mPreferences.getBoolean(Constants.PREF_RUN_ON_METERED_WIFI, false);
|
Boolean globalRunOnMeteredWifiEnabled = mPreferences.getBoolean(Constants.PREF_RUN_ON_METERED_WIFI, false);
|
||||||
Boolean globalRunOnMobileDataEnabled = mPreferences.getBoolean(Constants.PREF_RUN_ON_MOBILE_DATA, false);
|
Boolean globalRunOnMobileDataEnabled = mPreferences.getBoolean(Constants.PREF_RUN_ON_MOBILE_DATA, false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load custom folder preferences. If unset, use global setting as default.
|
* Load custom object preferences. If unset, use global setting as default.
|
||||||
*/
|
*/
|
||||||
mSyncOnWifi.setChecked(globalRunOnWifiEnabled && mPreferences.getBoolean(mPrefSyncOnWifi, globalRunOnWifiEnabled));
|
mSyncOnWifi.setChecked(globalRunOnWifiEnabled && mPreferences.getBoolean(mPrefSyncOnWifi, globalRunOnWifiEnabled));
|
||||||
mSyncOnWifi.setEnabled(globalRunOnWifiEnabled);
|
mSyncOnWifi.setEnabled(globalRunOnWifiEnabled);
|
||||||
|
@ -143,7 +143,7 @@ public class SyncConditionsActivity extends SyncthingActivity
|
||||||
mSyncOnMobileData.setOnCheckedChangeListener(mCheckedListener);
|
mSyncOnMobileData.setOnCheckedChangeListener(mCheckedListener);
|
||||||
|
|
||||||
// Read selected WiFi Ssid whitelist items.
|
// Read selected WiFi Ssid whitelist items.
|
||||||
Set<String> selectedWhitelistedSsid = mPreferences.getStringSet(mPrefSelectedWhitelistSsid, new HashSet<>());
|
Set<String> selectedWhitelistedSsid = mPreferences.getStringSet(mPrefSelectedWhitelistSsid, globalWhitelistedSsid);
|
||||||
// Removes any network that is no longer part of the global WiFi Ssid whitelist.
|
// Removes any network that is no longer part of the global WiFi Ssid whitelist.
|
||||||
selectedWhitelistedSsid.retainAll(globalWhitelistedSsid);
|
selectedWhitelistedSsid.retainAll(globalWhitelistedSsid);
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ public class SyncConditionsActivity extends SyncthingActivity
|
||||||
setMarginEnd(params, contentInset);
|
setMarginEnd(params, contentInset);
|
||||||
TextView emptyView = new TextView(mWifiSsidContainer.getContext());
|
TextView emptyView = new TextView(mWifiSsidContainer.getContext());
|
||||||
emptyView.setGravity(CENTER_VERTICAL);
|
emptyView.setGravity(CENTER_VERTICAL);
|
||||||
emptyView.setText(R.string.wifi_ssid_whitelist_empty);
|
emptyView.setText(R.string.custom_wifi_ssid_whitelist_empty);
|
||||||
mWifiSsidContainer.addView(emptyView, params);
|
mWifiSsidContainer.addView(emptyView, params);
|
||||||
mWifiSsidContainer.setEnabled(false);
|
mWifiSsidContainer.setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -224,7 +224,7 @@ public class SyncConditionsActivity extends SyncthingActivity
|
||||||
if (mUnsavedChanges) {
|
if (mUnsavedChanges) {
|
||||||
Log.v(TAG, "onPause: mUnsavedChanges == true. Saving prefs ...");
|
Log.v(TAG, "onPause: mUnsavedChanges == true. Saving prefs ...");
|
||||||
/**
|
/**
|
||||||
* Save custom folder preferences.
|
* Save custom object preferences.
|
||||||
*/
|
*/
|
||||||
SharedPreferences.Editor editor = mPreferences.edit();
|
SharedPreferences.Editor editor = mPreferences.edit();
|
||||||
editor.putBoolean(mPrefSyncOnWifi, mSyncOnWifi.isChecked());
|
editor.putBoolean(mPrefSyncOnWifi, mSyncOnWifi.isChecked());
|
||||||
|
|
|
@ -15,6 +15,7 @@ public class Constants {
|
||||||
public static final String PREF_RUN_ON_MOBILE_DATA = "run_on_mobile_data";
|
public static final String PREF_RUN_ON_MOBILE_DATA = "run_on_mobile_data";
|
||||||
public static final String PREF_RUN_ON_WIFI = "run_on_wifi";
|
public static final String PREF_RUN_ON_WIFI = "run_on_wifi";
|
||||||
public static final String PREF_RUN_ON_METERED_WIFI = "run_on_metered_wifi";
|
public static final String PREF_RUN_ON_METERED_WIFI = "run_on_metered_wifi";
|
||||||
|
public static final String PREF_USE_WIFI_SSID_WHITELIST = "use_wifi_whitelist";
|
||||||
public static final String PREF_WIFI_SSID_WHITELIST = "wifi_ssid_whitelist";
|
public static final String PREF_WIFI_SSID_WHITELIST = "wifi_ssid_whitelist";
|
||||||
public static final String PREF_POWER_SOURCE = "power_source";
|
public static final String PREF_POWER_SOURCE = "power_source";
|
||||||
public static final String PREF_RESPECT_BATTERY_SAVING = "respect_battery_saving";
|
public static final String PREF_RESPECT_BATTERY_SAVING = "respect_battery_saving";
|
||||||
|
@ -43,8 +44,8 @@ public class Constants {
|
||||||
return objectPrefixAndId + "_" + PREF_RUN_ON_WIFI;
|
return objectPrefixAndId + "_" + PREF_RUN_ON_WIFI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String DYN_PREF_OBJECT_SYNC_ON_WHITELISTED_WIFI(String objectPrefixAndId) {
|
public static String DYN_PREF_OBJECT_USE_WIFI_SSID_WHITELIST(String objectPrefixAndId) {
|
||||||
return objectPrefixAndId + "_" + "use_wifi_whitelist";
|
return objectPrefixAndId + "_" + PREF_USE_WIFI_SSID_WHITELIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String DYN_PREF_OBJECT_SELECTED_WHITELIST_SSID(String objectPrefixAndId) {
|
public static String DYN_PREF_OBJECT_SELECTED_WHITELIST_SSID(String objectPrefixAndId) {
|
||||||
|
|
|
@ -518,7 +518,7 @@ public class RestApi {
|
||||||
}, errorListener);
|
}, errorListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void editDevice(Device newDevice) {
|
public void updateDevice(Device newDevice) {
|
||||||
synchronized (mConfigLock) {
|
synchronized (mConfigLock) {
|
||||||
removeDeviceInternal(newDevice.deviceID);
|
removeDeviceInternal(newDevice.deviceID);
|
||||||
mConfig.devices.add(newDevice);
|
mConfig.devices.add(newDevice);
|
||||||
|
@ -782,11 +782,16 @@ public class RestApi {
|
||||||
Log.v(TAG, "onSyncPreconditionChanged: Event fired.");
|
Log.v(TAG, "onSyncPreconditionChanged: Event fired.");
|
||||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
|
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||||
synchronized (mConfigLock) {
|
synchronized (mConfigLock) {
|
||||||
if (mConfig == null || mConfig.folders == null) {
|
Boolean configChanged = false;
|
||||||
Log.d(TAG, "onSyncPreconditionChanged: mConfig.folders is not ready yet.");
|
|
||||||
|
// Check if the config has been loaded.
|
||||||
|
if (mConfig == null) {
|
||||||
|
Log.d(TAG, "onSyncPreconditionChanged: mConfig is not ready yet.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Boolean configChanged = false;
|
|
||||||
|
// Check if the folders are available from config.
|
||||||
|
if (mConfig.folders != null) {
|
||||||
for (Folder folder : mConfig.folders) {
|
for (Folder folder : mConfig.folders) {
|
||||||
Boolean folderCustomSyncConditionsEnabled = sharedPreferences.getBoolean(
|
Boolean folderCustomSyncConditionsEnabled = sharedPreferences.getBoolean(
|
||||||
Constants.DYN_PREF_OBJECT_CUSTOM_SYNC_CONDITIONS(Constants.PREF_OBJECT_PREFIX_FOLDER + folder.id), false
|
Constants.DYN_PREF_OBJECT_CUSTOM_SYNC_CONDITIONS(Constants.PREF_OBJECT_PREFIX_FOLDER + folder.id), false
|
||||||
|
@ -802,6 +807,33 @@ public class RestApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "onSyncPreconditionChanged: mConfig.folders is not ready yet.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the devices are available from config.
|
||||||
|
if (mConfig.devices != null) {
|
||||||
|
for (Device device : mConfig.devices) {
|
||||||
|
Boolean deviceCustomSyncConditionsEnabled = sharedPreferences.getBoolean(
|
||||||
|
Constants.DYN_PREF_OBJECT_CUSTOM_SYNC_CONDITIONS(Constants.PREF_OBJECT_PREFIX_DEVICE + device.deviceID), false
|
||||||
|
);
|
||||||
|
if (deviceCustomSyncConditionsEnabled) {
|
||||||
|
Boolean syncConditionsMet = runConditionMonitor.checkObjectSyncConditions(
|
||||||
|
Constants.PREF_OBJECT_PREFIX_DEVICE + device.deviceID
|
||||||
|
);
|
||||||
|
Log.v(TAG, "onSyncPreconditionChanged: syncDevice(" + device.deviceID + ")=" + (syncConditionsMet ? "1" : "0"));
|
||||||
|
if (device.paused != !syncConditionsMet) {
|
||||||
|
device.paused = !syncConditionsMet;
|
||||||
|
configChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "onSyncPreconditionChanged: mConfig.devices is not ready yet.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (configChanged) {
|
if (configChanged) {
|
||||||
Log.v(TAG, "onSyncPreconditionChanged: Sending changed config ...");
|
Log.v(TAG, "onSyncPreconditionChanged: Sending changed config ...");
|
||||||
sendConfig();
|
sendConfig();
|
||||||
|
|
|
@ -228,11 +228,13 @@ public class RunConditionMonitor {
|
||||||
/**
|
/**
|
||||||
* Constants.PREF_WIFI_SSID_WHITELIST
|
* Constants.PREF_WIFI_SSID_WHITELIST
|
||||||
*/
|
*/
|
||||||
private SyncConditionResult checkConditionSyncOnWhitelistedWifi(String prefNameSyncOnWhitelistedWifi) {
|
private SyncConditionResult checkConditionSyncOnWhitelistedWifi(
|
||||||
Set<String> whitelistedWifiSsids = mPreferences.getStringSet(prefNameSyncOnWhitelistedWifi, new HashSet<>());
|
String prefNameUseWifiWhitelist,
|
||||||
boolean prefWifiWhitelistEnabled = !whitelistedWifiSsids.isEmpty();
|
String prefNameSelectedWhitelistSsid) {
|
||||||
|
boolean wifiWhitelistEnabled = mPreferences.getBoolean(prefNameUseWifiWhitelist, false);
|
||||||
|
Set<String> whitelistedWifiSsids = mPreferences.getStringSet(prefNameSelectedWhitelistSsid, new HashSet<>());
|
||||||
try {
|
try {
|
||||||
if (wifiWhitelistConditionMet(prefWifiWhitelistEnabled, whitelistedWifiSsids)) {
|
if (wifiWhitelistConditionMet(wifiWhitelistEnabled, whitelistedWifiSsids)) {
|
||||||
return new SyncConditionResult(true, "\n" + res.getString(R.string.reason_on_whitelisted_wifi));
|
return new SyncConditionResult(true, "\n" + res.getString(R.string.reason_on_whitelisted_wifi));
|
||||||
}
|
}
|
||||||
return new SyncConditionResult(false, "\n" + res.getString(R.string.reason_not_on_whitelisted_wifi));
|
return new SyncConditionResult(false, "\n" + res.getString(R.string.reason_not_on_whitelisted_wifi));
|
||||||
|
@ -348,7 +350,7 @@ public class RunConditionMonitor {
|
||||||
// Wifi type is allowed.
|
// Wifi type is allowed.
|
||||||
Log.v(TAG, "decideShouldRun: checkConditionSyncOnWifi && checkConditionSyncOnMeteredWifi");
|
Log.v(TAG, "decideShouldRun: checkConditionSyncOnWifi && checkConditionSyncOnMeteredWifi");
|
||||||
|
|
||||||
scr = checkConditionSyncOnWhitelistedWifi(Constants.PREF_WIFI_SSID_WHITELIST);
|
scr = checkConditionSyncOnWhitelistedWifi(Constants.PREF_USE_WIFI_SSID_WHITELIST, Constants.PREF_WIFI_SSID_WHITELIST);
|
||||||
mRunDecisionExplanation += scr.explanation;
|
mRunDecisionExplanation += scr.explanation;
|
||||||
if (scr.conditionMet) {
|
if (scr.conditionMet) {
|
||||||
// Wifi is whitelisted.
|
// Wifi is whitelisted.
|
||||||
|
@ -395,7 +397,10 @@ public class RunConditionMonitor {
|
||||||
// Wifi type is allowed.
|
// Wifi type is allowed.
|
||||||
Log.v(TAG, "checkObjectSyncConditions: checkConditionSyncOnWifi && checkConditionSyncOnMeteredWifi");
|
Log.v(TAG, "checkObjectSyncConditions: checkConditionSyncOnWifi && checkConditionSyncOnMeteredWifi");
|
||||||
|
|
||||||
scr = checkConditionSyncOnWhitelistedWifi(Constants.DYN_PREF_OBJECT_SELECTED_WHITELIST_SSID(objectPrefixAndId));
|
scr = checkConditionSyncOnWhitelistedWifi(
|
||||||
|
Constants.DYN_PREF_OBJECT_USE_WIFI_SSID_WHITELIST(objectPrefixAndId),
|
||||||
|
Constants.DYN_PREF_OBJECT_SELECTED_WHITELIST_SSID(objectPrefixAndId)
|
||||||
|
);
|
||||||
if (scr.conditionMet) {
|
if (scr.conditionMet) {
|
||||||
// Wifi is whitelisted.
|
// Wifi is whitelisted.
|
||||||
Log.v(TAG, "checkObjectSyncConditions: checkConditionSyncOnWifi && checkConditionSyncOnMeteredWifi && checkConditionSyncOnWhitelistedWifi");
|
Log.v(TAG, "checkObjectSyncConditions: checkConditionSyncOnWifi && checkConditionSyncOnMeteredWifi && checkConditionSyncOnWhitelistedWifi");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Enhancements
|
Enhancements
|
||||||
* Specify sync conditions differently for each folder [NEW]
|
* Specify sync conditions differently for each folder, device [NEW]
|
||||||
* UI explains why syncthing is running (or not)
|
* UI explains why syncthing is running (or not)
|
||||||
* Support in-app editing of folder's ignore list items
|
* Support in-app editing of folder's ignore list items
|
||||||
Fixes
|
Fixes
|
||||||
|
|
|
@ -122,6 +122,59 @@
|
||||||
android:drawableStart="@drawable/ic_pause_circle_outline_black_24dp"
|
android:drawableStart="@drawable/ic_pause_circle_outline_black_24dp"
|
||||||
android:text="@string/pause_device" />
|
android:text="@string/pause_device" />
|
||||||
|
|
||||||
|
<!-- Custom sync conditions -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/customSyncConditionsContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<android.support.v7.widget.SwitchCompat
|
||||||
|
android:id="@+id/customSyncConditionsSwitch"
|
||||||
|
style="@style/Widget.Syncthing.TextView.Label.Details"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableLeft="@drawable/ic_autorenew_black_24dp"
|
||||||
|
android:drawableStart="@drawable/ic_autorenew_black_24dp"
|
||||||
|
android:text="@string/custom_sync_conditions_title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/customSyncConditionsDescription"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="75dp"
|
||||||
|
android:layout_marginStart="75dp"
|
||||||
|
android:layout_marginTop="-20dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
android:text="@string/custom_sync_conditions_description"
|
||||||
|
android:focusable="false"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/customSyncConditionsDialog"
|
||||||
|
style="@style/Widget.Syncthing.TextView.Label.Details"
|
||||||
|
android:layout_marginLeft="56dp"
|
||||||
|
android:layout_marginStart="56dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:text="@string/custom_sync_conditions_dialog"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/customSyncConditionsCurrent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="75dp"
|
||||||
|
android:layout_marginStart="75dp"
|
||||||
|
android:layout_marginTop="-20dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
android:text="@null"
|
||||||
|
android:focusable="false"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/currentAddress"
|
android:id="@+id/currentAddress"
|
||||||
style="@style/Widget.Syncthing.TextView.Label.Details"
|
style="@style/Widget.Syncthing.TextView.Label.Details"
|
||||||
|
|
|
@ -316,8 +316,10 @@ Please report any problems you encounter via Github.</string>
|
||||||
<string name="run_on_metered_wifi_summary">Run when device is connected to a metered Wi-Fi network e.g. a hotspot or tethered network. Attention: This can consume large portion of your data plan if you sync a lot of data.</string>
|
<string name="run_on_metered_wifi_summary">Run when device is connected to a metered Wi-Fi network e.g. a hotspot or tethered network. Attention: This can consume large portion of your data plan if you sync a lot of data.</string>
|
||||||
|
|
||||||
<string name="run_on_whitelisted_wifi_title">Run on specified Wi-Fi networks</string>
|
<string name="run_on_whitelisted_wifi_title">Run on specified Wi-Fi networks</string>
|
||||||
<string name="run_on_whitelisted_wifi_networks">Run only on selected Wi-Fi networks: %1$s</string>
|
<string name="specify_wifi_ssid_whitelist">Select Wi-Fi networks</string>
|
||||||
|
<string name="run_on_whitelisted_wifi_networks">Selected Wi-Fi networks: %1$s</string>
|
||||||
<string name="run_on_all_wifi_networks">Run on all Wi-Fi networks.</string>
|
<string name="run_on_all_wifi_networks">Run on all Wi-Fi networks.</string>
|
||||||
|
<string name="wifi_ssid_whitelist_empty">No Wi-Fi networks specified. Click to specify networks.</string>
|
||||||
|
|
||||||
<string name="sync_only_wifi_ssids_wifi_turn_on_wifi">Please turn on Wi-Fi to select networks.</string>
|
<string name="sync_only_wifi_ssids_wifi_turn_on_wifi">Please turn on Wi-Fi to select networks.</string>
|
||||||
|
|
||||||
|
@ -627,7 +629,7 @@ Please report any problems you encounter via Github.</string>
|
||||||
|
|
||||||
<!-- Sync Conditions Dialog -->
|
<!-- Sync Conditions Dialog -->
|
||||||
|
|
||||||
<string name="wifi_ssid_whitelist_empty">No WiFi SSID\'s whitelisted. Please specify some in the settings.</string>
|
<string name="custom_wifi_ssid_whitelist_empty">No WiFi SSID\'s whitelisted. Please specify some in the settings.</string>
|
||||||
|
|
||||||
<!-- SyncthingService -->
|
<!-- SyncthingService -->
|
||||||
|
|
||||||
|
|
|
@ -12,23 +12,34 @@
|
||||||
android:title="@string/run_conditions_title"
|
android:title="@string/run_conditions_title"
|
||||||
android:summary="@string/run_conditions_summary"/>
|
android:summary="@string/run_conditions_summary"/>
|
||||||
|
|
||||||
|
<!-- Sync on WiFi -->
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="run_on_wifi"
|
android:key="run_on_wifi"
|
||||||
android:title="@string/run_on_wifi_title"
|
android:title="@string/run_on_wifi_title"
|
||||||
android:summary="@string/run_on_wifi_summary"
|
android:summary="@string/run_on_wifi_summary"
|
||||||
android:defaultValue="true" />
|
android:defaultValue="true" />
|
||||||
|
|
||||||
|
<!-- Sync on metered WiFi -->
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="run_on_metered_wifi"
|
android:key="run_on_metered_wifi"
|
||||||
android:title="@string/run_on_metered_wifi_title"
|
android:title="@string/run_on_metered_wifi_title"
|
||||||
android:summary="@string/run_on_metered_wifi_summary"
|
android:summary="@string/run_on_metered_wifi_summary"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
|
|
||||||
|
<!-- Use WiFi Ssid whitelist -->
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="use_wifi_whitelist"
|
||||||
|
android:title="@string/run_on_whitelisted_wifi_title"
|
||||||
|
android:summary="@string/run_on_whitelisted_wifi_summary"
|
||||||
|
android:defaultValue="false" />
|
||||||
|
|
||||||
|
<!-- Select whitelisted WiFi Ssid -->
|
||||||
<com.nutomic.syncthingandroid.views.WifiSsidPreference
|
<com.nutomic.syncthingandroid.views.WifiSsidPreference
|
||||||
android:key="wifi_ssid_whitelist"
|
android:key="wifi_ssid_whitelist"
|
||||||
android:title="@string/run_on_whitelisted_wifi_title"
|
android:title="@string/specify_wifi_ssid_whitelist"
|
||||||
android:summary="@null" />
|
android:summary="@null" />
|
||||||
|
|
||||||
|
<!-- Sync on mobile data -->
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="run_on_mobile_data"
|
android:key="run_on_mobile_data"
|
||||||
android:title="@string/run_on_mobile_data_title"
|
android:title="@string/run_on_mobile_data_title"
|
||||||
|
|
Loading…
Reference in a new issue