diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceSettingsFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceSettingsFragment.java index f32a2404..ac24d8dd 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceSettingsFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceSettingsFragment.java @@ -131,7 +131,7 @@ public class DeviceSettingsFragment extends PreferenceFragment implements getActivity().setTitle(R.string.add_device); } else { getActivity().setTitle(R.string.edit_device); - List devices = mSyncthingService.getApi().getDevices(); + List devices = mSyncthingService.getApi().getDevices(false); for (int i = 0; i < devices.size(); i++) { if (devices.get(i).DeviceID.equals( getActivity().getIntent().getStringExtra(EXTRA_NODE_ID))) { diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/DevicesFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/DevicesFragment.java index 3eb9a8a5..e9aaf49f 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/DevicesFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/DevicesFragment.java @@ -54,7 +54,7 @@ public class DevicesFragment extends ListFragment implements SyncthingService.On return; mAdapter = new DevicesAdapter(activity); - mAdapter.add(activity.getApi().getDevices()); + mAdapter.add(activity.getApi().getDevices(false)); setListAdapter(mAdapter); setEmptyText(getString(R.string.devices_list_empty)); getListView().setOnItemClickListener(this); diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderSettingsFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderSettingsFragment.java index f10019d1..afa1329f 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderSettingsFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderSettingsFragment.java @@ -148,7 +148,7 @@ public class FolderSettingsFragment extends PreferenceFragment mRescanInterval.setText(Integer.toString(mFolder.RescanIntervalS)); mRescanInterval.setSummary(Integer.toString(mFolder.RescanIntervalS)); mFolderMaster.setChecked(mFolder.ReadOnly); - List devicesList = mSyncthingService.getApi().getDevices(); + List devicesList = mSyncthingService.getApi().getDevices(false); for (RestApi.Device n : devicesList) { ExtendedCheckBoxPreference cbp = new ExtendedCheckBoxPreference(getActivity(), n); // Calling addPreference later causes it to change the checked state. @@ -297,7 +297,8 @@ public class FolderSettingsFragment extends PreferenceFragment intent.putExtra(FolderPickerActivity.EXTRA_INITIAL_DIRECTORY, mFolder.Path); } startActivityForResult(intent, DIRECTORY_REQUEST_CODE); - } else if (preference.equals(mDevices) && mSyncthingService.getApi().getDevices().isEmpty()) { + } else if (preference.equals(mDevices) && + mSyncthingService.getApi().getDevices(false).isEmpty()) { Toast.makeText(getActivity(), R.string.no_devices, Toast.LENGTH_SHORT) .show(); } diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/SettingsFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/SettingsFragment.java index 405869f4..5d8ffd0a 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/SettingsFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/SettingsFragment.java @@ -1,6 +1,5 @@ package com.nutomic.syncthingandroid.fragments; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.preference.CheckBoxPreference; @@ -29,6 +28,10 @@ public class SettingsFragment extends PreferenceFragment private static final String SYNCTHING_GUI_KEY = "syncthing_gui"; + private static final String DEVICE_NAME_KEY = "DeviceName"; + + private static final String USAGE_REPORT_ACCEPTED = "URAccepted"; + private static final String SYNCTHING_VERSION_KEY = "syncthing_version"; private static final String APP_VERSION_KEY = "app_version"; @@ -52,21 +55,33 @@ public class SettingsFragment extends PreferenceFragment Preference syncthingVersion = getPreferenceScreen().findPreference(SYNCTHING_VERSION_KEY); syncthingVersion.setSummary(mSyncthingService.getApi().getVersion()); + RestApi api = mSyncthingService.getApi(); if (currentState == SyncthingService.State.ACTIVE) { for (int i = 0; i < mOptionsScreen.getPreferenceCount(); i++) { - Preference pref = mOptionsScreen.getPreference(i); + final Preference pref = mOptionsScreen.getPreference(i); pref.setOnPreferenceChangeListener(SettingsFragment.this); - String value = mSyncthingService.getApi() - .getValue(RestApi.TYPE_OPTIONS, pref.getKey()); + String value; + switch (pref.getKey()) { + case DEVICE_NAME_KEY: + value = api.getLocalDevice().Name; + break; + case USAGE_REPORT_ACCEPTED: + String v = api.getValue(RestApi.TYPE_OPTIONS, pref.getKey()); + value = (v.equals("1")) ? "true" : "false"; + break; + default: + value = api.getValue(RestApi.TYPE_OPTIONS, pref.getKey()); + + + } applyPreference(pref, value); } for (int i = 0; i < mGuiScreen.getPreferenceCount(); i++) { Preference pref = mGuiScreen.getPreference(i); pref.setOnPreferenceChangeListener(SettingsFragment.this); - String value = mSyncthingService.getApi() - .getValue(RestApi.TYPE_GUI, pref.getKey()); + String value = api.getValue(RestApi.TYPE_GUI, pref.getKey()); applyPreference(pref, value); } } @@ -170,9 +185,23 @@ public class SettingsFragment extends PreferenceFragment mSyncOnlyCharging.setEnabled((Boolean) o); mSyncOnlyWifi.setEnabled((Boolean) o); + } else if (preference.getKey().equals(DEVICE_NAME_KEY)) { + RestApi.Device old = mSyncthingService.getApi().getLocalDevice(); + RestApi.Device updated = new RestApi.Device(); + updated.Addresses = old.Addresses; + updated.Compression = old.Compression; + updated.DeviceID = old.DeviceID; + updated.Introducer = old.Introducer; + updated.Name = (String) o; + mSyncthingService.getApi().editDevice(updated, getActivity(), null); + } else if (preference.getKey().equals(USAGE_REPORT_ACCEPTED)) { + mSyncthingService.getApi().setValue(RestApi.TYPE_OPTIONS, preference.getKey(), + ((Boolean) o) ? 1 : 0, false, getActivity()); } else if (mOptionsScreen.findPreference(preference.getKey()) != null) { + boolean isArray = preference.getKey().equals("ListenAddress") || + preference.getKey().equals("GlobalAnnServers"); mSyncthingService.getApi().setValue(RestApi.TYPE_OPTIONS, preference.getKey(), o, - preference.getKey().equals("ListenAddress"), getActivity()); + isArray, getActivity()); } else if (mGuiScreen.findPreference(preference.getKey()) != null) { mSyncthingService.getApi().setValue( RestApi.TYPE_GUI, preference.getKey(), o, false, getActivity()); diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java index 4dd9a6e3..1ef04562 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java @@ -25,7 +25,6 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.Serializable; -import java.security.InvalidParameterException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; @@ -288,8 +287,8 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, try { Object value = mConfig.getJSONObject(name).get(key); return (value instanceof JSONArray) - ? ((JSONArray) value).join(" ").replace("\"", "") - : String.valueOf(value); + ? ((JSONArray) value).join(" ").replace("\"", "").replace("\\", "") + : value.toString(); } catch (JSONException e) { Log.w(TAG, "Failed to get value for " + key, e); return null; @@ -392,13 +391,29 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, /** * Returns a list of all existing devices. + * + * @param includeLocal True if the local device should be included in the result. */ - public List getDevices() { + public List getDevices(boolean includeLocal) { if (mConfig == null) return new ArrayList<>(); try { - return getDevices(mConfig.getJSONArray("Devices")); + JSONArray devices = mConfig.getJSONArray("Devices"); + List ret = new ArrayList<>(devices.length()); + for (int i = 0; i < devices.length(); i++) { + JSONObject json = devices.getJSONObject(i); + Device n = new Device(); + n.Addresses = json.optJSONArray("Addresses").join(" ").replace("\"", ""); + n.Name = json.getString("Name"); + n.DeviceID = json.getString("DeviceID"); + n.Compression = json.getBoolean("Compression"); + n.Introducer = json.getBoolean("Introducer"); + if (includeLocal || !mLocalDeviceId.equals(n.DeviceID)) { + ret.add(n); + } + } + return ret; } catch (JSONException e) { Log.w(TAG, "Failed to read devices", e); return null; @@ -429,13 +444,14 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, SystemInfo si = new SystemInfo(); si.alloc = system.getLong("alloc"); si.cpuPercent = system.getDouble("cpuPercent"); - JSONObject announce = system.getJSONObject("extAnnounceOK"); - si.extAnnounceConnected = 0; - si.extAnnounceTotal = announce.length(); - for (Iterator it = announce.keys(); it.hasNext(); ) { - String key = it.next(); - if (announce.getBoolean(key)) { - si.extAnnounceConnected++; + if (system.has("extAnnounceOK")) { + JSONObject announce = system.getJSONObject("extAnnounceOK"); + si.extAnnounceTotal = announce.length(); + for (Iterator it = announce.keys(); it.hasNext(); ) { + String key = it.next(); + if (announce.getBoolean(key)) { + si.extAnnounceConnected++; + } } } si.goroutines = system.getInt("goroutines"); @@ -450,27 +466,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, } /** - * Returns a list of all devices in the array devices, excluding the local device. - */ - private List getDevices(JSONArray devices) throws JSONException { - List ret = new ArrayList<>(devices.length()); - for (int i = 0; i < devices.length(); i++) { - JSONObject json = devices.getJSONObject(i); - Device n = new Device(); - n.Addresses = json.optJSONArray("Addresses").join(" ").replace("\"", ""); - n.Name = json.getString("Name"); - n.DeviceID = json.getString("DeviceID"); - n.Compression = json.getBoolean("Compression"); - n.Introducer = json.getBoolean("Introducer"); - if (!n.DeviceID.equals(mLocalDeviceId)) { - ret.add(n); - } - } - return ret; - } - - /** - * Returns a list of all existing foldersitores. + * Returns a list of all existing folders. */ public List getFolders() { if (mConfig == null) @@ -700,8 +696,8 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, /** * Updates or creates the given device, depending on whether it already exists. * - * @param device Settings of the device to edit. To create a device, pass a non-existant device ID. - * @param listener {@link OnDeviceIdNormalizedListener} for the normalized device ID. + * @param device Settings of the device to edit. To create a device, pass a non-existant device ID. + * @param listener for the normalized device ID (may be null). */ public void editDevice(final Device device, final Activity activity, final OnDeviceIdNormalizedListener listener) { @@ -709,14 +705,14 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, new RestApi.OnDeviceIdNormalizedListener() { @Override public void onDeviceIdNormalized(String normalizedId, String error) { - listener.onDeviceIdNormalized(normalizedId, error); + if (listener != null) listener.onDeviceIdNormalized(normalizedId, error); if (normalizedId == null) return; device.DeviceID = normalizedId; // If the device already exists, just update it. boolean create = true; - for (RestApi.Device n : getDevices()) { + for (RestApi.Device n : getDevices(true)) { if (n.DeviceID.equals(device.DeviceID)) { create = false; } @@ -935,4 +931,16 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, relativePath); } + /** + * Returns the object representing the local device. + */ + public Device getLocalDevice() { + for (Device d : getDevices(true)) { + if (d.DeviceID.equals(mLocalDeviceId)) { + return d; + } + } + return new Device(); + } + } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 7af3019a..8b41d3e8 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -218,26 +218,24 @@ Please report any problems you encounter via Github. Syncthing Options + Device Name + Sync Protocol Listen Addresses Incoming Rate Limit (KiB/s) Outgoing Rate Limit (KiB/s) - Reconnect Interval (s) - - Max Outstanding Requests - - Max File Change Rate (KiB/s) - Global Discovery Local Discovery - Local Discovery Port - Enable UPnP + Global Discovery Server + + Anonymous Usage Reporting + Syncthing GUI GUI Listen Addresses diff --git a/src/main/res/xml/app_settings.xml b/src/main/res/xml/app_settings.xml index 6af841ee..09291a95 100644 --- a/src/main/res/xml/app_settings.xml +++ b/src/main/res/xml/app_settings.xml @@ -26,10 +26,13 @@ android:title="@string/syncthing_options" android:persistent="false"> + + + android:title="@string/listen_address" /> - - - - - - @@ -64,15 +52,18 @@ android:key="LocalAnnEnabled" android:title="@string/local_announce_enabled" /> - - + + + +