1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
package com.wireguard.android;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import com.wireguard.config.Config;
/**
* Activity that allows creating/viewing/editing/deleting WireGuard configurations.
*/
public class ConfigActivity extends BaseConfigActivity {
private boolean canAddFragments;
private int containerId;
private final FragmentManager fm = getFragmentManager();
private boolean isEditing;
private boolean isSplitLayout;
@Override
public void onBackPressed() {
super.onBackPressed();
// Make sure the current config is cleared when going back to the list.
if (isEditing)
isEditing = false;
else
setCurrentConfig(null);
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.config_activity);
isSplitLayout = findViewById(R.id.detail_fragment) != null;
if (isSplitLayout)
containerId = R.id.detail_fragment;
else
containerId = R.id.master_fragment;
}
@Override
protected void onCurrentConfigChanged(final Config config) {
if (!canAddFragments)
return;
final Fragment currentFragment = fm.findFragmentById(containerId);
Log.d(getClass().getSimpleName(), "onCurrentConfigChanged config=" +
(config != null ? config.getName() : null) + " fragment=" + currentFragment);
if (currentFragment instanceof ConfigDetailFragment) {
// Handle the case when the split layout is switching from one config to another.
final ConfigDetailFragment detailFragment = (ConfigDetailFragment) currentFragment;
if (detailFragment.getCurrentConfig() != config)
detailFragment.setCurrentConfig(config);
} else if (currentFragment instanceof ConfigEditFragment) {
// Handle the case when ConfigEditFragment is finished updating a config.
fm.popBackStack();
isEditing = false;
final ConfigDetailFragment detailFragment =
(ConfigDetailFragment) fm.findFragmentByTag(TAG_DETAIL);
if (detailFragment.getCurrentConfig() != config)
detailFragment.setCurrentConfig(config);
} else if (config != null) {
// Handle the single-fragment-layout case and the case when a placeholder is replaced.
ConfigDetailFragment detailFragment =
(ConfigDetailFragment) fm.findFragmentByTag(TAG_DETAIL);
if (detailFragment != null) {
detailFragment.setCurrentConfig(config);
} else {
detailFragment = new ConfigDetailFragment();
final Bundle arguments = new Bundle();
arguments.putString(KEY_CURRENT_CONFIG, config.getName());
detailFragment.setArguments(arguments);
}
final FragmentTransaction transaction = fm.beginTransaction();
if (!isSplitLayout)
transaction.addToBackStack(TAG_DETAIL);
transaction.replace(containerId, detailFragment, TAG_DETAIL);
transaction.commit();
} else {
if (isSplitLayout) {
// Handle the split layout case when there is no config, so a placeholder is shown.
PlaceholderFragment placeholderFragment =
(PlaceholderFragment) fm.findFragmentByTag(TAG_PLACEHOLDER);
if (placeholderFragment == null)
placeholderFragment = new PlaceholderFragment();
final FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(containerId, placeholderFragment, TAG_PLACEHOLDER);
transaction.commit();
}
}
// If the config change came from the intent or ConfigEditFragment, forward it to the list.
ConfigListFragment listFragment = (ConfigListFragment) fm.findFragmentByTag(TAG_LIST);
if (listFragment == null) {
listFragment = new ConfigListFragment();
final FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.master_fragment, listFragment, TAG_LIST);
transaction.commit();
}
if (listFragment.getCurrentConfig() != config)
listFragment.setCurrentConfig(config);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_action_edit:
ConfigEditFragment editFragment =
(ConfigEditFragment) fm.findFragmentByTag(TAG_EDIT);
if (editFragment != null) {
editFragment.setCurrentConfig(getCurrentConfig());
} else {
editFragment = new ConfigEditFragment();
final Bundle arguments = new Bundle();
arguments.putString(KEY_CURRENT_CONFIG, getCurrentConfig().getName());
editFragment.setArguments(arguments);
}
final FragmentTransaction transaction = fm.beginTransaction();
transaction.addToBackStack(TAG_EDIT);
transaction.replace(containerId, editFragment, TAG_EDIT);
transaction.commit();
isEditing = true;
return true;
case R.id.menu_action_save:
// This menu item is handled by the current fragment.
return false;
case R.id.menu_settings:
startActivity(new Intent(this, SettingsActivity.class));
return true;
default:
return false;
}
}
@Override
public void onSaveInstanceState(final Bundle outState) {
// We cannot save fragments that might switch between containers if the layout changes.
if (fm.getBackStackEntryCount() > 0) {
final int bottomEntryId = fm.getBackStackEntryAt(0).getId();
fm.popBackStackImmediate(bottomEntryId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
if (isSplitLayout) {
final Fragment oldFragment = fm.findFragmentById(containerId);
if (oldFragment != null)
fm.beginTransaction().remove(oldFragment).commit();
}
super.onSaveInstanceState(outState);
}
@Override
protected void onServiceAvailable() {
// Create the initial fragment set.
canAddFragments = true;
onCurrentConfigChanged(getCurrentConfig());
}
}
|