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:
parent
4c2b325676
commit
1fd86211dc
18 changed files with 164 additions and 165 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in a new issue