mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-23 11:21:29 +00:00
Merge pull request #711 from syncthing/improve-state-handling
Disable sync if Android sync setting is disabled
This commit is contained in:
commit
88cef95656
3 changed files with 99 additions and 49 deletions
|
@ -12,6 +12,7 @@
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
|
|
|
@ -2,12 +2,21 @@ package com.nutomic.syncthingandroid.syncthing;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
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.BatteryManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
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.
|
||||||
|
@ -17,6 +26,8 @@ import android.os.BatteryManager;
|
||||||
*/
|
*/
|
||||||
public class DeviceStateHolder extends BroadcastReceiver {
|
public class DeviceStateHolder extends BroadcastReceiver {
|
||||||
|
|
||||||
|
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.
|
||||||
*/
|
*/
|
||||||
|
@ -91,7 +102,62 @@ public class DeviceStateHolder extends BroadcastReceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWifiSsid() {
|
private String getWifiSsid() {
|
||||||
return mWifiSsid;
|
return mWifiSsid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if Syncthing should currently run.
|
||||||
|
*/
|
||||||
|
@TargetApi(21)
|
||||||
|
public boolean shouldRun() {
|
||||||
|
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB && pm.isPowerSaveMode()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!ContentResolver.getMasterSyncAutomatically()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (SyncthingService.alwaysRunInBackground(mContext)) {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||||
|
// Check wifi/charging state against preferences and start if ok.
|
||||||
|
boolean prefStopMobileData = prefs.getBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, false);
|
||||||
|
boolean prefStopNotCharging = prefs.getBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, false);
|
||||||
|
|
||||||
|
return (isCharging() || !prefStopNotCharging) &&
|
||||||
|
(!prefStopMobileData || isAllowedWifiConnected());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAllowedWifiConnected() {
|
||||||
|
boolean wifiConnected = isWifiConnected();
|
||||||
|
if (wifiConnected) {
|
||||||
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||||
|
Set<String> ssids = sp.getStringSet(SyncthingService.PREF_SYNC_ONLY_WIFI_SSIDS, new HashSet<String>());
|
||||||
|
if (ssids.isEmpty()) {
|
||||||
|
Log.d(TAG, "All SSIDs allowed for syncing");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
String ssid = getWifiSsid();
|
||||||
|
if (ssid != null) {
|
||||||
|
if (ssids.contains(ssid)) {
|
||||||
|
Log.d(TAG, "SSID [" + ssid + "] found in whitelist: " + ssids);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Log.i(TAG, "SSID [" + ssid + "] not whitelisted: " + ssids);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// Don't know the SSID (yet) (should not happen?!), so not allowing
|
||||||
|
Log.w(TAG, "SSID unknown (yet), cannot check SSID whitelist. Disallowing sync.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d(TAG, "Wifi not connected");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
package com.nutomic.syncthingandroid.syncthing;
|
package com.nutomic.syncthingandroid.syncthing;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.annotation.TargetApi;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SyncStatusObserver;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.PowerManager;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -22,7 +24,6 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.activities.MainActivity;
|
import com.nutomic.syncthingandroid.activities.MainActivity;
|
||||||
import com.nutomic.syncthingandroid.activities.SettingsActivity;
|
|
||||||
import com.nutomic.syncthingandroid.util.ConfigXml;
|
import com.nutomic.syncthingandroid.util.ConfigXml;
|
||||||
import com.nutomic.syncthingandroid.util.FolderObserver;
|
import com.nutomic.syncthingandroid.util.FolderObserver;
|
||||||
import com.nutomic.syncthingandroid.util.PRNGFixes;
|
import com.nutomic.syncthingandroid.util.PRNGFixes;
|
||||||
|
@ -128,6 +129,20 @@ public class SyncthingService extends Service implements
|
||||||
private final HashSet<OnApiChangeListener> mOnApiChangeListeners =
|
private final HashSet<OnApiChangeListener> mOnApiChangeListeners =
|
||||||
new HashSet<>();
|
new HashSet<>();
|
||||||
|
|
||||||
|
private final SyncStatusObserver mSyncStatusObserver = new SyncStatusObserver() {
|
||||||
|
@Override
|
||||||
|
public void onStatusChanged(int i) {
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver mPowerSaveModeChangedReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* INIT: Service is starting up and initializing.
|
* INIT: Service is starting up and initializing.
|
||||||
* STARTING: Syncthing binary is starting (but the API is not yet ready).
|
* STARTING: Syncthing binary is starting (but the API is not yet ready).
|
||||||
|
@ -194,23 +209,8 @@ public class SyncthingService extends Service implements
|
||||||
* called.
|
* called.
|
||||||
*/
|
*/
|
||||||
public void updateState() {
|
public void updateState() {
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
boolean shouldRun;
|
|
||||||
if (!alwaysRunInBackground(this)) {
|
|
||||||
// Always run, ignoring wifi/charging state.
|
|
||||||
shouldRun = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Check wifi/charging state against preferences and start if ok.
|
|
||||||
boolean prefStopMobileData = prefs.getBoolean(PREF_SYNC_ONLY_WIFI, false);
|
|
||||||
boolean prefStopNotCharging = prefs.getBoolean(PREF_SYNC_ONLY_CHARGING, false);
|
|
||||||
|
|
||||||
shouldRun = (mDeviceStateHolder.isCharging() || !prefStopNotCharging) &&
|
|
||||||
(!prefStopMobileData || isAllowedWifiConnected());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start syncthing.
|
// Start syncthing.
|
||||||
if (shouldRun) {
|
if (mDeviceStateHolder.shouldRun()) {
|
||||||
if (mCurrentState == State.ACTIVE || mCurrentState == State.STARTING) {
|
if (mCurrentState == State.ACTIVE || mCurrentState == State.STARTING) {
|
||||||
mStopScheduled = false;
|
mStopScheduled = false;
|
||||||
return;
|
return;
|
||||||
|
@ -257,34 +257,6 @@ public class SyncthingService extends Service implements
|
||||||
onApiChange();
|
onApiChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllowedWifiConnected() {
|
|
||||||
boolean wifiConnected = mDeviceStateHolder.isWifiConnected();
|
|
||||||
if (wifiConnected) {
|
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
Set<String> ssids = sp.getStringSet(PREF_SYNC_ONLY_WIFI_SSIDS, new HashSet<String>());
|
|
||||||
if (ssids.isEmpty()) {
|
|
||||||
Log.d(TAG, "All SSIDs allowed for syncing");
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
String ssid = mDeviceStateHolder.getWifiSsid();
|
|
||||||
if (ssid != null) {
|
|
||||||
if (ssids.contains(ssid)) {
|
|
||||||
Log.d(TAG, "SSID [" + ssid + "] found in whitelist: " + ssids);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Log.i(TAG, "SSID [" + ssid + "] not whitelisted: " + ssids);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// Don't know the SSID (yet) (should not happen?!), so not allowing
|
|
||||||
Log.w(TAG, "SSID unknown (yet), cannot check SSID whitelist. Disallowing sync.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.d(TAG, "Wifi not connected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows or hides the persistent notification based on running state and
|
* Shows or hides the persistent notification based on running state and
|
||||||
* {@link #PREF_NOTIFICATION_TYPE}.
|
* {@link #PREF_NOTIFICATION_TYPE}.
|
||||||
|
@ -339,6 +311,7 @@ public class SyncthingService extends Service implements
|
||||||
* Starts the native binary.
|
* Starts the native binary.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@TargetApi(21)
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
PRNGFixes.apply();
|
PRNGFixes.apply();
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
@ -359,8 +332,15 @@ public class SyncthingService extends Service implements
|
||||||
|
|
||||||
mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this);
|
mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this);
|
||||||
registerReceiver(mDeviceStateHolder, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
registerReceiver(mDeviceStateHolder, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
|
||||||
|
registerReceiver(mPowerSaveModeChangedReceiver,
|
||||||
|
new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
|
||||||
|
}
|
||||||
|
|
||||||
new StartupTask(sp.getString("gui_user",""), sp.getString("gui_password","")).execute();
|
new StartupTask(sp.getString("gui_user",""), sp.getString("gui_password","")).execute();
|
||||||
sp.registerOnSharedPreferenceChangeListener(this);
|
sp.registerOnSharedPreferenceChangeListener(this);
|
||||||
|
ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
|
||||||
|
mSyncStatusObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -467,6 +447,9 @@ public class SyncthingService extends Service implements
|
||||||
|
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
sp.unregisterOnSharedPreferenceChangeListener(this);
|
sp.unregisterOnSharedPreferenceChangeListener(this);
|
||||||
|
ContentResolver.removeStatusChangeListener(mSyncStatusObserver);
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB)
|
||||||
|
unregisterReceiver(mPowerSaveModeChangedReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shutdown() {
|
private void shutdown() {
|
||||||
|
|
Loading…
Reference in a new issue