1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2024-11-26 14:21:16 +00:00

Refactor DeviceStateHolder and receivers

This commit is contained in:
Felix Ableitner 2017-10-02 15:21:11 +09:00
parent 9ad854defb
commit be1be9746e
5 changed files with 121 additions and 53 deletions

View file

@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.BatteryManager; import android.os.BatteryManager;
import android.support.v4.content.LocalBroadcastManager;
import com.nutomic.syncthingandroid.service.DeviceStateHolder; import com.nutomic.syncthingandroid.service.DeviceStateHolder;
import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.service.SyncthingService;
@ -24,9 +25,13 @@ 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());
Intent i = new Intent(context, SyncthingService.class); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
Intent i = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
i.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging); i.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging);
context.startService(i); lbm.sendBroadcast(i);
// Make sure service is running.
context.startService(new Intent(context, SyncthingService.class));
} }
/** /**
@ -38,9 +43,10 @@ public class BatteryReceiver extends BroadcastReceiver {
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL; status == BatteryManager.BATTERY_STATUS_FULL;
Intent intent = new Intent(context, SyncthingService.class); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
Intent intent = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
intent.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging); intent.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging);
context.startService(intent); lbm.sendBroadcast(intent);
} }
} }

View file

@ -7,6 +7,8 @@ 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.os.Build;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.nutomic.syncthingandroid.service.DeviceStateHolder; import com.nutomic.syncthingandroid.service.DeviceStateHolder;
import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.service.SyncthingService;
@ -37,9 +39,13 @@ public class NetworkReceiver extends BroadcastReceiver {
boolean isNetworkMetered = (Build.VERSION.SDK_INT >= 16) ? cm.isActiveNetworkMetered() : false; boolean isNetworkMetered = (Build.VERSION.SDK_INT >= 16) ? cm.isActiveNetworkMetered() : false;
boolean isAllowedConnection = isOffline || (isWifi && !isNetworkMetered); boolean isAllowedConnection = isOffline || (isWifi && !isNetworkMetered);
Intent intent = new Intent(context, SyncthingService.class); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
Intent intent = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
intent.putExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION, isAllowedConnection); intent.putExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION, isAllowedConnection);
context.startService(intent); lbm.sendBroadcast(intent);
// Make sure service is running.
context.startService(new Intent(context, SyncthingService.class));
} }
} }

View file

@ -0,0 +1,31 @@
package com.nutomic.syncthingandroid.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.PowerManager;
import android.support.v4.content.LocalBroadcastManager;
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
import com.nutomic.syncthingandroid.service.SyncthingService;
public class PowerSaveModeChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(intent.getAction()))
return;
updatePowerSavingState(context);
}
public static void updatePowerSavingState(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
boolean isPowerSaveMode = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && pm.isPowerSaveMode();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
Intent intent = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
intent.putExtra(DeviceStateHolder.EXTRA_IS_POWER_SAVING, isPowerSaveMode);
lbm.sendBroadcast(intent);
}
}

View file

@ -1,31 +1,40 @@
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.wifi.WifiInfo; import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
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.support.v4.content.LocalBroadcastManager;
import android.util.Log; import android.util.Log;
import com.google.common.base.Joiner;
import com.nutomic.syncthingandroid.receiver.BatteryReceiver; import com.nutomic.syncthingandroid.receiver.BatteryReceiver;
import com.nutomic.syncthingandroid.receiver.NetworkReceiver; import com.nutomic.syncthingandroid.receiver.NetworkReceiver;
import com.nutomic.syncthingandroid.receiver.PowerSaveModeChangedReceiver;
import java.util.Collections;
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.
* *
* This information is actively read on construction, and then updated from intents that are passed * This information is actively read on instance creation, and then updated from intents
* to {@link #update(android.content.Intent)}. * that are passed with {@link #ACTION_DEVICE_STATE_CHANGED}.
*/ */
public class DeviceStateHolder { public class DeviceStateHolder {
private static final String TAG = "DeviceStateHolder"; private static final String TAG = "DeviceStateHolder";
public static final String ACTION_DEVICE_STATE_CHANGED =
"com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.DEVICE_STATE_CHANGED";
/** /**
* Intent extra containing a boolean saying whether wifi is connected or not. * Intent extra containing a boolean saying whether wifi is connected or not.
*/ */
@ -39,29 +48,53 @@ public class DeviceStateHolder {
public static final String EXTRA_IS_CHARGING = public static final String EXTRA_IS_CHARGING =
"com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_CHARGING"; "com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_CHARGING";
public static final String EXTRA_IS_POWER_SAVING =
"com.nutomic.syncthingandroid.syncthing.DeviceStateHolder.IS_POWER_SAVING";
public interface OnDeviceStateChangedListener {
void onDeviceStateChanged();
}
private final Context mContext; private final Context mContext;
private final SharedPreferences mPreferences; private final SharedPreferences mPreferences;
private final LocalBroadcastManager mBroadcastManager;
private final DeviceStateChangedReceiver mReceiver = new DeviceStateChangedReceiver();
private final OnDeviceStateChangedListener mListener;
private boolean mIsAllowedNetworkConnection = false; private boolean mIsAllowedNetworkConnection = false;
private String mWifiSsid; private String mWifiSsid;
private boolean mIsCharging = false; private boolean mIsCharging = false;
private boolean mIsPowerSaving = true;
public DeviceStateHolder(Context context) { public DeviceStateHolder(Context context, OnDeviceStateChangedListener listener) {
mContext = context; mContext = context;
mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
mBroadcastManager = LocalBroadcastManager.getInstance(mContext);
mBroadcastManager.registerReceiver(mReceiver, new IntentFilter(ACTION_DEVICE_STATE_CHANGED));
mListener = listener;
BatteryReceiver.updateInitialChargingStatus(mContext); BatteryReceiver.updateInitialChargingStatus(mContext);
NetworkReceiver.updateNetworkStatus(mContext); NetworkReceiver.updateNetworkStatus(mContext);
PowerSaveModeChangedReceiver.updatePowerSavingState(mContext);
} }
public void update(Intent intent) { public void shutdown() {
mIsAllowedNetworkConnection = mBroadcastManager.unregisterReceiver(mReceiver);
intent.getBooleanExtra(EXTRA_IS_ALLOWED_NETWORK_CONNECTION, mIsAllowedNetworkConnection); }
mIsCharging = intent.getBooleanExtra(EXTRA_IS_CHARGING, mIsCharging);
Log.i(TAG, "State updated, allowed network connection: " + mIsAllowedNetworkConnection +
", charging: " + mIsCharging);
updateWifiSsid(); private class DeviceStateChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
mIsAllowedNetworkConnection =
intent.getBooleanExtra(EXTRA_IS_ALLOWED_NETWORK_CONNECTION, mIsAllowedNetworkConnection);
mIsCharging = intent.getBooleanExtra(EXTRA_IS_CHARGING, mIsCharging);
mIsPowerSaving = intent.getBooleanExtra(EXTRA_IS_POWER_SAVING, mIsPowerSaving);
Log.i(TAG, "State updated, allowed network connection: " + mIsAllowedNetworkConnection +
", charging: " + mIsCharging + ", power saving: " + mIsPowerSaving);
updateWifiSsid();
mListener.onDeviceStateChanged();
}
} }
private void updateWifiSsid() { private void updateWifiSsid() {
@ -69,7 +102,7 @@ public class DeviceStateHolder {
WifiManager wifiManager = WifiManager wifiManager =
(WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE); (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo(); WifiInfo wifiInfo = wifiManager.getConnectionInfo();
// may be null, if WiFi has been turned off in meantime // May be null, if WiFi has been turned off in meantime.
if (wifiInfo != null) { if (wifiInfo != null) {
mWifiSsid = wifiInfo.getSSID(); mWifiSsid = wifiInfo.getSSID();
} }
@ -78,24 +111,23 @@ public class DeviceStateHolder {
/** /**
* Determines if Syncthing should currently run. * Determines if Syncthing should currently run.
*/ */
public boolean shouldRun() { boolean shouldRun() {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); boolean prefRespectPowerSaving = mPreferences.getBoolean("respect_battery_saving", true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && if (prefRespectPowerSaving && mIsPowerSaving)
mPreferences.getBoolean("respect_battery_saving", true) &&
pm.isPowerSaveMode()) {
return false; return false;
}
else if (SyncthingService.alwaysRunInBackground(mContext)) { if (SyncthingService.alwaysRunInBackground(mContext)) {
// Check wifi/charging state against preferences and start if ok.
boolean prefStopMobileData = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, false); boolean prefStopMobileData = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, false);
boolean prefStopNotCharging = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, false); boolean prefStopNotCharging = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, false);
return (mIsCharging || !prefStopNotCharging) && if (prefStopMobileData && !isWhitelistedNetworkConnection())
(!prefStopMobileData || isWhitelistedNetworkConnection()); return false;
}
else { if (prefStopNotCharging && !mIsCharging)
return true; return false;
} }
return true;
} }
private boolean isWhitelistedNetworkConnection() { private boolean isWhitelistedNetworkConnection() {

View file

@ -28,6 +28,7 @@ import com.nutomic.syncthingandroid.activities.FirstStartActivity;
import com.nutomic.syncthingandroid.http.PollWebGuiAvailableTask; import com.nutomic.syncthingandroid.http.PollWebGuiAvailableTask;
import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.model.Folder;
import com.nutomic.syncthingandroid.receiver.NetworkReceiver; import com.nutomic.syncthingandroid.receiver.NetworkReceiver;
import com.nutomic.syncthingandroid.receiver.PowerSaveModeChangedReceiver;
import com.nutomic.syncthingandroid.util.ConfigXml; import com.nutomic.syncthingandroid.util.ConfigXml;
import com.nutomic.syncthingandroid.util.FolderObserver; import com.nutomic.syncthingandroid.util.FolderObserver;
@ -97,18 +98,6 @@ public class SyncthingService extends Service implements
private static final int NOTIFICATION_ACTIVE = 1; private static final int NOTIFICATION_ACTIVE = 1;
private ConfigXml mConfig;
private RestApi mApi;
private EventProcessor mEventProcessor;
private final LinkedList<FolderObserver> mObservers = new LinkedList<>();
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
private final NetworkReceiver mNetworkReceiver = new NetworkReceiver();
/** /**
* Callback for when the Syncthing web interface becomes first available after service start. * Callback for when the Syncthing web interface becomes first available after service start.
*/ */
@ -125,13 +114,6 @@ public class SyncthingService extends Service implements
private final HashSet<OnApiChangeListener> mOnApiChangeListeners = private final HashSet<OnApiChangeListener> mOnApiChangeListeners =
new HashSet<>(); new HashSet<>();
private final BroadcastReceiver mPowerSaveModeChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateState();
}
};
/** /**
* Indicates the current state of SyncthingService and of Syncthing itself. * Indicates the current state of SyncthingService and of Syncthing itself.
@ -151,6 +133,19 @@ public class SyncthingService extends Service implements
private State mCurrentState = State.INIT; private State mCurrentState = State.INIT;
private ConfigXml mConfig;
private RestApi mApi;
private EventProcessor mEventProcessor;
private final LinkedList<FolderObserver> mObservers = new LinkedList<>();
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
private final NetworkReceiver mNetworkReceiver = new NetworkReceiver();
private final BroadcastReceiver mPowerSaveModeChangedReceiver = new PowerSaveModeChangedReceiver();
/** /**
* Object that can be locked upon when accessing mCurrentState * Object that can be locked upon when accessing mCurrentState
* Currently used to male onDestroy() and PollWebGuiAvailableTaskImpl.onPostExcecute() tread-safe * Currently used to male onDestroy() and PollWebGuiAvailableTaskImpl.onPostExcecute() tread-safe
@ -184,9 +179,6 @@ public class SyncthingService extends Service implements
new SyncthingRunnable(this, SyncthingRunnable.Command.reset).run(); new SyncthingRunnable(this, SyncthingRunnable.Command.reset).run();
new StartupTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new StartupTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}); });
} else {
mDeviceStateHolder.update(intent);
updateState();
} }
return START_STICKY; return START_STICKY;
} }
@ -285,7 +277,7 @@ public class SyncthingService extends Service implements
super.onCreate(); super.onCreate();
PRNGFixes.apply(); PRNGFixes.apply();
mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this); mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this, this::updateState);
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));
@ -393,6 +385,7 @@ public class SyncthingService extends Service implements
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.unregisterOnSharedPreferenceChangeListener(this); sp.unregisterOnSharedPreferenceChangeListener(this);
mDeviceStateHolder.shutdown();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
unregisterReceiver(mPowerSaveModeChangedReceiver); unregisterReceiver(mPowerSaveModeChangedReceiver);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)