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