Skip to content

Commit

Permalink
Start receivers when required, instead of declaring them in manifest
Browse files Browse the repository at this point in the history
  • Loading branch information
Nutomic committed Oct 19, 2017
1 parent fc79c3c commit da9db84
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 75 deletions.
12 changes: 0 additions & 12 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,6 @@
android:value=".activities.MainActivity" />
</activity>
<service android:name=".service.SyncthingService" />

<receiver android:name=".receiver.NetworkReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.BatteryReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.nutomic.syncthingandroid.activities.FirstStartActivity;
import com.nutomic.syncthingandroid.activities.FolderPickerActivity;
import com.nutomic.syncthingandroid.activities.MainActivity;
import com.nutomic.syncthingandroid.activities.SettingsActivity;
import com.nutomic.syncthingandroid.receiver.AppConfigReceiver;
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
import com.nutomic.syncthingandroid.service.EventProcessor;
Expand Down Expand Up @@ -32,4 +33,5 @@ public interface DaggerComponent {
void inject(NotificationHandler notificationHandler);
void inject(AppConfigReceiver appConfigReceiver);
void inject(RestApi restApi);
void inject(SettingsActivity.SettingsFragment fragment);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
Expand All @@ -12,17 +13,20 @@
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.model.Config;
import com.nutomic.syncthingandroid.model.Device;
import com.nutomic.syncthingandroid.model.Options;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.NotificationHandler;
import com.nutomic.syncthingandroid.service.RestApi;
import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.util.Languages;
Expand All @@ -31,6 +35,8 @@

import java.security.InvalidParameterException;

import javax.inject.Inject;

import eu.chainfire.libsuperuser.Shell;

public class SettingsActivity extends SyncthingActivity {
Expand All @@ -46,14 +52,17 @@ protected void onCreate(Bundle savedInstanceState) {
public static class SettingsFragment extends PreferenceFragment
implements SyncthingActivity.OnServiceConnectedListener,
SyncthingService.OnApiChangeListener, Preference.OnPreferenceChangeListener,
Preference.OnPreferenceClickListener {
Preference.OnPreferenceClickListener, SharedPreferences.OnSharedPreferenceChangeListener {

private static final String TAG = "SettingsFragment";
private static final String KEY_STTRACE = "sttrace";
private static final String KEY_EXPORT_CONFIG = "export_config";
private static final String KEY_IMPORT_CONFIG = "import_config";
private static final String KEY_STRESET = "streset";

@Inject NotificationHandler mNotificationHandler;
@Inject SharedPreferences mPreferences;

private CheckBoxPreference mAlwaysRunInBackground;
private CheckBoxPreference mSyncOnlyCharging;
private CheckBoxPreference mSyncOnlyWifi;
Expand Down Expand Up @@ -84,6 +93,14 @@ public static class SettingsFragment extends PreferenceFragment
private Options mOptions;
private Config.Gui mGui;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((SyncthingApp) getActivity().getApplication()).component().inject(this);
((SyncthingActivity) getActivity()).registerOnServiceConnectedListener(this);
mPreferences.registerOnSharedPreferenceChangeListener(this);
}

/**
* Loads layout, sets version from Rest API.
*
Expand All @@ -93,8 +110,6 @@ public static class SettingsFragment extends PreferenceFragment
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

((SyncthingActivity) getActivity()).registerOnServiceConnectedListener(this);

addPreferencesFromResource(R.xml.app_settings);
PreferenceScreen screen = getPreferenceScreen();
mAlwaysRunInBackground =
Expand Down Expand Up @@ -228,6 +243,7 @@ public void onApiChange(SyncthingService.State currentState) {
@Override
public void onDestroy() {
super.onDestroy();
mPreferences.unregisterOnSharedPreferenceChangeListener(this);
if (mSyncthingService != null)
mSyncthingService.unregisterOnApiChangeListener(this);
}
Expand Down Expand Up @@ -394,6 +410,13 @@ public boolean onPreferenceClick(Preference preference) {
}
}

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(Constants.PREF_NOTIFICATION_TYPE) || key.equals(Constants.PREF_FOREGROUND_SERVICE)) {
mNotificationHandler.updatePersistentNotification(mSyncthingService);
}
}

/**
* Enables or disables {@link #mUseRoot} preference depending whether root is available.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ public void onReceive(Context context, Intent intent) {
Intent i = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
i.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging);
lbm.sendBroadcast(i);

// Make sure service is running.
BootReceiver.startServiceCompat(context);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void onReceive(Context context, Intent intent) {
*
* https://stackoverflow.com/a/44505719/1837158
*/
public static void startServiceCompat(Context context) {
private static void startServiceCompat(Context context) {
// This method is called from {@link DeviceStateHolder#DeviceStateHolder()}, make sure it
// is only executed if run in background is enabled.
if (!DeviceStateHolder.alwaysRunInBackground(context))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ public static void updateNetworkStatus(Context context) {
Intent intent = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
intent.putExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION, isAllowedConnection);
lbm.sendBroadcast(intent);

// Make sure service is running.
BootReceiver.startServiceCompat(context);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.google.common.collect.Lists;
import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.receiver.BatteryReceiver;
import com.nutomic.syncthingandroid.receiver.NetworkReceiver;
import com.nutomic.syncthingandroid.receiver.PowerSaveModeChangedReceiver;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;
Expand All @@ -27,7 +33,7 @@
* This information is actively read on instance creation, and then updated from intents
* that are passed with {@link #ACTION_DEVICE_STATE_CHANGED}.
*/
public class DeviceStateHolder {
public class DeviceStateHolder implements SharedPreferences.OnSharedPreferenceChangeListener {

private static final String TAG = "DeviceStateHolder";

Expand Down Expand Up @@ -68,25 +74,87 @@ public interface OnDeviceStateChangedListener {
private final OnDeviceStateChangedListener mListener;
@Inject SharedPreferences mPreferences;

private boolean mIsAllowedNetworkConnection = false;
private @Nullable NetworkReceiver mNetworkReceiver;
private @Nullable BatteryReceiver mBatteryReceiver;
private @Nullable BroadcastReceiver mPowerSaveModeChangedReceiver;

private boolean mIsAllowedNetworkConnection;
private String mWifiSsid;
private boolean mIsCharging = false;
private boolean mIsPowerSaving = true;
private boolean mIsCharging;
private boolean mIsPowerSaving;

public DeviceStateHolder(Context context, OnDeviceStateChangedListener listener) {
((SyncthingApp) context.getApplicationContext()).component().inject(this);
mContext = context;
mBroadcastManager = LocalBroadcastManager.getInstance(mContext);
mBroadcastManager.registerReceiver(mReceiver, new IntentFilter(ACTION_DEVICE_STATE_CHANGED));
mPreferences.registerOnSharedPreferenceChangeListener(this);
mListener = listener;

BatteryReceiver.updateInitialChargingStatus(mContext);
NetworkReceiver.updateNetworkStatus(mContext);
PowerSaveModeChangedReceiver.updatePowerSavingState(mContext);
updateReceivers();
}

public void shutdown() {
mBroadcastManager.unregisterReceiver(mReceiver);
mPreferences.unregisterOnSharedPreferenceChangeListener(this);

unregisterReceiver(mNetworkReceiver);
unregisterReceiver(mBatteryReceiver);
unregisterReceiver(mPowerSaveModeChangedReceiver);
}

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
List<String> watched = Lists.newArrayList(Constants.PREF_SYNC_ONLY_CHARGING,
Constants.PREF_SYNC_ONLY_WIFI, Constants.PREF_RESPECT_BATTERY_SAVING,
Constants.PREF_SYNC_ONLY_WIFI_SSIDS);
if (watched.contains(key)) {
updateReceivers();
}
}

private void updateReceivers() {
if (mPreferences.getBoolean(Constants.PREF_SYNC_ONLY_WIFI, false)) {
Log.i(TAG, "Listening for network state changes");
NetworkReceiver.updateNetworkStatus(mContext);
mNetworkReceiver = new NetworkReceiver();
mContext.registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
} else {
Log.i(TAG, "Stopped listening to network state changes");
unregisterReceiver(mNetworkReceiver);
mNetworkReceiver = null;
}

if (mPreferences.getBoolean(Constants.PREF_SYNC_ONLY_CHARGING, false)) {
Log.i(TAG, "Listening to battery state changes");
BatteryReceiver.updateInitialChargingStatus(mContext);
mBatteryReceiver = new BatteryReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
mContext.registerReceiver(mBatteryReceiver, filter);
} else {
Log.i(TAG, "Stopped listening to battery state changes");
unregisterReceiver(mBatteryReceiver);
mBatteryReceiver = null;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
mPreferences.getBoolean("respect_battery_saving", true)) {
Log.i(TAG, "Listening to power saving changes");
PowerSaveModeChangedReceiver.updatePowerSavingState(mContext);
mPowerSaveModeChangedReceiver = new PowerSaveModeChangedReceiver();
mContext.registerReceiver(mPowerSaveModeChangedReceiver,
new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
} else {
Log.i(TAG, "Stopped listening to power saving changes");
unregisterReceiver(mPowerSaveModeChangedReceiver);
mPowerSaveModeChangedReceiver = null;
}
}

private void unregisterReceiver(BroadcastReceiver receiver) {
if (receiver != null)
mContext.unregisterReceiver(receiver);
}

private class DeviceStateChangedReceiver extends BroadcastReceiver {
Expand Down Expand Up @@ -154,7 +222,6 @@ private boolean isWhitelistedNetworkConnection() {
}
}
}
Log.d(TAG, "Wifi not connected");
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public NotificationHandler(Context context) {
* Shows or hides the persistent notification based on running state and
* {@link Constants#PREF_NOTIFICATION_TYPE}.
*/
public void updatePersistentNotification(SyncthingService service, SyncthingService.State currentState) {
public void updatePersistentNotification(SyncthingService service) {
String type = mPreferences.getString(Constants.PREF_NOTIFICATION_TYPE, "low_priority");
boolean foreground = mPreferences.getBoolean(Constants.PREF_FOREGROUND_SERVICE, false);

Expand All @@ -57,8 +57,8 @@ public void updatePersistentNotification(SyncthingService service, SyncthingServ
type = "low_priority";
}

boolean syncthingRunning = currentState == SyncthingService.State.ACTIVE ||
currentState == SyncthingService.State.STARTING;
boolean syncthingRunning = service.getCurrentState() == SyncthingService.State.ACTIVE ||
service.getCurrentState() == SyncthingService.State.STARTING;
if (foreground || (syncthingRunning && !type.equals("none"))) {
// Launch FirstStartActivity instead of MainActivity so we can request permission if
// necessary.
Expand Down
Loading

0 comments on commit da9db84

Please sign in to comment.