mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-23 11:21:29 +00:00
Rework run conditions (fixes #540)
This commit is contained in:
parent
42a87031f1
commit
5c97251ffa
7 changed files with 67 additions and 78 deletions
|
@ -42,29 +42,13 @@ public class DeviceStateHolderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testWifiConnected() {
|
public void testWifiConnected() {
|
||||||
Intent i = new Intent();
|
Intent i = new Intent();
|
||||||
i.putExtra(DeviceStateHolder.EXTRA_HAS_WIFI, false);
|
i.putExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION, false);
|
||||||
mReceiver.update(i);
|
mReceiver.update(i);
|
||||||
Assert.assertFalse(mReceiver.isWifiConnected());
|
Assert.assertFalse(mReceiver.isAllowedNetworkConnection());
|
||||||
|
|
||||||
i.putExtra(DeviceStateHolder.EXTRA_HAS_WIFI, true);
|
i.putExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION, true);
|
||||||
mReceiver.update(i);
|
mReceiver.update(i);
|
||||||
Assert.assertTrue(mReceiver.isWifiConnected());
|
Assert.assertTrue(mReceiver.isAllowedNetworkConnection());
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testonReceiveInitialChargingState() {
|
|
||||||
Intent i = new Intent();
|
|
||||||
mReceiver.onReceive(mContext, i);
|
|
||||||
Assert.assertFalse(mReceiver.isCharging());
|
|
||||||
Assert.assertEquals(mContext.getLastUnregistered(), mReceiver);
|
|
||||||
|
|
||||||
i.putExtra(BatteryManager.EXTRA_PLUGGED, 0);
|
|
||||||
mReceiver.onReceive(mContext, i);
|
|
||||||
Assert.assertFalse(mReceiver.isCharging());
|
|
||||||
|
|
||||||
i.putExtra(BatteryManager.EXTRA_PLUGGED, 1);
|
|
||||||
mReceiver.onReceive(mContext, i);
|
|
||||||
Assert.assertTrue(mReceiver.isCharging());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class NetworkReceiverTest {
|
||||||
Intent receivedIntent = mContext.getReceivedIntents().get(0);
|
Intent receivedIntent = mContext.getReceivedIntents().get(0);
|
||||||
Assert.assertEquals(SyncthingService.class.getName(), receivedIntent.getComponent().getClassName());
|
Assert.assertEquals(SyncthingService.class.getName(), receivedIntent.getComponent().getClassName());
|
||||||
Assert.assertNull(receivedIntent.getAction());
|
Assert.assertNull(receivedIntent.getAction());
|
||||||
Assert.assertTrue(receivedIntent.hasExtra(DeviceStateHolder.EXTRA_HAS_WIFI));
|
Assert.assertTrue(receivedIntent.hasExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION));
|
||||||
mContext.clearReceivedIntents();
|
mContext.clearReceivedIntents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,9 +73,8 @@ public abstract class StateDialogActivity extends SyncthingActivity {
|
||||||
.setNegativeButton(R.string.exit,
|
.setNegativeButton(R.string.exit,
|
||||||
(dialogInterface, i) -> ActivityCompat.finishAffinity(this)
|
(dialogInterface, i) -> ActivityCompat.finishAffinity(this)
|
||||||
)
|
)
|
||||||
.setOnCancelListener(dialogInterface -> ActivityCompat.finishAffinity(this))
|
.setCancelable(false)
|
||||||
.show();
|
.show();
|
||||||
mDisabledDialog.setCanceledOnTouchOutside(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dismissDisabledDialog() {
|
private void dismissDisabledDialog() {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.nutomic.syncthingandroid.receiver;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.os.BatteryManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
|
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
|
||||||
|
@ -13,8 +15,6 @@ import com.nutomic.syncthingandroid.service.SyncthingService;
|
||||||
*/
|
*/
|
||||||
public class BatteryReceiver extends BroadcastReceiver {
|
public class BatteryReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
private static final String TAG = "BatteryReceiver";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (!Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())
|
if (!Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())
|
||||||
|
@ -25,10 +25,23 @@ public class BatteryReceiver extends BroadcastReceiver {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean isCharging = Intent.ACTION_POWER_CONNECTED.equals(intent.getAction());
|
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);
|
Intent i = new Intent(context, SyncthingService.class);
|
||||||
i.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging);
|
i.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging);
|
||||||
context.startService(i);
|
context.startService(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current charging status without waiting for connected/disconnected events.
|
||||||
|
*/
|
||||||
|
public static void updateInitialChargingStatus(Context context) {
|
||||||
|
Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||||
|
int status = batteryIntent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
|
||||||
|
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
|
||||||
|
status == BatteryManager.BATTERY_STATUS_FULL;
|
||||||
|
|
||||||
|
Intent intent = new Intent(context, SyncthingService.class);
|
||||||
|
intent.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging);
|
||||||
|
context.startService(intent);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.nutomic.syncthingandroid.receiver;
|
package com.nutomic.syncthingandroid.receiver;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
|
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
|
||||||
|
@ -25,14 +27,22 @@ public class NetworkReceiver extends BroadcastReceiver {
|
||||||
if (!SyncthingService.alwaysRunInBackground(context))
|
if (!SyncthingService.alwaysRunInBackground(context))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ConnectivityManager cm =
|
updateNetworkStatus(context);
|
||||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
}
|
||||||
|
|
||||||
|
@TargetApi(16)
|
||||||
|
public static void updateNetworkStatus(Context context) {
|
||||||
|
ConnectivityManager cm = (ConnectivityManager)
|
||||||
|
context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
NetworkInfo ni = cm.getActiveNetworkInfo();
|
NetworkInfo ni = cm.getActiveNetworkInfo();
|
||||||
boolean isWifiConnected = ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI && ni.isConnected();
|
boolean isOffline = ni == null;
|
||||||
Log.v(TAG, "Received wifi " + (isWifiConnected ? "connected" : "disconnected") + " event");
|
boolean isWifi = ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI && ni.isConnected();
|
||||||
Intent i = new Intent(context, SyncthingService.class);
|
boolean isNetworkMetered = (Build.VERSION.SDK_INT >= 16) ? cm.isActiveNetworkMetered() : false;
|
||||||
i.putExtra(DeviceStateHolder.EXTRA_HAS_WIFI, isWifiConnected);
|
boolean isAllowedConnection = isOffline || (isWifi && !isNetworkMetered);
|
||||||
context.startService(i);
|
|
||||||
|
Intent intent = new Intent(context, SyncthingService.class);
|
||||||
|
intent.putExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION, isAllowedConnection);
|
||||||
|
context.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
package com.nutomic.syncthingandroid.service;
|
package com.nutomic.syncthingandroid.service;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.BatteryManager;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.receiver.BatteryReceiver;
|
||||||
|
import com.nutomic.syncthingandroid.receiver.NetworkReceiver;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds information about the current wifi and charging state of the device.
|
* Holds information about the current wifi and charging state of the device.
|
||||||
* <p/>
|
*
|
||||||
* This information is actively read on construction, and then updated from intents that are passed
|
* This information is actively read on construction, and then updated from intents that are passed
|
||||||
* to {@link #update(android.content.Intent)}.
|
* to {@link #update(android.content.Intent)}.
|
||||||
*/
|
*/
|
||||||
public class DeviceStateHolder extends BroadcastReceiver {
|
public class DeviceStateHolder {
|
||||||
|
|
||||||
private static final String TAG = "DeviceStateHolder";
|
private static final String TAG = "DeviceStateHolder";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intent extra containing a boolean saying whether wifi is connected or not.
|
* Intent extra containing a boolean saying whether wifi is connected or not.
|
||||||
*/
|
*/
|
||||||
public static final String EXTRA_HAS_WIFI =
|
public static final String EXTRA_IS_ALLOWED_NETWORK_CONNECTION =
|
||||||
"com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.HAS_WIFI";
|
"com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_ALLOWED_NETWORK_CONNECTION";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intent extra containging a boolean saying whether the device is
|
* Intent extra containging a boolean saying whether the device is
|
||||||
|
@ -41,50 +41,36 @@ public class DeviceStateHolder extends BroadcastReceiver {
|
||||||
"com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_CHARGING";
|
"com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_CHARGING";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
private final SharedPreferences mPreferences;
|
||||||
|
|
||||||
private boolean mIsWifiConnected = false;
|
private boolean mIsAllowedNetworkConnection = false;
|
||||||
|
|
||||||
private String mWifiSsid;
|
private String mWifiSsid;
|
||||||
|
|
||||||
private boolean mIsCharging = false;
|
private boolean mIsCharging = false;
|
||||||
|
|
||||||
public DeviceStateHolder(Context context) {
|
public DeviceStateHolder(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
ConnectivityManager cm = (ConnectivityManager)
|
mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||||
context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
NetworkInfo ni = cm.getActiveNetworkInfo();
|
|
||||||
mIsWifiConnected = ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI && ni.isConnected();
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 16 && cm.isActiveNetworkMetered())
|
|
||||||
mIsWifiConnected = false;
|
|
||||||
if (mIsWifiConnected) {
|
|
||||||
updateWifiSsid();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
BatteryReceiver.updateInitialChargingStatus(mContext);
|
||||||
* Receiver for {@link Intent#ACTION_BATTERY_CHANGED}, which is used to determine the initial
|
NetworkReceiver.updateNetworkStatus(mContext);
|
||||||
* charging state.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
context.unregisterReceiver(this);
|
|
||||||
int status = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
|
|
||||||
mIsCharging = status != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCharging() {
|
public boolean isCharging() {
|
||||||
return mIsCharging;
|
return mIsCharging;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isWifiConnected() {
|
public boolean isAllowedNetworkConnection() {
|
||||||
return mIsWifiConnected;
|
return mIsAllowedNetworkConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(Intent intent) {
|
public void update(Intent intent) {
|
||||||
mIsWifiConnected = intent.getBooleanExtra(EXTRA_HAS_WIFI, mIsWifiConnected);
|
mIsAllowedNetworkConnection =
|
||||||
|
intent.getBooleanExtra(EXTRA_IS_ALLOWED_NETWORK_CONNECTION, mIsAllowedNetworkConnection);
|
||||||
mIsCharging = intent.getBooleanExtra(EXTRA_IS_CHARGING, mIsCharging);
|
mIsCharging = intent.getBooleanExtra(EXTRA_IS_CHARGING, mIsCharging);
|
||||||
|
Log.i(TAG, "State updated, allowed network connection: " + mIsAllowedNetworkConnection +
|
||||||
|
", charging: " + mIsCharging);
|
||||||
|
|
||||||
if (mIsWifiConnected) {
|
if (mIsAllowedNetworkConnection) {
|
||||||
updateWifiSsid();
|
updateWifiSsid();
|
||||||
} else {
|
} else {
|
||||||
mWifiSsid = null;
|
mWifiSsid = null;
|
||||||
|
@ -110,17 +96,16 @@ public class DeviceStateHolder extends BroadcastReceiver {
|
||||||
* Determines if Syncthing should currently run.
|
* Determines if Syncthing should currently run.
|
||||||
*/
|
*/
|
||||||
public boolean shouldRun() {
|
public boolean shouldRun() {
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
|
||||||
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
|
||||||
prefs.getBoolean("respect_battery_saving", true) &&
|
mPreferences.getBoolean("respect_battery_saving", true) &&
|
||||||
pm.isPowerSaveMode()) {
|
pm.isPowerSaveMode()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (SyncthingService.alwaysRunInBackground(mContext)) {
|
else if (SyncthingService.alwaysRunInBackground(mContext)) {
|
||||||
// Check wifi/charging state against preferences and start if ok.
|
// Check wifi/charging state against preferences and start if ok.
|
||||||
boolean prefStopMobileData = prefs.getBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, false);
|
boolean prefStopMobileData = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, false);
|
||||||
boolean prefStopNotCharging = prefs.getBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, false);
|
boolean prefStopNotCharging = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, false);
|
||||||
|
|
||||||
return (isCharging() || !prefStopNotCharging) &&
|
return (isCharging() || !prefStopNotCharging) &&
|
||||||
(!prefStopMobileData || isAllowedWifiConnected());
|
(!prefStopMobileData || isAllowedWifiConnected());
|
||||||
|
@ -131,10 +116,9 @@ public class DeviceStateHolder extends BroadcastReceiver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllowedWifiConnected() {
|
private boolean isAllowedWifiConnected() {
|
||||||
boolean wifiConnected = isWifiConnected();
|
boolean wifiConnected = isAllowedNetworkConnection();
|
||||||
if (wifiConnected) {
|
if (wifiConnected) {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
Set<String> ssids = mPreferences.getStringSet(SyncthingService.PREF_SYNC_ONLY_WIFI_SSIDS, new HashSet<>());
|
||||||
Set<String> ssids = sp.getStringSet(SyncthingService.PREF_SYNC_ONLY_WIFI_SSIDS, new HashSet<>());
|
|
||||||
if (ssids.isEmpty()) {
|
if (ssids.isEmpty()) {
|
||||||
Log.d(TAG, "All SSIDs allowed for syncing");
|
Log.d(TAG, "All SSIDs allowed for syncing");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -167,8 +167,8 @@ public class SyncthingService extends Service implements
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles intents, either {@link #ACTION_RESTART}, or intents having
|
* Handles intents, either {@link #ACTION_RESTART}, or intents having
|
||||||
* {@link DeviceStateHolder#EXTRA_HAS_WIFI} or {@link DeviceStateHolder#EXTRA_IS_CHARGING}
|
* {@link DeviceStateHolder#EXTRA_IS_ALLOWED_NETWORK_CONNECTION} or
|
||||||
* (which are handled by {@link DeviceStateHolder}.
|
* {@link DeviceStateHolder#EXTRA_IS_CHARGING} (which are handled by {@link DeviceStateHolder}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
@ -184,7 +184,7 @@ public class SyncthingService extends Service implements
|
||||||
new SyncthingRunnable(this, SyncthingRunnable.Command.reset).run();
|
new SyncthingRunnable(this, SyncthingRunnable.Command.reset).run();
|
||||||
mCurrentState = State.INIT;
|
mCurrentState = State.INIT;
|
||||||
updateState();
|
updateState();
|
||||||
} else if (mCurrentState != State.INIT) {
|
} else {
|
||||||
mDeviceStateHolder.update(intent);
|
mDeviceStateHolder.update(intent);
|
||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,6 @@ public class SyncthingService extends Service implements
|
||||||
PRNGFixes.apply();
|
PRNGFixes.apply();
|
||||||
|
|
||||||
mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this);
|
mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this);
|
||||||
registerReceiver(mDeviceStateHolder, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
registerReceiver(mPowerSaveModeChangedReceiver,
|
registerReceiver(mPowerSaveModeChangedReceiver,
|
||||||
new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
|
new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
|
||||||
|
|
Loading…
Reference in a new issue