ConfigEditFragment: Save and restore editor state properly
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
f83c84ce4e
commit
e2df9931ac
@ -1,5 +1,6 @@
|
|||||||
package com.wireguard.android;
|
package com.wireguard.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -19,16 +20,38 @@ import com.wireguard.config.Config;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class ConfigEditFragment extends BaseConfigFragment {
|
public class ConfigEditFragment extends BaseConfigFragment {
|
||||||
private final Config localConfig = new Config();
|
private static final String KEY_MODIFIED_CONFIG = "modifiedConfig";
|
||||||
|
private static final String KEY_ORIGINAL_NAME = "originalName";
|
||||||
|
|
||||||
|
private Config localConfig;
|
||||||
|
private String originalName;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCurrentConfigChanged(final Config config) {
|
protected void onCurrentConfigChanged(final Config config) {
|
||||||
|
// Only discard modifications when the config *they are based on* changes.
|
||||||
|
if (config == null || config.getName().equals(originalName) || localConfig == null)
|
||||||
|
return;
|
||||||
localConfig.copyFrom(config);
|
localConfig.copyFrom(config);
|
||||||
|
originalName = config.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(final Bundle savedInstanceState) {
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
// Restore more saved information.
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
localConfig = savedInstanceState.getParcelable(KEY_MODIFIED_CONFIG);
|
||||||
|
originalName = savedInstanceState.getString(KEY_ORIGINAL_NAME);
|
||||||
|
} else if (getArguments() != null) {
|
||||||
|
final Bundle arguments = getArguments();
|
||||||
|
localConfig = arguments.getParcelable(KEY_MODIFIED_CONFIG);
|
||||||
|
originalName = arguments.getString(KEY_ORIGINAL_NAME);
|
||||||
|
}
|
||||||
|
if (localConfig == null) {
|
||||||
|
localConfig = new Config();
|
||||||
|
originalName = null;
|
||||||
|
}
|
||||||
|
onCurrentConfigChanged(getCurrentConfig());
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +69,14 @@ public class ConfigEditFragment extends BaseConfigFragment {
|
|||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
// Reset changes to the config when the user cancels editing. See also the comment below.
|
||||||
|
if (isRemoving())
|
||||||
|
localConfig.copyFrom(getCurrentConfig());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
@ -53,27 +84,38 @@ public class ConfigEditFragment extends BaseConfigFragment {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(final Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
// When ConfigActivity unwinds the back stack, isRemoving() is true, so localConfig will be
|
||||||
|
// reset. Since outState is not serialized yet, it resets the saved config too. Avoid this
|
||||||
|
// by copying the local config. originalName is fine because it is replaced, not modified.
|
||||||
|
outState.putParcelable(KEY_MODIFIED_CONFIG, localConfig.copy());
|
||||||
|
outState.putString(KEY_ORIGINAL_NAME, originalName);
|
||||||
|
}
|
||||||
|
|
||||||
private void saveConfig() {
|
private void saveConfig() {
|
||||||
final String errorMessage = localConfig.validate();
|
final String errorMessage = localConfig.validate();
|
||||||
|
final VpnService service = VpnService.getInstance();
|
||||||
if (errorMessage != null) {
|
if (errorMessage != null) {
|
||||||
Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (getCurrentConfig() != null)
|
if (getCurrentConfig() != null)
|
||||||
VpnService.getInstance().update(getCurrentConfig().getName(), localConfig);
|
service.update(getCurrentConfig().getName(), localConfig);
|
||||||
else
|
else
|
||||||
VpnService.getInstance().add(localConfig);
|
service.add(localConfig);
|
||||||
} catch (final IllegalStateException e) {
|
} catch (final IllegalStateException e) {
|
||||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Hide the keyboard; it rarely goes away on its own.
|
// Hide the keyboard; it rarely goes away on its own.
|
||||||
final BaseConfigActivity activity = (BaseConfigActivity) getActivity();
|
final Activity activity = getActivity();
|
||||||
final View focusedView = activity.getCurrentFocus();
|
final View focusedView = activity.getCurrentFocus();
|
||||||
if (focusedView != null) {
|
if (focusedView != null) {
|
||||||
final InputMethodManager inputManager =
|
final InputMethodManager inputManager =
|
||||||
@ -82,6 +124,6 @@ public class ConfigEditFragment extends BaseConfigFragment {
|
|||||||
InputMethodManager.HIDE_NOT_ALWAYS);
|
InputMethodManager.HIDE_NOT_ALWAYS);
|
||||||
}
|
}
|
||||||
// Tell the activity to finish itself or go back to the detail view.
|
// Tell the activity to finish itself or go back to the detail view.
|
||||||
activity.setCurrentConfig(localConfig);
|
((BaseConfigActivity) activity).setIsEditing(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user