mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-23 11:21:29 +00:00
Added functionality to manually stop sync (fixes #131).
This functionality can not be used together with wifi/charging settings. By default, this is set so that syncthing is only active when requested, and can be stopped by the user.
This commit is contained in:
parent
e76f354ddd
commit
f383393ce4
16 changed files with 224 additions and 35 deletions
|
@ -1,6 +1,7 @@
|
|||
package com.nutomic.syncthingandroid.test.syncthing;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
|
@ -18,11 +19,21 @@ public class BatteryReceiverTest extends AndroidTestCase {
|
|||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mReceiver = new BatteryReceiver();
|
||||
mContext = new MockContext(null);
|
||||
mContext = new MockContext(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
PreferenceManager.getDefaultSharedPreferences(mContext).edit().clear().commit();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOnReceiveCharging() {
|
||||
PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, true)
|
||||
.commit();
|
||||
Intent intent = new Intent(Intent.ACTION_POWER_CONNECTED);
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
@ -35,6 +46,10 @@ public class BatteryReceiverTest extends AndroidTestCase {
|
|||
|
||||
@MediumTest
|
||||
public void testOnReceiveNotCharging() {
|
||||
PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, true)
|
||||
.commit();
|
||||
Intent intent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
@ -46,4 +61,16 @@ public class BatteryReceiverTest extends AndroidTestCase {
|
|||
mContext.clearReceivedIntents();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOnlyRunInForeground() {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, false)
|
||||
.commit();
|
||||
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_POWER_CONNECTED));
|
||||
assertEquals(0, mContext.getReceivedIntents().size());
|
||||
mReceiver.onReceive(mContext, new Intent(Intent.ACTION_POWER_DISCONNECTED));
|
||||
assertEquals(0, mContext.getReceivedIntents().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.nutomic.syncthingandroid.test.syncthing;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
|
@ -21,11 +22,21 @@ public class BootReceiverTest extends AndroidTestCase {
|
|||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mReceiver = new BootReceiver();
|
||||
mContext = new MockContext(null);
|
||||
mContext = new MockContext(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
PreferenceManager.getDefaultSharedPreferences(mContext).edit().clear().commit();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOnReceiveCharging() {
|
||||
PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, true)
|
||||
.commit();
|
||||
mReceiver.onReceive(mContext, null);
|
||||
assertEquals(1, mContext.getReceivedIntents().size());
|
||||
|
||||
|
@ -33,4 +44,14 @@ public class BootReceiverTest extends AndroidTestCase {
|
|||
assertEquals(SyncthingService.class.getName(), receivedIntent.getComponent().getClassName());
|
||||
mContext.clearReceivedIntents();
|
||||
}
|
||||
|
||||
public void testOnlyRunInForeground() {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, false)
|
||||
.commit();
|
||||
mReceiver.onReceive(mContext, null);
|
||||
assertEquals(0, mContext.getReceivedIntents().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.nutomic.syncthingandroid.test.syncthing;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
|
@ -28,8 +29,18 @@ public class NetworkReceiverTest extends AndroidTestCase {
|
|||
mContext = new MockContext(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
PreferenceManager.getDefaultSharedPreferences(mContext).edit().clear().commit();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOnReceive() {
|
||||
PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, true)
|
||||
.commit();
|
||||
mReceiver.onReceive(mContext, null);
|
||||
assertEquals(1, mContext.getReceivedIntents().size());
|
||||
|
||||
|
@ -40,4 +51,14 @@ public class NetworkReceiverTest extends AndroidTestCase {
|
|||
mContext.clearReceivedIntents();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOnlyRunInForeground() {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, false)
|
||||
.commit();
|
||||
mReceiver.onReceive(mContext, null);
|
||||
assertEquals(0, mContext.getReceivedIntents().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@ import com.nutomic.syncthingandroid.test.MockContext;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* NOTE: This test will cause a "syncthing binary crashed" notification, because
|
||||
* {@code -home " + mContext.getFilesDir()} is run as a "command" and fails.
|
||||
*/
|
||||
public class SyncthingRunnableTest extends AndroidTestCase {
|
||||
|
||||
@SmallTest
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.test.ServiceTestCase;
|
|||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.nutomic.syncthingandroid.syncthing.DeviceStateHolder;
|
||||
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
||||
|
@ -16,19 +17,27 @@ import com.nutomic.syncthingandroid.test.Util;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* FIXME: There are some problems with shutting down the service after tests. It may be that the
|
||||
* service remains running after short tests. As a workaround, kill the app in Android.
|
||||
* NOTE: It seems that @link #tearDown()} is not executed if a test fails, so the test data folder
|
||||
* is not deleted (which may cause following tests to fail).
|
||||
* These tests assume that syncthing keys have already been generated. If not, tests may fail
|
||||
* because startup takes too long.
|
||||
*
|
||||
* FIXME: These tests are rather fragile and may fail even if they shouldn't. Repeating them
|
||||
* should fix this.
|
||||
* NOTE: If a test fails with "expected:<ACTIVE> but was:<INIT>", you may have to increase
|
||||
* {@link #STARTUP_TIME_SECONDS}.
|
||||
*/
|
||||
public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
||||
|
||||
private static final int STARTUP_TIME_SECONDS = 90;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private CountDownLatch mLatch;
|
||||
|
||||
public SyncthingServiceTest() {
|
||||
super(SyncthingService.class);
|
||||
}
|
||||
|
@ -37,19 +46,18 @@ public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
|||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mContext = new MockContext(getContext());
|
||||
setContext(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
Util.deleteRecursive(getContext().getFilesDir());
|
||||
Util.deleteRecursive(mContext.getFilesDir());
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().clear().commit();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
public void testStartService() throws InterruptedException {
|
||||
startService(new Intent(mContext, SyncthingService.class));
|
||||
startService(new Intent(getContext(), SyncthingService.class));
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
getService().registerOnWebGuiAvailableListener(new SyncthingService.OnWebGuiAvailableListener() {
|
||||
@Override
|
||||
|
@ -70,12 +78,14 @@ public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
|||
|
||||
@SmallTest
|
||||
public void testFirstStart() {
|
||||
setContext(mContext);
|
||||
startService(new Intent(mContext, SyncthingService.class));
|
||||
assertTrue(getService().isFirstStart());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNotFirstStart() throws IOException {
|
||||
setContext(mContext);
|
||||
startService(new Intent(mContext, SyncthingService.class));
|
||||
new File(mContext.getFilesDir(), SyncthingService.PUBLIC_KEY_FILE).createNewFile();
|
||||
assertFalse(getService().isFirstStart());
|
||||
|
@ -84,7 +94,7 @@ public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
|||
@SmallTest
|
||||
public void testBindService() throws InterruptedException {
|
||||
SyncthingServiceBinder binder = (SyncthingServiceBinder)
|
||||
bindService(new Intent(mContext, SyncthingService.class));
|
||||
bindService(new Intent(getContext(), SyncthingService.class));
|
||||
SyncthingService service = binder.getService();
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
getService().registerOnWebGuiAvailableListener(new SyncthingService.OnWebGuiAvailableListener() {
|
||||
|
@ -109,6 +119,8 @@ public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
|||
|
||||
@Override
|
||||
public void onApiChange(SyncthingService.State currentState) {
|
||||
mLatch.countDown();
|
||||
|
||||
mLastState = currentState;
|
||||
}
|
||||
|
||||
|
@ -122,9 +134,10 @@ public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
|||
|
||||
@MediumTest
|
||||
public void testStatesAllRequired() throws InterruptedException {
|
||||
setupStatesTest(true, true);
|
||||
setupStatesTest(true, true, true);
|
||||
|
||||
assertState(true, true, SyncthingService.State.ACTIVE);
|
||||
|
||||
assertState(true, false, SyncthingService.State.DISABLED);
|
||||
assertState(false, true, SyncthingService.State.DISABLED);
|
||||
assertState(false, false, SyncthingService.State.DISABLED);
|
||||
|
@ -132,27 +145,29 @@ public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
|||
|
||||
@MediumTest
|
||||
public void testStatesWifiRequired() throws InterruptedException {
|
||||
setupStatesTest(true, false);
|
||||
setupStatesTest(true, true, false);
|
||||
|
||||
assertState(true, true, SyncthingService.State.ACTIVE);
|
||||
assertState(true, false, SyncthingService.State.DISABLED);
|
||||
assertState(false, true, SyncthingService.State.ACTIVE);
|
||||
|
||||
assertState(true, false, SyncthingService.State.DISABLED);
|
||||
assertState(false, false, SyncthingService.State.DISABLED);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testStatesChargingRequired() throws InterruptedException {
|
||||
setupStatesTest(false, true);
|
||||
setupStatesTest(true, false, true);
|
||||
|
||||
assertState(true, true, SyncthingService.State.ACTIVE);
|
||||
assertState(true, false, SyncthingService.State.ACTIVE);
|
||||
|
||||
assertState(false, true, SyncthingService.State.DISABLED);
|
||||
assertState(false, false, SyncthingService.State.DISABLED);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testStatesNoneRequired() throws InterruptedException {
|
||||
setupStatesTest(false, false);
|
||||
setupStatesTest(true, false, false);
|
||||
|
||||
assertState(true, true, SyncthingService.State.ACTIVE);
|
||||
assertState(true, false, SyncthingService.State.ACTIVE);
|
||||
|
@ -162,25 +177,55 @@ public class SyncthingServiceTest extends ServiceTestCase<SyncthingService> {
|
|||
|
||||
public void assertState(boolean charging, boolean wifi, SyncthingService.State expected)
|
||||
throws InterruptedException {
|
||||
Intent i = new Intent(mContext, SyncthingService.class);
|
||||
Intent i = new Intent(getContext(), SyncthingService.class);
|
||||
i.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, charging);
|
||||
i.putExtra(DeviceStateHolder.EXTRA_HAS_WIFI, wifi);
|
||||
mLatch = new CountDownLatch(1);
|
||||
startService(i);
|
||||
// Wait for service to react to preference change.
|
||||
Thread.sleep(7500);
|
||||
mLatch.await(1, TimeUnit.SECONDS);
|
||||
assertEquals(expected, mListener.getLastState());
|
||||
}
|
||||
|
||||
public void setupStatesTest(boolean syncOnlyWifi, boolean syncOnlyCharging)
|
||||
throws InterruptedException {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit()
|
||||
public void setupStatesTest(boolean alwaysRunInBackground,
|
||||
boolean syncOnlyWifi, boolean syncOnlyCharging) throws InterruptedException {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.edit()
|
||||
.putBoolean(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND, alwaysRunInBackground)
|
||||
.putBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, syncOnlyWifi)
|
||||
.putBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, syncOnlyCharging)
|
||||
.commit();
|
||||
// Wait for service to react to preference change.
|
||||
Thread.sleep(1000);
|
||||
|
||||
startService(new Intent(getContext(), SyncthingService.class));
|
||||
// 3 calls plus 1 call immediately when registering.
|
||||
mLatch = new CountDownLatch(4);
|
||||
getService().registerOnApiChangeListener(mListener);
|
||||
assertEquals(SyncthingService.State.INIT, mListener.getLastState());
|
||||
if (mListener.getLastState() != SyncthingService.State.ACTIVE) {
|
||||
// Wait for service to start.
|
||||
mLatch.await(STARTUP_TIME_SECONDS, TimeUnit.SECONDS);
|
||||
assertEquals(SyncthingService.State.ACTIVE, mListener.getLastState());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For all possible settings and charging/wifi states, service should be active.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testOnlyForeground() throws InterruptedException {
|
||||
ArrayList<Pair<Boolean, Boolean>> values = new ArrayList<>();
|
||||
values.add(new Pair(true, true));
|
||||
values.add(new Pair(true, false));
|
||||
values.add(new Pair(false, true));
|
||||
values.add(new Pair(false, false));
|
||||
|
||||
for (Pair<Boolean, Boolean> v : values) {
|
||||
setupStatesTest(false, v.first, v.second);
|
||||
|
||||
assertState(true, true, SyncthingService.State.ACTIVE);
|
||||
assertState(true, false, SyncthingService.State.ACTIVE);
|
||||
assertState(false, true, SyncthingService.State.ACTIVE);
|
||||
assertState(false, false, SyncthingService.State.ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -247,6 +247,7 @@ public class MainActivity extends SyncthingActivity
|
|||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
boolean drawerOpen = mDrawerLayout.isDrawerOpen(findViewById(R.id.drawer));
|
||||
menu.findItem(R.id.share_node_id).setVisible(drawerOpen);
|
||||
menu.findItem(R.id.exit).setVisible(!SyncthingService.alwaysRunInBackground(this));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -277,6 +278,9 @@ public class MainActivity extends SyncthingActivity
|
|||
startActivity(new Intent(this, SettingsActivity.class)
|
||||
.setAction(SettingsActivity.ACTION_APP_SETTINGS_FRAGMENT));
|
||||
return true;
|
||||
case R.id.exit:
|
||||
stopService(new Intent(this, SyncthingService.class));
|
||||
finish();
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ public class SettingsFragment extends PreferenceFragment
|
|||
|
||||
private static final String SYNCTHING_VERSION_KEY = "syncthing_version";
|
||||
|
||||
private CheckBoxPreference mAlwaysRunInBackground;
|
||||
|
||||
private CheckBoxPreference mSyncOnlyCharging;
|
||||
|
||||
private CheckBoxPreference mSyncOnlyWifi;
|
||||
|
@ -96,18 +98,24 @@ public class SettingsFragment extends PreferenceFragment
|
|||
|
||||
addPreferencesFromResource(R.xml.app_settings);
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
mAlwaysRunInBackground = (CheckBoxPreference)
|
||||
findPreference(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND);
|
||||
mSyncOnlyCharging = (CheckBoxPreference)
|
||||
findPreference(SyncthingService.PREF_SYNC_ONLY_CHARGING);
|
||||
mSyncOnlyCharging.setOnPreferenceChangeListener(this);
|
||||
mSyncOnlyWifi = (CheckBoxPreference) findPreference(SyncthingService.PREF_SYNC_ONLY_WIFI);
|
||||
mVersion = screen.findPreference(SYNCTHING_VERSION_KEY);
|
||||
mOptionsScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_OPTIONS_KEY);
|
||||
mGuiScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_GUI_KEY);
|
||||
|
||||
mAlwaysRunInBackground.setOnPreferenceChangeListener(this);
|
||||
mSyncOnlyCharging.setOnPreferenceChangeListener(this);
|
||||
mSyncOnlyWifi.setOnPreferenceChangeListener(this);
|
||||
// Force summary update and wifi/charging preferences enable/disable.
|
||||
onPreferenceChange(mAlwaysRunInBackground, mAlwaysRunInBackground.isChecked());
|
||||
Preference sttrace = findPreference("sttrace");
|
||||
sttrace.setOnPreferenceChangeListener(this);
|
||||
sttrace.setSummary(PreferenceManager
|
||||
.getDefaultSharedPreferences(getActivity()).getString("sttrace", ""));
|
||||
mVersion = screen.findPreference(SYNCTHING_VERSION_KEY);
|
||||
mOptionsScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_OPTIONS_KEY);
|
||||
mGuiScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_GUI_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,6 +154,13 @@ public class SettingsFragment extends PreferenceFragment
|
|||
|
||||
if (preference.equals(mSyncOnlyCharging) || preference.equals(mSyncOnlyWifi)) {
|
||||
mSyncthingService.updateState();
|
||||
} else if (preference.equals(mAlwaysRunInBackground)) {
|
||||
preference.setSummary(((Boolean) o)
|
||||
? R.string.always_run_in_background_enabled
|
||||
: R.string.always_run_in_background_disabled);
|
||||
mSyncOnlyCharging.setEnabled((Boolean) o);
|
||||
mSyncOnlyWifi.setEnabled((Boolean) o);
|
||||
|
||||
} else if (mOptionsScreen.findPreference(preference.getKey()) != null) {
|
||||
mSyncthingService.getApi().setValue(RestApi.TYPE_OPTIONS, preference.getKey(), o,
|
||||
preference.getKey().equals("ListenAddress"), getActivity());
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.nutomic.syncthingandroid.syncthing;
|
|||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
|
@ -14,6 +16,9 @@ public class BatteryReceiver extends BroadcastReceiver {
|
|||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!SyncthingService.alwaysRunInBackground(context))
|
||||
return;
|
||||
|
||||
boolean isCharging = Intent.ACTION_POWER_CONNECTED.equals(intent.getAction());
|
||||
Log.v(TAG, "Received charger " + (isCharging ? "connected" : "disconnected") + " event");
|
||||
Intent i = new Intent(context, SyncthingService.class);
|
||||
|
|
|
@ -3,11 +3,16 @@ package com.nutomic.syncthingandroid.syncthing;
|
|||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class BootReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!SyncthingService.alwaysRunInBackground(context))
|
||||
return;
|
||||
|
||||
context.startService(new Intent(context, SyncthingService.class));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@ public class NetworkReceiver extends BroadcastReceiver {
|
|||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!SyncthingService.alwaysRunInBackground(context))
|
||||
return;
|
||||
|
||||
ConnectivityManager cm =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo wifiInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
|
|
|
@ -849,7 +849,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
|||
normalized = json.optString("id", null);
|
||||
error = json.optString("error", null);
|
||||
} catch (JSONException e) {
|
||||
Log.d(TAG, "Failed to parse normalized node ID JSON", e);
|
||||
Log.w(TAG, "Failed to parse normalized node ID JSON", e);
|
||||
}
|
||||
listener.onNodeIdNormalized(normalized, error);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.nutomic.syncthingandroid.syncthing;
|
|||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
|
@ -57,6 +58,8 @@ public class SyncthingService extends Service {
|
|||
*/
|
||||
public static final String BINARY_NAME = "lib/libsyncthing.so";
|
||||
|
||||
public static final String PREF_ALWAYS_RUN_IN_BACKGROUND = "always_run_in_background";
|
||||
|
||||
public static final String PREF_SYNC_ONLY_WIFI = "sync_only_wifi";
|
||||
|
||||
public static final String PREF_SYNC_ONLY_CHARGING = "sync_only_charging";
|
||||
|
@ -141,13 +144,23 @@ public class SyncthingService extends Service {
|
|||
* called.
|
||||
*/
|
||||
public void updateState() {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
boolean prefStopMobileData = prefs.getBoolean(PREF_SYNC_ONLY_WIFI, false);
|
||||
boolean prefStopNotCharging = prefs.getBoolean(PREF_SYNC_ONLY_CHARGING, false);
|
||||
boolean shouldRun;
|
||||
if (!alwaysRunInBackground(this)) {
|
||||
// Always run, ignoring wifi/charging state.
|
||||
shouldRun = true;
|
||||
}
|
||||
else {
|
||||
// Check wifi/charging state against preferences and start if ok.
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
boolean prefStopMobileData = prefs.getBoolean(PREF_SYNC_ONLY_WIFI, false);
|
||||
boolean prefStopNotCharging = prefs.getBoolean(PREF_SYNC_ONLY_CHARGING, false);
|
||||
|
||||
shouldRun = (mDeviceStateHolder.isCharging() || !prefStopNotCharging) &&
|
||||
(mDeviceStateHolder.isWifiConnected() || !prefStopMobileData);
|
||||
}
|
||||
|
||||
// Start syncthing.
|
||||
if ((mDeviceStateHolder.isCharging() || !prefStopNotCharging) &&
|
||||
(mDeviceStateHolder.isWifiConnected() || !prefStopMobileData)) {
|
||||
if (shouldRun) {
|
||||
if (mCurrentState == State.ACTIVE || mCurrentState == State.STARTING) {
|
||||
mStopScheduled = false;
|
||||
return;
|
||||
|
@ -396,4 +409,12 @@ public class SyncthingService extends Service {
|
|||
return mConfig.getWebGuiUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of "always_run_in_background" preference.
|
||||
*/
|
||||
public static boolean alwaysRunInBackground(Context context) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return sp.getBoolean(PREF_ALWAYS_RUN_IN_BACKGROUND, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class RepoObserver extends FileObserver {
|
|||
}
|
||||
});
|
||||
|
||||
mChilds = new ArrayList<>(directories.length);
|
||||
mChilds = new ArrayList<>();
|
||||
for (File f : directories) {
|
||||
mChilds.add(new RepoObserver(mListener, mRepo, path + "/" + f.getName()));
|
||||
}
|
||||
|
|
|
@ -28,4 +28,8 @@
|
|||
android:id="@+id/settings"
|
||||
android:title="@string/settings_title" />
|
||||
|
||||
<item
|
||||
android:id="@+id/exit"
|
||||
android:title="@string/exit" />
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -199,6 +199,15 @@ Please report any problems you encounter via Github.</string>
|
|||
<!-- Activity title -->
|
||||
<string name="settings_title">Settings</string>
|
||||
|
||||
<!-- Preference title -->
|
||||
<string name="always_run_in_background">Always run in background</string>
|
||||
|
||||
<!-- Preference summary in case it is enabled -->
|
||||
<string name="always_run_in_background_enabled">Syncthing always runs in the background, according to preferences below.</string>
|
||||
|
||||
<!-- Preference summary in case it is disabled -->
|
||||
<string name="always_run_in_background_disabled">Syncthing only runs when explicitly started, and can be stopped by menu button.</string>
|
||||
|
||||
<string name="sync_only_charging">Sync only when charging</string>
|
||||
|
||||
<string name="sync_only_wifi">Sync only on wifi</string>
|
||||
|
@ -252,7 +261,7 @@ If this error persists, try restarting your device.</string>
|
|||
<!-- Button text on the "syncthing disabled" dialog -->
|
||||
<string name="syncthing_disabled_change_settings">Change Settings</string>
|
||||
|
||||
<!-- Button text on the "syncthing disabled" dialog -->
|
||||
<!-- Button text on the "syncthing disabled" dialog, used as menu item to stop syncthing service if "always_run_in_background" is true -->
|
||||
<string name="exit">Exit</string>
|
||||
|
||||
<!-- RestApi -->
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="always_run_in_background"
|
||||
android:title="@string/always_run_in_background"
|
||||
android:defaultValue="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="sync_only_charging"
|
||||
android:title="@string/sync_only_charging"
|
||||
|
|
Loading…
Reference in a new issue