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

Moved Syncthing constants to seperate file

This commit is contained in:
Felix Ableitner 2017-10-04 17:44:56 +09:00
parent 4c2b325676
commit 1fd86211dc
18 changed files with 164 additions and 165 deletions

View file

@ -22,6 +22,7 @@ import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.model.Config; import com.nutomic.syncthingandroid.model.Config;
import com.nutomic.syncthingandroid.model.Device; import com.nutomic.syncthingandroid.model.Device;
import com.nutomic.syncthingandroid.model.Options; import com.nutomic.syncthingandroid.model.Options;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.RestApi; import com.nutomic.syncthingandroid.service.RestApi;
import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.util.Languages; import com.nutomic.syncthingandroid.util.Languages;
@ -94,13 +95,13 @@ public class SettingsActivity extends SyncthingActivity {
addPreferencesFromResource(R.xml.app_settings); addPreferencesFromResource(R.xml.app_settings);
PreferenceScreen screen = getPreferenceScreen(); PreferenceScreen screen = getPreferenceScreen();
mAlwaysRunInBackground = mAlwaysRunInBackground =
(CheckBoxPreference) findPreference(SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND); (CheckBoxPreference) findPreference(Constants.PREF_ALWAYS_RUN_IN_BACKGROUND);
mSyncOnlyCharging = mSyncOnlyCharging =
(CheckBoxPreference) findPreference(SyncthingService.PREF_SYNC_ONLY_CHARGING); (CheckBoxPreference) findPreference(Constants.PREF_SYNC_ONLY_CHARGING);
mSyncOnlyWifi = mSyncOnlyWifi =
(CheckBoxPreference) findPreference(SyncthingService.PREF_SYNC_ONLY_WIFI); (CheckBoxPreference) findPreference(Constants.PREF_SYNC_ONLY_WIFI);
mSyncOnlyOnSSIDs = mSyncOnlyOnSSIDs =
(WifiSsidPreference) findPreference(SyncthingService.PREF_SYNC_ONLY_WIFI_SSIDS); (WifiSsidPreference) findPreference(Constants.PREF_SYNC_ONLY_WIFI_SSIDS);
mSyncOnlyCharging.setEnabled(mAlwaysRunInBackground.isChecked()); mSyncOnlyCharging.setEnabled(mAlwaysRunInBackground.isChecked());
mSyncOnlyWifi.setEnabled(mAlwaysRunInBackground.isChecked()); mSyncOnlyWifi.setEnabled(mAlwaysRunInBackground.isChecked());
@ -140,8 +141,8 @@ public class SettingsActivity extends SyncthingActivity {
Preference environmentVariables = findPreference("environment_variables"); Preference environmentVariables = findPreference("environment_variables");
Preference stReset = findPreference("streset"); Preference stReset = findPreference("streset");
mUseRoot = (CheckBoxPreference) findPreference(SyncthingService.PREF_USE_ROOT); mUseRoot = (CheckBoxPreference) findPreference(Constants.PREF_USE_ROOT);
Preference useWakelock = findPreference(SyncthingService.PREF_USE_WAKE_LOCK); Preference useWakelock = findPreference(Constants.PREF_USE_WAKE_LOCK);
Preference foregroundService = findPreference("run_as_foreground_service"); Preference foregroundService = findPreference("run_as_foreground_service");
Preference useTor = findPreference("use_tor"); Preference useTor = findPreference("use_tor");
@ -284,7 +285,7 @@ public class SettingsActivity extends SyncthingActivity {
@Override @Override
public boolean onPreferenceChange(Preference preference, Object o) { public boolean onPreferenceChange(Preference preference, Object o) {
switch (preference.getKey()) { switch (preference.getKey()) {
case SyncthingService.PREF_ALWAYS_RUN_IN_BACKGROUND: case Constants.PREF_ALWAYS_RUN_IN_BACKGROUND:
boolean value = (Boolean) o; boolean value = (Boolean) o;
mAlwaysRunInBackground.setSummary((value) mAlwaysRunInBackground.setSummary((value)
? R.string.always_run_in_background_enabled ? R.string.always_run_in_background_enabled
@ -298,7 +299,7 @@ public class SettingsActivity extends SyncthingActivity {
mSyncOnlyWifi.setChecked(false); mSyncOnlyWifi.setChecked(false);
} }
break; break;
case SyncthingService.PREF_SYNC_ONLY_WIFI: case Constants.PREF_SYNC_ONLY_WIFI:
mSyncOnlyOnSSIDs.setEnabled((Boolean) o); mSyncOnlyOnSSIDs.setEnabled((Boolean) o);
break; break;
case KEY_STTRACE: case KEY_STTRACE:
@ -328,7 +329,7 @@ public class SettingsActivity extends SyncthingActivity {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
switch (preference.getKey()) { switch (preference.getKey()) {
case SyncthingService.PREF_USE_ROOT: case Constants.PREF_USE_ROOT:
if (mUseRoot.isChecked()) { if (mUseRoot.isChecked()) {
// Only check preference after root was granted. // Only check preference after root was granted.
mUseRoot.setChecked(false); mUseRoot.setChecked(false);
@ -345,7 +346,7 @@ public class SettingsActivity extends SyncthingActivity {
mSyncthingService.exportConfig(); mSyncthingService.exportConfig();
Toast.makeText(getActivity(), Toast.makeText(getActivity(),
getString(R.string.config_export_successful, getString(R.string.config_export_successful,
SyncthingService.EXPORT_PATH), Toast.LENGTH_LONG).show(); Constants.EXPORT_PATH), Toast.LENGTH_LONG).show();
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.show(); .show();
@ -363,7 +364,7 @@ public class SettingsActivity extends SyncthingActivity {
} else { } else {
Toast.makeText(getActivity(), Toast.makeText(getActivity(),
getString(R.string.config_import_failed, getString(R.string.config_import_failed,
SyncthingService.EXPORT_PATH), Toast.LENGTH_LONG).show(); Constants.EXPORT_PATH), Toast.LENGTH_LONG).show();
} }
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)

View file

@ -17,9 +17,11 @@ import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.util.ConfigXml; import com.nutomic.syncthingandroid.util.ConfigXml;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -157,7 +159,7 @@ public class WebGuiActivity extends StateDialogActivity
private void loadCaCert() { private void loadCaCert() {
InputStream inStream = null; InputStream inStream = null;
try { try {
String httpsCertPath = getFilesDir() + "/" + SyncthingService.HTTPS_CERT_FILE; File httpsCertPath = Constants.getHttpsCertFile(this);
inStream = new FileInputStream(httpsCertPath); inStream = new FileInputStream(httpsCertPath);
CertificateFactory cf = CertificateFactory.getInstance("X.509"); CertificateFactory cf = CertificateFactory.getInstance("X.509");
mCaCert = (X509Certificate) mCaCert = (X509Certificate)

View file

@ -14,6 +14,7 @@ import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.activities.DeviceActivity; import com.nutomic.syncthingandroid.activities.DeviceActivity;
import com.nutomic.syncthingandroid.activities.SyncthingActivity; import com.nutomic.syncthingandroid.activities.SyncthingActivity;
import com.nutomic.syncthingandroid.model.Device; import com.nutomic.syncthingandroid.model.Device;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.views.DevicesAdapter; import com.nutomic.syncthingandroid.views.DevicesAdapter;
@ -58,7 +59,7 @@ public class DeviceListFragment extends ListFragment implements SyncthingService
getActivity().runOnUiThread(DeviceListFragment.this::updateList); getActivity().runOnUiThread(DeviceListFragment.this::updateList);
} }
}, 0, SyncthingService.GUI_UPDATE_INTERVAL); }, 0, Constants.GUI_UPDATE_INTERVAL);
} }
@Override @Override

View file

@ -20,11 +20,11 @@ import com.nutomic.syncthingandroid.http.ImageGetRequest;
import com.nutomic.syncthingandroid.model.Connections; import com.nutomic.syncthingandroid.model.Connections;
import com.nutomic.syncthingandroid.model.SystemInfo; import com.nutomic.syncthingandroid.model.SystemInfo;
import com.nutomic.syncthingandroid.model.SystemVersion; import com.nutomic.syncthingandroid.model.SystemVersion;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.RestApi; import com.nutomic.syncthingandroid.service.RestApi;
import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.util.Util; import com.nutomic.syncthingandroid.util.Util;
import java.io.File;
import java.net.URL; import java.net.URL;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.Locale; import java.util.Locale;
@ -57,7 +57,7 @@ public class DrawerFragment extends Fragment implements View.OnClickListener {
updateGui(); updateGui();
} }
}, 0, SyncthingService.GUI_UPDATE_INTERVAL); }, 0, Constants.GUI_UPDATE_INTERVAL);
} }
@Override @Override
@ -197,12 +197,11 @@ public class DrawerFragment extends Fragment implements View.OnClickListener {
private void showQrCode() { private void showQrCode() {
//The QRCode request takes one paramteer called "text", which is the text to be converted to a QRCode. //The QRCode request takes one paramteer called "text", which is the text to be converted to a QRCode.
File httpsCertPath = new File(mActivity.getFilesDir(), SyncthingService.HTTPS_CERT_FILE);
String apiKey = mActivity.getApi().getGui().apiKey; String apiKey = mActivity.getApi().getGui().apiKey;
String deviceId = mActivity.getApi().getLocalDevice().deviceID; String deviceId = mActivity.getApi().getLocalDevice().deviceID;
URL url = mActivity.getApi().getUrl(); URL url = mActivity.getApi().getUrl();
new ImageGetRequest(mActivity, url, ImageGetRequest.QR_CODE_GENERATOR, httpsCertPath, new ImageGetRequest(mActivity, url, ImageGetRequest.QR_CODE_GENERATOR, apiKey,
apiKey, ImmutableMap.of("text", deviceId),qrCodeBitmap -> { ImmutableMap.of("text", deviceId),qrCodeBitmap -> {
mActivity.showQrCodeDialog(deviceId, qrCodeBitmap); mActivity.showQrCodeDialog(deviceId, qrCodeBitmap);
mActivity.closeDrawer(); mActivity.closeDrawer();
}, error -> Toast.makeText(mActivity, R.string.could_not_access_deviceid, Toast.LENGTH_SHORT).show()); }, error -> Toast.makeText(mActivity, R.string.could_not_access_deviceid, Toast.LENGTH_SHORT).show());

View file

@ -13,6 +13,7 @@ import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.activities.FolderActivity; import com.nutomic.syncthingandroid.activities.FolderActivity;
import com.nutomic.syncthingandroid.activities.SyncthingActivity; import com.nutomic.syncthingandroid.activities.SyncthingActivity;
import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.model.Folder;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.views.FoldersAdapter; import com.nutomic.syncthingandroid.views.FoldersAdapter;
@ -53,7 +54,7 @@ public class FolderListFragment extends ListFragment implements SyncthingService
getActivity().runOnUiThread(FolderListFragment.this::updateList); getActivity().runOnUiThread(FolderListFragment.this::updateList);
} }
}, 0, SyncthingService.GUI_UPDATE_INTERVAL); }, 0, Constants.GUI_UPDATE_INTERVAL);
} }
@Override @Override

View file

@ -18,23 +18,15 @@ import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley; import com.android.volley.toolbox.Volley;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.nutomic.syncthingandroid.service.Constants;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.security.InvalidKeyException;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
@ -43,7 +35,6 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public abstract class ApiRequest { public abstract class ApiRequest {
@ -79,14 +70,12 @@ public abstract class ApiRequest {
private final Context mContext; private final Context mContext;
private final URL mUrl; private final URL mUrl;
private final String mPath; private final String mPath;
private final File mHttpsCertPath;
private final String mApiKey; private final String mApiKey;
public ApiRequest(Context context, URL url, String path, File httpsCertPath, String apiKey) { public ApiRequest(Context context, URL url, String path, String apiKey) {
mContext = context; mContext = context;
mUrl = url; mUrl = url;
mPath = path; mPath = path;
mHttpsCertPath = httpsCertPath;
mApiKey = apiKey; mApiKey = apiKey;
} }
@ -177,7 +166,8 @@ public abstract class ApiRequest {
private SSLSocketFactory getSslSocketFactory() { private SSLSocketFactory getSslSocketFactory() {
try { try {
SSLContext sslContext = SSLContext.getInstance("TLS"); SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new SyncthingTrustManager(mHttpsCertPath)}, File httpsCertPath = Constants.getHttpsCertFile(mContext);
sslContext.init(null, new TrustManager[]{new SyncthingTrustManager(httpsCertPath)},
new SecureRandom()); new SecureRandom());
return sslContext.getSocketFactory(); return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) { } catch (NoSuchAlgorithmException | KeyManagementException e) {

View file

@ -7,7 +7,6 @@ import android.support.annotation.Nullable;
import com.android.volley.Request; import com.android.volley.Request;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -26,9 +25,9 @@ public class GetRequest extends ApiRequest {
public static final String URI_REPORT = "/rest/svc/report"; public static final String URI_REPORT = "/rest/svc/report";
public static final String URI_EVENTS = "/rest/events"; public static final String URI_EVENTS = "/rest/events";
public GetRequest(Context context, URL url, String path, File httpsCertPath, String apiKey, public GetRequest(Context context, URL url, String path, String apiKey,
@Nullable Map<String, String> params, OnSuccessListener listener) { @Nullable Map<String, String> params, OnSuccessListener listener) {
super(context, url, path, httpsCertPath, apiKey); super(context, url, path, apiKey);
Map<String, String> safeParams = Optional.fromNullable(params).or(Collections.emptyMap()); Map<String, String> safeParams = Optional.fromNullable(params).or(Collections.emptyMap());
Uri uri = buildUri(safeParams); Uri uri = buildUri(safeParams);
connect(Request.Method.GET, uri, null, listener, null); connect(Request.Method.GET, uri, null, listener, null);

View file

@ -6,7 +6,6 @@ import android.support.annotation.Nullable;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -15,9 +14,10 @@ public class ImageGetRequest extends ApiRequest {
public static final String QR_CODE_GENERATOR = "/qr/"; public static final String QR_CODE_GENERATOR = "/qr/";
public ImageGetRequest(Context context, URL url, String path, File httpsCertPath, String apiKey, public ImageGetRequest(Context context, URL url, String path, String apiKey,
@Nullable Map<String, String> params, OnImageSuccessListener onSuccessListener, OnErrorListener onErrorListener) { @Nullable Map<String, String> params,
super(context, url, path, httpsCertPath, apiKey); OnImageSuccessListener onSuccessListener, OnErrorListener onErrorListener) {
super(context, url, path, apiKey);
Map<String, String> safeParams = Optional.fromNullable(params).or(Collections.emptyMap()); Map<String, String> safeParams = Optional.fromNullable(params).or(Collections.emptyMap());
Uri uri = buildUri(safeParams); Uri uri = buildUri(safeParams);
makeImageRequest(uri, onSuccessListener, onErrorListener); makeImageRequest(uri, onSuccessListener, onErrorListener);

View file

@ -8,7 +8,6 @@ import android.os.Handler;
import com.android.volley.Request; import com.android.volley.Request;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
@ -26,9 +25,9 @@ public class PollWebGuiAvailableTask extends ApiRequest {
private final OnSuccessListener mListener; private final OnSuccessListener mListener;
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
public PollWebGuiAvailableTask(Context context, URL url, File httpsCertPath, String apiKey, public PollWebGuiAvailableTask(Context context, URL url, String apiKey,
OnSuccessListener listener) { OnSuccessListener listener) {
super(context, url, "", httpsCertPath, apiKey); super(context, url, "", apiKey);
mListener = listener; mListener = listener;
performRequest(); performRequest();
} }

View file

@ -5,7 +5,6 @@ import android.net.Uri;
import com.android.volley.Request; import com.android.volley.Request;
import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
@ -13,9 +12,9 @@ public class PostConfigRequest extends ApiRequest {
private static final String URI_CONFIG = "/rest/system/config"; private static final String URI_CONFIG = "/rest/system/config";
public PostConfigRequest(Context context, URL url, File httpsCertPath, String apiKey, String config, public PostConfigRequest(Context context, URL url, String apiKey, String config,
OnSuccessListener listener) { OnSuccessListener listener) {
super(context, url, URI_CONFIG, httpsCertPath, apiKey); super(context, url, URI_CONFIG, apiKey);
Uri uri = buildUri(Collections.emptyMap()); Uri uri = buildUri(Collections.emptyMap());
connect(Request.Method.POST, uri, config, listener, null); connect(Request.Method.POST, uri, config, listener, null);
} }

View file

@ -6,16 +6,15 @@ import android.net.Uri;
import com.android.volley.Request; import com.android.volley.Request;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.net.URL; import java.net.URL;
public class PostScanRequest extends ApiRequest { public class PostScanRequest extends ApiRequest {
private static final String URI_SCAN = "/rest/db/scan"; private static final String URI_SCAN = "/rest/db/scan";
public PostScanRequest(Context context, URL url, File httpsCertPath, String apiKey, public PostScanRequest(Context context, URL url, String apiKey,
String folder, String sub) { String folder, String sub) {
super(context, url, URI_SCAN, httpsCertPath, apiKey); super(context, url, URI_SCAN, apiKey);
Uri uri = buildUri(ImmutableMap.of("folder", folder, "sub", sub)); Uri uri = buildUri(ImmutableMap.of("folder", folder, "sub", sub));
connect(Request.Method.POST, uri, null, null, null); connect(Request.Method.POST, uri, null, null, null);
} }

View file

@ -0,0 +1,69 @@
package com.nutomic.syncthingandroid.service;
import android.content.Context;
import android.os.Environment;
import java.io.File;
import java.util.concurrent.TimeUnit;
public class Constants {
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_WIFI_SSIDS = "sync_only_wifi_ssids_set";
public static final String PREF_SYNC_ONLY_CHARGING = "sync_only_charging";
public static final String PREF_RESPECT_BATTERY_SAVING = "respect_battery_saving";
public static final String PREF_USE_ROOT = "use_root";
public static final String PREF_NOTIFICATION_TYPE = "notification_type";
public static final String PREF_USE_WAKE_LOCK = "wakelock_while_binary_running";
public static final String PREF_FOREGROUND_SERVICE = "run_as_foreground_service";
/**
* Interval in ms at which the GUI is updated (eg {@link com.nutomic.syncthingandroid.fragments.DrawerFragment}).
*/
public static final long GUI_UPDATE_INTERVAL = TimeUnit.SECONDS.toMillis(5);
/**
* Directory where config is exported to and imported from.
*/
public static final File EXPORT_PATH =
new File(Environment.getExternalStorageDirectory(), "backups/syncthing");
/**
* File in the config folder that contains configuration.
*/
static String CONFIG_FILE = "config.xml";
public static File getConfigFile(Context context) {
return new File(context.getFilesDir(), CONFIG_FILE);
}
/**
* Name of the public key file in the data directory.
*/
static String PUBLIC_KEY_FILE = "cert.pem";
static File getPublicKeyFile(Context context) {
return new File(context.getFilesDir(), PUBLIC_KEY_FILE);
}
/**
* Name of the private key file in the data directory.
*/
static final String PRIVATE_KEY_FILE = "key.pem";
static File getPrivateKeyFile(Context context) {
return new File(context.getFilesDir(), PRIVATE_KEY_FILE);
}
/**
* Name of the public HTTPS CA file in the data directory.
*/
public static File getHttpsCertFile(Context context) {
return new File(context.getFilesDir(), "https-cert.pem");
}
static File getSyncthingBinary(Context context) {
return new File(context.getApplicationInfo().nativeLibraryDir, "libsyncthing.so");
}
}

View file

@ -115,8 +115,8 @@ public class DeviceStateHolder {
return false; return false;
if (SyncthingService.alwaysRunInBackground(mContext)) { if (SyncthingService.alwaysRunInBackground(mContext)) {
boolean prefStopMobileData = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_WIFI, false); boolean prefStopMobileData = mPreferences.getBoolean(Constants.PREF_SYNC_ONLY_WIFI, false);
boolean prefStopNotCharging = mPreferences.getBoolean(SyncthingService.PREF_SYNC_ONLY_CHARGING, false); boolean prefStopNotCharging = mPreferences.getBoolean(Constants.PREF_SYNC_ONLY_CHARGING, false);
if (prefStopMobileData && !isWhitelistedNetworkConnection()) if (prefStopMobileData && !isWhitelistedNetworkConnection())
return false; return false;
@ -131,7 +131,7 @@ public class DeviceStateHolder {
private boolean isWhitelistedNetworkConnection() { private boolean isWhitelistedNetworkConnection() {
boolean wifiConnected = mIsAllowedNetworkConnection; boolean wifiConnected = mIsAllowedNetworkConnection;
if (wifiConnected) { if (wifiConnected) {
Set<String> ssids = mPreferences.getStringSet(SyncthingService.PREF_SYNC_ONLY_WIFI_SSIDS, new HashSet<>()); Set<String> ssids = mPreferences.getStringSet(Constants.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;

View file

@ -35,11 +35,11 @@ public class NotificationHandler {
/** /**
* Shows or hides the persistent notification based on running state and * Shows or hides the persistent notification based on running state and
* {@link SyncthingService#PREF_NOTIFICATION_TYPE}. * {@link Constants#PREF_NOTIFICATION_TYPE}.
*/ */
public void updatePersistentNotification(SyncthingService service, SyncthingService.State currentState) { public void updatePersistentNotification(SyncthingService service, SyncthingService.State currentState) {
String type = mPreferences.getString(SyncthingService.PREF_NOTIFICATION_TYPE, "low_priority"); String type = mPreferences.getString(Constants.PREF_NOTIFICATION_TYPE, "low_priority");
boolean foreground = mPreferences.getBoolean(SyncthingService.PREF_FOREGROUND_SERVICE, false); boolean foreground = mPreferences.getBoolean(Constants.PREF_FOREGROUND_SERVICE, false);
if ("none".equals(type) && foreground) { if ("none".equals(type) && foreground) {
// foreground priority requires any notification // foreground priority requires any notification
// so this ensures that we either have a "default" or "low_priority" notification, // so this ensures that we either have a "default" or "low_priority" notification,

View file

@ -32,7 +32,6 @@ import com.nutomic.syncthingandroid.model.SystemInfo;
import com.nutomic.syncthingandroid.model.SystemVersion; import com.nutomic.syncthingandroid.model.SystemVersion;
import com.nutomic.syncthingandroid.util.FolderObserver; import com.nutomic.syncthingandroid.util.FolderObserver;
import java.io.File;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
@ -78,7 +77,6 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
private final Context mContext; private final Context mContext;
private final URL mUrl; private final URL mUrl;
private final String mApiKey; private final String mApiKey;
private final File mHttpsCertPath;
private String mVersion; private String mVersion;
private Config mConfig; private Config mConfig;
@ -110,7 +108,6 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
mContext = context; mContext = context;
mUrl = url; mUrl = url;
mApiKey = apiKey; mApiKey = apiKey;
mHttpsCertPath = new File(mContext.getFilesDir(), SyncthingService.HTTPS_CERT_FILE);
mOnApiAvailableListener = apiListener; mOnApiAvailableListener = apiListener;
mOnConfigChangedListener = configListener; mOnConfigChangedListener = configListener;
} }
@ -139,13 +136,13 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
@Override @Override
public void onWebGuiAvailable() { public void onWebGuiAvailable() {
mAvailableCount.set(0); mAvailableCount.set(0);
new GetRequest(mContext, mUrl, GetRequest.URI_VERSION, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_VERSION, mApiKey, null, result -> {
JsonObject json = new JsonParser().parse(result).getAsJsonObject(); JsonObject json = new JsonParser().parse(result).getAsJsonObject();
mVersion = json.get("version").getAsString(); mVersion = json.get("version").getAsString();
Log.i(TAG, "Syncthing version is " + mVersion); Log.i(TAG, "Syncthing version is " + mVersion);
tryIsAvailable(); tryIsAvailable();
}); });
new GetRequest(mContext, mUrl, GetRequest.URI_CONFIG, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_CONFIG, mApiKey, null, result -> {
mConfig = new Gson().fromJson(result, Config.class); mConfig = new Gson().fromJson(result, Config.class);
tryIsAvailable(); tryIsAvailable();
}); });
@ -186,14 +183,14 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Sends current config to Syncthing. * Sends current config to Syncthing.
*/ */
private void sendConfig() { private void sendConfig() {
new PostConfigRequest(mContext, mUrl, mHttpsCertPath, mApiKey, new Gson().toJson(mConfig), null); new PostConfigRequest(mContext, mUrl, mApiKey, new Gson().toJson(mConfig), null);
} }
/** /**
* Sends current config and restarts Syncthing. * Sends current config and restarts Syncthing.
*/ */
public void restart() { public void restart() {
new PostConfigRequest(mContext, mUrl, mHttpsCertPath, mApiKey, new Gson().toJson(mConfig), result -> { new PostConfigRequest(mContext, mUrl, mApiKey, new Gson().toJson(mConfig), result -> {
Intent intent = new Intent(mContext, SyncthingService.class) Intent intent = new Intent(mContext, SyncthingService.class)
.setAction(SyncthingService.ACTION_RESTART); .setAction(SyncthingService.ACTION_RESTART);
mContext.startService(intent); mContext.startService(intent);
@ -326,7 +323,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Requests and parses information about current system status and resource usage. * Requests and parses information about current system status and resource usage.
*/ */
public void getSystemInfo(OnResultListener1<SystemInfo> listener) { public void getSystemInfo(OnResultListener1<SystemInfo> listener) {
new GetRequest(mContext, mUrl, GetRequest.URI_SYSTEM, mHttpsCertPath, mApiKey, null, result -> new GetRequest(mContext, mUrl, GetRequest.URI_SYSTEM, mApiKey, null, result ->
listener.onResult(new Gson().fromJson(result, SystemInfo.class))); listener.onResult(new Gson().fromJson(result, SystemInfo.class)));
} }
@ -338,7 +335,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Requests and parses system version information. * Requests and parses system version information.
*/ */
public void getSystemVersion(OnResultListener1<SystemVersion> listener) { public void getSystemVersion(OnResultListener1<SystemVersion> listener) {
new GetRequest(mContext, mUrl, GetRequest.URI_VERSION, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_VERSION, mApiKey, null, result -> {
SystemVersion systemVersion = new Gson().fromJson(result, SystemVersion.class); SystemVersion systemVersion = new Gson().fromJson(result, SystemVersion.class);
listener.onResult(systemVersion); listener.onResult(systemVersion);
}); });
@ -348,10 +345,10 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Returns connection info for the local device and all connected devices. * Returns connection info for the local device and all connected devices.
*/ */
public void getConnections(final OnResultListener1<Connections> listener) { public void getConnections(final OnResultListener1<Connections> listener) {
new GetRequest(mContext, mUrl, GetRequest.URI_CONNECTIONS, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_CONNECTIONS, mApiKey, null, result -> {
Long now = System.currentTimeMillis(); Long now = System.currentTimeMillis();
Long msElapsed = now - mPreviousConnectionTime; Long msElapsed = now - mPreviousConnectionTime;
if (msElapsed < SyncthingService.GUI_UPDATE_INTERVAL) { if (msElapsed < Constants.GUI_UPDATE_INTERVAL) {
listener.onResult(deepCopy(mPreviousConnections.get(), Connections.class)); listener.onResult(deepCopy(mPreviousConnections.get(), Connections.class));
return; return;
} }
@ -411,7 +408,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Returns status information about the folder with the given id. * Returns status information about the folder with the given id.
*/ */
public void getModel(final String folderId, final OnResultListener2<String, Model> listener) { public void getModel(final String folderId, final OnResultListener2<String, Model> listener) {
new GetRequest(mContext, mUrl, GetRequest.URI_MODEL, mHttpsCertPath, mApiKey, new GetRequest(mContext, mUrl, GetRequest.URI_MODEL, mApiKey,
ImmutableMap.of("folder", folderId), result -> { ImmutableMap.of("folder", folderId), result -> {
Model m = new Gson().fromJson(result, Model.class); Model m = new Gson().fromJson(result, Model.class);
mCachedModelInfo.put(folderId, m); mCachedModelInfo.put(folderId, m);
@ -444,7 +441,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
public final void getEvents(final long sinceId, final long limit, final OnReceiveEventListener listener) { public final void getEvents(final long sinceId, final long limit, final OnReceiveEventListener listener) {
Map<String, String> params = Map<String, String> params =
ImmutableMap.of("since", String.valueOf(sinceId), "limit", String.valueOf(limit)); ImmutableMap.of("since", String.valueOf(sinceId), "limit", String.valueOf(limit));
new GetRequest(mContext, mUrl, GetRequest.URI_EVENTS, mHttpsCertPath, mApiKey, params, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_EVENTS, mApiKey, params, result -> {
JsonArray jsonEvents = new JsonParser().parse(result).getAsJsonArray(); JsonArray jsonEvents = new JsonParser().parse(result).getAsJsonArray();
long lastId = 0; long lastId = 0;
@ -467,7 +464,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
*/ */
public void normalizeDeviceId(String id, OnResultListener1<String> listener, public void normalizeDeviceId(String id, OnResultListener1<String> listener,
OnResultListener1<String> errorListener) { OnResultListener1<String> errorListener) {
new GetRequest(mContext, mUrl, GetRequest.URI_DEVICEID, mHttpsCertPath, mApiKey, new GetRequest(mContext, mUrl, GetRequest.URI_DEVICEID, mApiKey,
ImmutableMap.of("id", id), result -> { ImmutableMap.of("id", id), result -> {
JsonObject json = new JsonParser().parse(result).getAsJsonObject(); JsonObject json = new JsonParser().parse(result).getAsJsonObject();
JsonElement normalizedId = json.get("id"); JsonElement normalizedId = json.get("id");
@ -484,14 +481,14 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
*/ */
@Override @Override
public void onFolderFileChange(String folderId, String relativePath) { public void onFolderFileChange(String folderId, String relativePath) {
new PostScanRequest(mContext, mUrl, mHttpsCertPath, mApiKey, folderId, relativePath); new PostScanRequest(mContext, mUrl, mApiKey, folderId, relativePath);
} }
/** /**
* Returns prettyfied usage report. * Returns prettyfied usage report.
*/ */
public void getUsageReport(final OnResultListener1<String> listener) { public void getUsageReport(final OnResultListener1<String> listener) {
new GetRequest(mContext, mUrl, GetRequest.URI_REPORT, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_REPORT, mApiKey, null, result -> {
JsonElement json = new JsonParser().parse(result); JsonElement json = new JsonParser().parse(result);
Gson gson = new GsonBuilder().setPrettyPrinting().create(); Gson gson = new GsonBuilder().setPrettyPrinting().create();
listener.onResult(gson.toJson(json)); listener.onResult(gson.toJson(json));

View file

@ -43,12 +43,11 @@ public class SyncthingRunnable implements Runnable {
private static final String TAG_NATIVE = "SyncthingNativeCode"; private static final String TAG_NATIVE = "SyncthingNativeCode";
private static final String TAG_NICE = "SyncthingRunnableIoNice"; private static final String TAG_NICE = "SyncthingRunnableIoNice";
private static final String TAG_KILL = "SyncthingRunnableKill"; private static final String TAG_KILL = "SyncthingRunnableKill";
private static final String BINARY_NAME = "libsyncthing.so";
private static final int LOG_FILE_MAX_LINES = 10; private static final int LOG_FILE_MAX_LINES = 10;
private static final AtomicReference<Process> mSyncthing = new AtomicReference<>(); private static final AtomicReference<Process> mSyncthing = new AtomicReference<>();
private final Context mContext; private final Context mContext;
private final String mSyncthingBinary; private final File mSyncthingBinary;
private String[] mCommand; private String[] mCommand;
private final File mLogFile; private final File mLogFile;
@Inject SharedPreferences mPreferences; @Inject SharedPreferences mPreferences;
@ -69,18 +68,18 @@ public class SyncthingRunnable implements Runnable {
public SyncthingRunnable(Context context, Command command) { public SyncthingRunnable(Context context, Command command) {
((SyncthingApp) context.getApplicationContext()).component().inject(this); ((SyncthingApp) context.getApplicationContext()).component().inject(this);
mContext = context; mContext = context;
mSyncthingBinary = mContext.getApplicationInfo().nativeLibraryDir + "/" + BINARY_NAME; mSyncthingBinary = Constants.getSyncthingBinary(mContext);
mLogFile = new File(mContext.getExternalFilesDir(null), "syncthing.log"); mLogFile = new File(mContext.getExternalFilesDir(null), "syncthing.log");
mUseRoot = mPreferences.getBoolean(SyncthingService.PREF_USE_ROOT, false) && Shell.SU.available(); mUseRoot = mPreferences.getBoolean(Constants.PREF_USE_ROOT, false) && Shell.SU.available();
switch (command) { switch (command) {
case generate: case generate:
mCommand = new String[]{ mSyncthingBinary, "-generate", mContext.getFilesDir().toString() }; mCommand = new String[]{ mSyncthingBinary.getPath(), "-generate", mContext.getFilesDir().toString() };
break; break;
case main: case main:
mCommand = new String[]{ mSyncthingBinary, "-home", mContext.getFilesDir().toString(), "-no-browser" }; mCommand = new String[]{ mSyncthingBinary.getPath(), "-home", mContext.getFilesDir().toString(), "-no-browser" };
break; break;
case reset: case reset:
mCommand = new String[]{ mSyncthingBinary, "-home", mContext.getFilesDir().toString(), "-reset" }; mCommand = new String[]{ mSyncthingBinary.getPath(), "-home", mContext.getFilesDir().toString(), "-reset" };
break; break;
default: default:
throw new InvalidParameterException("Unknown command option"); throw new InvalidParameterException("Unknown command option");
@ -93,7 +92,7 @@ public class SyncthingRunnable implements Runnable {
int ret; int ret;
// Make sure Syncthing is executable // Make sure Syncthing is executable
try { try {
ProcessBuilder pb = new ProcessBuilder("chmod", "500", mSyncthingBinary); ProcessBuilder pb = new ProcessBuilder("chmod", "500", mSyncthingBinary.getPath());
Process p = pb.start(); Process p = pb.start();
p.waitFor(); p.waitFor();
} catch (IOException|InterruptedException e) { } catch (IOException|InterruptedException e) {
@ -171,7 +170,7 @@ public class SyncthingRunnable implements Runnable {
* Returns true if the experimental setting for using wake locks has been enabled in settings. * Returns true if the experimental setting for using wake locks has been enabled in settings.
*/ */
private boolean useWakeLock() { private boolean useWakeLock() {
return mPreferences.getBoolean(SyncthingService.PREF_USE_WAKE_LOCK, false); return mPreferences.getBoolean(Constants.PREF_USE_WAKE_LOCK, false);
} }
/** /**

View file

@ -9,7 +9,6 @@ import android.content.SharedPreferences;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Environment;
import android.os.IBinder; import android.os.IBinder;
import android.os.PowerManager; import android.os.PowerManager;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -35,7 +34,6 @@ import java.net.URL;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
@ -59,42 +57,6 @@ public class SyncthingService extends Service implements
public static final String ACTION_RESET = public static final String ACTION_RESET =
"com.nutomic.syncthingandroid.service.SyncthingService.RESET"; "com.nutomic.syncthingandroid.service.SyncthingService.RESET";
/**
* Interval in ms at which the GUI is updated (eg {@link com.nutomic.syncthingandroid.fragments.DrawerFragment}).
*/
public static final long GUI_UPDATE_INTERVAL = TimeUnit.SECONDS.toMillis(5);
/**
* name of the public key file in the data directory.
*/
public static final String PUBLIC_KEY_FILE = "cert.pem";
/**
* name of the private key file in the data directory.
*/
public static final String PRIVATE_KEY_FILE = "key.pem";
/**
* name of the public HTTPS CA file in the data directory.
*/
public static final String HTTPS_CERT_FILE = "https-cert.pem";
/**
* Directory where config is exported to and imported from.
*/
public static final File EXPORT_PATH =
new File(Environment.getExternalStorageDirectory(), "backups/syncthing");
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_WIFI_SSIDS = "sync_only_wifi_ssids_set";
public static final String PREF_SYNC_ONLY_CHARGING = "sync_only_charging";
public static final String PREF_RESPECT_BATTERY_SAVING = "respect_battery_saving";
public static final String PREF_USE_ROOT = "use_root";
public static final String PREF_NOTIFICATION_TYPE = "notification_type";
public static final String PREF_USE_WAKE_LOCK = "wakelock_while_binary_running";
public static final String PREF_FOREGROUND_SERVICE = "run_as_foreground_service";
/** /**
* 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.
*/ */
@ -109,9 +71,6 @@ public class SyncthingService extends Service implements
void onApiChange(State currentState); void onApiChange(State currentState);
} }
private final HashSet<OnApiChangeListener> mOnApiChangeListeners =
new HashSet<>();
/** /**
* Indicates the current state of SyncthingService and of Syncthing itself. * Indicates the current state of SyncthingService and of Syncthing itself.
*/ */
@ -131,25 +90,25 @@ public class SyncthingService extends Service implements
private State mCurrentState = State.INIT; private State mCurrentState = State.INIT;
private ConfigXml mConfig; private ConfigXml mConfig;
private RestApi mApi; private RestApi mApi;
private EventProcessor mEventProcessor; private EventProcessor mEventProcessor;
private DeviceStateHolder mDeviceStateHolder;
private SyncthingRunnable mSyncthingRunnable;
private final LinkedList<FolderObserver> mObservers = new LinkedList<>(); private final LinkedList<FolderObserver> mObservers = new LinkedList<>();
private final HashSet<OnApiChangeListener> mOnApiChangeListeners = new HashSet<>();
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this); private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
private final NetworkReceiver mNetworkReceiver = new NetworkReceiver(); private final NetworkReceiver mNetworkReceiver = new NetworkReceiver();
private final BroadcastReceiver mPowerSaveModeChangedReceiver = new PowerSaveModeChangedReceiver(); private final BroadcastReceiver mPowerSaveModeChangedReceiver = new PowerSaveModeChangedReceiver();
@Inject NotificationHandler mNotificationHandler; @Inject NotificationHandler mNotificationHandler;
@Inject SharedPreferences mPreferences;
/** /**
* 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
*/ */
private final Object stateLock = new Object(); private final Object mStateLock = new Object();
/** /**
* True if a stop was requested while syncthing is starting, in that case, perform stop in * True if a stop was requested while syncthing is starting, in that case, perform stop in
@ -157,12 +116,6 @@ public class SyncthingService extends Service implements
*/ */
private boolean mStopScheduled = false; private boolean mStopScheduled = false;
private DeviceStateHolder mDeviceStateHolder;
private SyncthingRunnable mSyncthingRunnable;
@Inject SharedPreferences mPreferences;
/** /**
* Handles intents, either {@link #ACTION_RESTART}, or intents having * Handles intents, either {@link #ACTION_RESTART}, or intents having
* {@link DeviceStateHolder#EXTRA_IS_ALLOWED_NETWORK_CONNECTION} or * {@link DeviceStateHolder#EXTRA_IS_ALLOWED_NETWORK_CONNECTION} or
@ -218,10 +171,10 @@ public class SyncthingService extends Service implements
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(PREF_NOTIFICATION_TYPE) || key.equals(PREF_FOREGROUND_SERVICE)) if (key.equals(Constants.PREF_NOTIFICATION_TYPE) || key.equals(Constants.PREF_FOREGROUND_SERVICE))
mNotificationHandler.updatePersistentNotification(this, mCurrentState); mNotificationHandler.updatePersistentNotification(this, mCurrentState);
else if (key.equals(PREF_SYNC_ONLY_CHARGING) || key.equals(PREF_SYNC_ONLY_WIFI) else if (key.equals(Constants.PREF_SYNC_ONLY_CHARGING) || key.equals(Constants.PREF_SYNC_ONLY_WIFI)
|| key.equals(PREF_SYNC_ONLY_WIFI_SSIDS) || key.equals(PREF_RESPECT_BATTERY_SAVING)) { || key.equals(Constants.PREF_SYNC_ONLY_WIFI_SSIDS) || key.equals(Constants.PREF_RESPECT_BATTERY_SAVING)) {
updateState(); updateState();
} }
} }
@ -328,7 +281,7 @@ public class SyncthingService extends Service implements
@Override @Override
public void onDestroy() { public void onDestroy() {
synchronized (stateLock) { synchronized (mStateLock) {
if (mCurrentState == State.INIT || mCurrentState == State.STARTING) { if (mCurrentState == State.INIT || mCurrentState == State.STARTING) {
Log.i(TAG, "Delay shutting down service until initialisation of Syncthing finished"); Log.i(TAG, "Delay shutting down service until initialisation of Syncthing finished");
mStopScheduled = true; mStopScheduled = true;
@ -424,9 +377,8 @@ public class SyncthingService extends Service implements
* for SyncthingService.onDestroy for details. * for SyncthingService.onDestroy for details.
*/ */
private void pollWebGui() { private void pollWebGui() {
new PollWebGuiAvailableTask(this, getWebGuiUrl(), new File(getFilesDir(), HTTPS_CERT_FILE), new PollWebGuiAvailableTask(this, getWebGuiUrl(), mConfig.getApiKey(), result -> {
mConfig.getApiKey(), result -> { synchronized (mStateLock) {
synchronized (stateLock) {
if (mStopScheduled) { if (mStopScheduled) {
shutdown(State.DISABLED, () -> {}); shutdown(State.DISABLED, () -> {});
mStopScheduled = false; mStopScheduled = false;
@ -469,42 +421,42 @@ public class SyncthingService extends Service implements
*/ */
public static boolean alwaysRunInBackground(Context context) { public static boolean alwaysRunInBackground(Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
return sp.getBoolean(PREF_ALWAYS_RUN_IN_BACKGROUND, false); return sp.getBoolean(Constants.PREF_ALWAYS_RUN_IN_BACKGROUND, false);
} }
/** /**
* Exports the local config and keys to {@link #EXPORT_PATH}. * Exports the local config and keys to {@link Constants#EXPORT_PATH}.
*/ */
public void exportConfig() { public void exportConfig() {
EXPORT_PATH.mkdirs(); Constants.EXPORT_PATH.mkdirs();
try { try {
Files.copy(new File(getFilesDir(), ConfigXml.CONFIG_FILE), Files.copy(Constants.getConfigFile(this),
new File(EXPORT_PATH, ConfigXml.CONFIG_FILE)); new File(Constants.EXPORT_PATH, Constants.CONFIG_FILE));
Files.copy(new File(getFilesDir(), PRIVATE_KEY_FILE), Files.copy(Constants.getPrivateKeyFile(this),
new File(EXPORT_PATH, PRIVATE_KEY_FILE)); new File(Constants.EXPORT_PATH, Constants.PRIVATE_KEY_FILE));
Files.copy(new File(getFilesDir(), PUBLIC_KEY_FILE), Files.copy(Constants.getPublicKeyFile(this),
new File(EXPORT_PATH, PUBLIC_KEY_FILE)); new File(Constants.EXPORT_PATH, Constants.PUBLIC_KEY_FILE));
} catch (IOException e) { } catch (IOException e) {
Log.w(TAG, "Failed to export config", e); Log.w(TAG, "Failed to export config", e);
} }
} }
/** /**
* Imports config and keys from {@link #EXPORT_PATH}. * Imports config and keys from {@link Constants#EXPORT_PATH}.
* *
* @return True if the import was successful, false otherwise (eg if files aren't found). * @return True if the import was successful, false otherwise (eg if files aren't found).
*/ */
public boolean importConfig() { public boolean importConfig() {
File config = new File(EXPORT_PATH, ConfigXml.CONFIG_FILE); File config = new File(Constants.EXPORT_PATH, Constants.CONFIG_FILE);
File privateKey = new File(EXPORT_PATH, PRIVATE_KEY_FILE); File privateKey = new File(Constants.EXPORT_PATH, Constants.PRIVATE_KEY_FILE);
File publicKey = new File(EXPORT_PATH, PUBLIC_KEY_FILE); File publicKey = new File(Constants.EXPORT_PATH, Constants.PUBLIC_KEY_FILE);
if (!config.exists() || !privateKey.exists() || !publicKey.exists()) if (!config.exists() || !privateKey.exists() || !publicKey.exists())
return false; return false;
shutdown(State.INIT, () -> { shutdown(State.INIT, () -> {
try { try {
Files.copy(config, new File(getFilesDir(), ConfigXml.CONFIG_FILE)); Files.copy(config, Constants.getConfigFile(this));
Files.copy(privateKey, new File(getFilesDir(), PRIVATE_KEY_FILE)); Files.copy(privateKey, Constants.getPrivateKeyFile(this));
Files.copy(publicKey, new File(getFilesDir(), PUBLIC_KEY_FILE)); Files.copy(publicKey, Constants.getPublicKeyFile(this));
} catch (IOException e) { } catch (IOException e) {
Log.w(TAG, "Failed to import config", e); Log.w(TAG, "Failed to import config", e);
} }

View file

@ -7,6 +7,7 @@ import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.SyncthingRunnable; import com.nutomic.syncthingandroid.service.SyncthingRunnable;
import org.mindrot.jbcrypt.BCrypt; import org.mindrot.jbcrypt.BCrypt;
@ -43,11 +44,6 @@ public class ConfigXml {
private static final String TAG = "ConfigXml"; private static final String TAG = "ConfigXml";
/**
* File in the config folder that contains configuration.
*/
public static final String CONFIG_FILE = "config.xml";
private final Context mContext; private final Context mContext;
private final File mConfigFile; private final File mConfigFile;
@ -56,7 +52,7 @@ public class ConfigXml {
public ConfigXml(Context context) throws OpenConfigException { public ConfigXml(Context context) throws OpenConfigException {
mContext = context; mContext = context;
mConfigFile = getConfigFile(context); mConfigFile = Constants.getConfigFile(mContext);
boolean isFirstStart = !mConfigFile.exists(); boolean isFirstStart = !mConfigFile.exists();
if (isFirstStart) { if (isFirstStart) {
Log.i(TAG, "App started for the first time. Generating keys and config."); Log.i(TAG, "App started for the first time. Generating keys and config.");
@ -89,10 +85,6 @@ public class ConfigXml {
new SyncthingRunnable(context, SyncthingRunnable.Command.generate).run(); new SyncthingRunnable(context, SyncthingRunnable.Command.generate).run();
} }
public static File getConfigFile(Context context) {
return new File(context.getFilesDir(), CONFIG_FILE);
}
public URL getWebGuiUrl() { public URL getWebGuiUrl() {
try { try {
return new URL("https://" + getGuiElement().getElementsByTagName("address").item(0).getTextContent()); return new URL("https://" + getGuiElement().getElementsByTagName("address").item(0).getTextContent());