[UI/MM] agregar Maintentance Mode para administrar la puerta del Walled Garden
This commit is contained in:
parent
33dc5c910b
commit
9348fe438a
|
|
@ -78,6 +78,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
private CheckBox checkbox_udp_in_tcp;
|
private CheckBox checkbox_udp_in_tcp;
|
||||||
private CheckBox checkbox_remote_dns;
|
private CheckBox checkbox_remote_dns;
|
||||||
private CheckBox checkbox_global;
|
private CheckBox checkbox_global;
|
||||||
|
private CheckBox checkbox_maintenance;
|
||||||
private CheckBox checkbox_ipv4;
|
private CheckBox checkbox_ipv4;
|
||||||
private CheckBox checkbox_ipv6;
|
private CheckBox checkbox_ipv6;
|
||||||
private Button button_apps;
|
private Button button_apps;
|
||||||
|
|
@ -170,6 +171,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
checkbox_global = findViewById(R.id.global);
|
checkbox_global = findViewById(R.id.global);
|
||||||
checkbox_udp_in_tcp = findViewById(R.id.udp_in_tcp);
|
checkbox_udp_in_tcp = findViewById(R.id.udp_in_tcp);
|
||||||
checkbox_remote_dns = findViewById(R.id.remote_dns);
|
checkbox_remote_dns = findViewById(R.id.remote_dns);
|
||||||
|
checkbox_maintenance = findViewById(R.id.checkbox_maintenance);
|
||||||
|
checkbox_maintenance.setOnClickListener(this);
|
||||||
button_apps = findViewById(R.id.apps);
|
button_apps = findViewById(R.id.apps);
|
||||||
button_save = findViewById(R.id.save);
|
button_save = findViewById(R.id.save);
|
||||||
button_control = findViewById(R.id.control);
|
button_control = findViewById(R.id.control);
|
||||||
|
|
@ -196,7 +199,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
btnClearLog.setOnClickListener(this);
|
btnClearLog.setOnClickListener(this);
|
||||||
btnCopyLog.setOnClickListener(this);
|
btnCopyLog.setOnClickListener(this);
|
||||||
themeToggle.setOnClickListener(v -> toggleTheme());
|
themeToggle.setOnClickListener(v -> toggleTheme());
|
||||||
configLabel.setOnClickListener(v -> toggleVisibility(configLayout, configLabel, getString(R.string.configuration_label)));
|
configLabel.setOnClickListener(v -> handleConfigToggle());
|
||||||
advConfigLabel.setOnClickListener(v -> toggleVisibility(advancedConfig, advConfigLabel, getString(R.string.advanced_settings_label)));
|
advConfigLabel.setOnClickListener(v -> toggleVisibility(advancedConfig, advConfigLabel, getString(R.string.advanced_settings_label)));
|
||||||
logLabel.setOnClickListener(v -> handleLogToggle());
|
logLabel.setOnClickListener(v -> handleLogToggle());
|
||||||
checkbox_udp_in_tcp.setOnClickListener(this);
|
checkbox_udp_in_tcp.setOnClickListener(this);
|
||||||
|
|
@ -525,7 +528,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (view == checkbox_global || view == checkbox_remote_dns) {
|
if (view == checkbox_global || view == checkbox_remote_dns || view == checkbox_maintenance) {
|
||||||
savePrefs();
|
savePrefs();
|
||||||
updateUI();
|
updateUI();
|
||||||
} else if (view == button_apps) {
|
} else if (view == button_apps) {
|
||||||
|
|
@ -571,8 +574,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleWatchdogClick() {
|
private void handleWatchdogClick() {
|
||||||
if (prefs.getWatchdogEnable()) showWatchdogBiometricPrompt();
|
// if (prefs.getWatchdogEnable()) showWatchdogBiometricPrompt();
|
||||||
else toggleWatchdog(false);
|
// else toggleWatchdog(false);
|
||||||
|
toggleWatchdog(prefs.getWatchdogEnable());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleWatchdog(boolean stop) {
|
private void toggleWatchdog(boolean stop) {
|
||||||
|
|
@ -629,6 +633,53 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
bp.authenticate(new BiometricPrompt.PromptInfo.Builder().setTitle(getString(R.string.auth_required_title)).setSubtitle(getString(R.string.auth_required_subtitle)).setAllowedAuthenticators(auth).build());
|
bp.authenticate(new BiometricPrompt.PromptInfo.Builder().setTitle(getString(R.string.auth_required_title)).setSubtitle(getString(R.string.auth_required_subtitle)).setAllowedAuthenticators(auth).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Secure Advanced Settings Menu ---
|
||||||
|
private void handleConfigToggle() {
|
||||||
|
if (configLayout.getVisibility() == View.GONE) {
|
||||||
|
// The menu is closed. We want to open it, so we check for security first.
|
||||||
|
BiometricManager bm = BiometricManager.from(this);
|
||||||
|
int auth = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||||
|
auth = BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||||
|
}
|
||||||
|
android.app.KeyguardManager km = (android.app.KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
|
||||||
|
|
||||||
|
if (bm.canAuthenticate(auth) == BiometricManager.BIOMETRIC_SUCCESS || (km != null && km.isDeviceSecure())) {
|
||||||
|
showConfigBiometricPrompt();
|
||||||
|
} else {
|
||||||
|
showEnrollmentDialog(); // Forces user to set a PIN if device has no security
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The menu is open. Just close it without asking for fingerprint.
|
||||||
|
toggleVisibility(configLayout, configLabel, getString(R.string.advanced_settings_label));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showConfigBiometricPrompt() {
|
||||||
|
Executor ex = ContextCompat.getMainExecutor(this);
|
||||||
|
BiometricPrompt bp = new BiometricPrompt(this, ex, new BiometricPrompt.AuthenticationCallback() {
|
||||||
|
@Override
|
||||||
|
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
|
||||||
|
super.onAuthenticationSucceeded(result);
|
||||||
|
// Auth successful! Open the menu.
|
||||||
|
toggleVisibility(configLayout, configLabel, getString(R.string.advanced_settings_label));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int auth = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||||
|
auth = BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reusing your existing strings to avoid compilation errors
|
||||||
|
bp.authenticate(new BiometricPrompt.PromptInfo.Builder()
|
||||||
|
.setTitle(getString(R.string.auth_required_title))
|
||||||
|
.setSubtitle(getString(R.string.auth_required_subtitle))
|
||||||
|
.setAllowedAuthenticators(auth)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
// ------------------------------------------------
|
||||||
|
|
||||||
private void showWatchdogBiometricPrompt() {
|
private void showWatchdogBiometricPrompt() {
|
||||||
Executor ex = ContextCompat.getMainExecutor(this);
|
Executor ex = ContextCompat.getMainExecutor(this);
|
||||||
BiometricPrompt bp = new BiometricPrompt(this, new BiometricPrompt.AuthenticationCallback() {
|
BiometricPrompt bp = new BiometricPrompt(this, new BiometricPrompt.AuthenticationCallback() {
|
||||||
|
|
@ -685,25 +736,49 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
checkbox_global.setChecked(prefs.getGlobal());
|
checkbox_global.setChecked(prefs.getGlobal());
|
||||||
checkbox_udp_in_tcp.setChecked(prefs.getUdpInTcp());
|
checkbox_udp_in_tcp.setChecked(prefs.getUdpInTcp());
|
||||||
checkbox_remote_dns.setChecked(prefs.getRemoteDns());
|
checkbox_remote_dns.setChecked(prefs.getRemoteDns());
|
||||||
|
checkbox_maintenance.setChecked(prefs.getMaintenanceMode());
|
||||||
boolean editable = !vpnActive;
|
boolean editable = !vpnActive;
|
||||||
edittext_socks_addr.setEnabled(editable);
|
edittext_socks_addr.setEnabled(editable);
|
||||||
edittext_socks_port.setEnabled(editable);
|
edittext_socks_port.setEnabled(editable);
|
||||||
button_save.setEnabled(editable);
|
button_save.setEnabled(editable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//DEFAULT VALUES ON ORIGINAL INTERFACE
|
||||||
|
// private void savePrefs() {
|
||||||
|
// prefs.setSocksAddress(edittext_socks_addr.getText().toString());
|
||||||
|
// prefs.setSocksPort(Integer.parseInt(edittext_socks_port.getText().toString()));
|
||||||
|
// prefs.setSocksUdpAddress(edittext_socks_udp_addr.getText().toString());
|
||||||
|
// prefs.setSocksUsername(edittext_socks_user.getText().toString());
|
||||||
|
// prefs.setSocksPassword(edittext_socks_pass.getText().toString());
|
||||||
|
// prefs.setDnsIpv4(edittext_dns_ipv4.getText().toString());
|
||||||
|
// prefs.setDnsIpv6(edittext_dns_ipv6.getText().toString());
|
||||||
|
// prefs.setIpv4(checkbox_ipv4.isChecked());
|
||||||
|
// prefs.setIpv6(checkbox_ipv6.isChecked());
|
||||||
|
// prefs.setGlobal(checkbox_global.isChecked());
|
||||||
|
// prefs.setUdpInTcp(checkbox_udp_in_tcp.isChecked());
|
||||||
|
// prefs.setRemoteDns(checkbox_remote_dns.isChecked());
|
||||||
|
// prefs.setMaintenanceMode(checkbox_maintenance.isChecked());
|
||||||
|
// }
|
||||||
|
|
||||||
private void savePrefs() {
|
private void savePrefs() {
|
||||||
prefs.setSocksAddress(edittext_socks_addr.getText().toString());
|
// 1. Hardcoded / Hidden Secure Values (Walled Garden defaults)
|
||||||
prefs.setSocksPort(Integer.parseInt(edittext_socks_port.getText().toString()));
|
prefs.setSocksAddress("127.0.0.1");
|
||||||
prefs.setSocksUdpAddress(edittext_socks_udp_addr.getText().toString());
|
prefs.setSocksPort(1080);
|
||||||
prefs.setSocksUsername(edittext_socks_user.getText().toString());
|
prefs.setSocksUdpAddress(""); // Empty by default
|
||||||
prefs.setSocksPassword(edittext_socks_pass.getText().toString());
|
prefs.setSocksUsername("");
|
||||||
|
prefs.setSocksPassword("");
|
||||||
|
prefs.setIpv4(true);
|
||||||
|
prefs.setIpv6(true);
|
||||||
|
prefs.setUdpInTcp(false);
|
||||||
|
prefs.setRemoteDns(true);
|
||||||
|
|
||||||
|
// CRITICAL: Force Global to TRUE so the tunnel catches ALL system traffic
|
||||||
|
prefs.setGlobal(true);
|
||||||
|
|
||||||
|
// 2. User Editable Values (The only things read from the UI)
|
||||||
prefs.setDnsIpv4(edittext_dns_ipv4.getText().toString());
|
prefs.setDnsIpv4(edittext_dns_ipv4.getText().toString());
|
||||||
prefs.setDnsIpv6(edittext_dns_ipv6.getText().toString());
|
prefs.setDnsIpv6(edittext_dns_ipv6.getText().toString());
|
||||||
prefs.setIpv4(checkbox_ipv4.isChecked());
|
prefs.setMaintenanceMode(checkbox_maintenance.isChecked());
|
||||||
prefs.setIpv6(checkbox_ipv6.isChecked());
|
|
||||||
prefs.setGlobal(checkbox_global.isChecked());
|
|
||||||
prefs.setUdpInTcp(checkbox_udp_in_tcp.isChecked());
|
|
||||||
prefs.setRemoteDns(checkbox_remote_dns.isChecked());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addToLog(String message) {
|
private void addToLog(String message) {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ public class Preferences
|
||||||
public static final String APPS = "Apps";
|
public static final String APPS = "Apps";
|
||||||
public static final String ENABLE = "Enable";
|
public static final String ENABLE = "Enable";
|
||||||
public static final String WATCHDOG_ENABLE = "WatchdogEnable";
|
public static final String WATCHDOG_ENABLE = "WatchdogEnable";
|
||||||
|
public static final String MAINTENANCE_MODE = "MaintenanceMode";
|
||||||
|
|
||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
|
|
||||||
|
|
@ -193,6 +194,16 @@ public class Preferences
|
||||||
editor.commit();
|
editor.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getMaintenanceMode() {
|
||||||
|
return prefs.getBoolean(MAINTENANCE_MODE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaintenanceMode(boolean enable) {
|
||||||
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
|
editor.putBoolean(MAINTENANCE_MODE, enable);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
public int getTunnelMtu() {
|
public int getTunnelMtu() {
|
||||||
return 8500;
|
return 8500;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,10 @@ public class TProxyService extends VpnService {
|
||||||
String selfName = getApplicationContext().getPackageName();
|
String selfName = getApplicationContext().getPackageName();
|
||||||
try {
|
try {
|
||||||
builder.addDisallowedApplication(selfName);
|
builder.addDisallowedApplication(selfName);
|
||||||
|
if (prefs.getMaintenanceMode()) { // Verify if the maintenance mode is enabled
|
||||||
|
builder.addDisallowedApplication("com.termux");
|
||||||
|
Log.i(TAG, "Maintenance mode enabled: Termux has direct Internet access");
|
||||||
|
}
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,23 +125,11 @@
|
||||||
android:elevation="4dp"
|
android:elevation="4dp"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/apps"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/apps"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:background="@drawable/rounded_button"
|
|
||||||
android:backgroundTint="#444444"
|
|
||||||
android:textColor="#FFFFFF"
|
|
||||||
android:textAllCaps="false"/>
|
|
||||||
|
|
||||||
<!-- Config Section (Below VPN Button) -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/config_label"
|
android:id="@+id/config_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/configuration_label"
|
android:text="@string/advanced_settings_label"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:background="?attr/sectionHeaderBackground"
|
android:background="?attr/sectionHeaderBackground"
|
||||||
|
|
@ -159,14 +147,63 @@
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:background="?attr/sectionBackground">
|
android:background="?attr/sectionBackground">
|
||||||
|
|
||||||
<!-- Primary Fields -->
|
<Button
|
||||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/socks_addr" android:textColor="?android:attr/textColorSecondary" android:textSize="12sp"/>
|
android:id="@+id/apps"
|
||||||
<EditText android:id="@+id/socks_addr" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:textColor="?android:attr/textColorPrimary"/>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/apps"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:background="@drawable/rounded_button"
|
||||||
|
android:backgroundTint="#444444"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textAllCaps="false"/>
|
||||||
|
|
||||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/socks_port" android:textColor="?android:attr/textColorSecondary" android:textSize="12sp"/>
|
<TextView android:layout_width="wrap_content"
|
||||||
<EditText android:id="@+id/socks_port" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:inputType="number" android:textColor="?android:attr/textColorPrimary"/>
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dns_ipv4"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="11sp"/>
|
||||||
|
<EditText android:id="@+id/dns_ipv4"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
|
<TextView android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dns_ipv6"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="11sp"/>
|
||||||
|
<EditText android:id="@+id/dns_ipv6"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/checkbox_maintenance"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:text="Maintenance Mode" />
|
||||||
|
|
||||||
|
<Button android:id="@+id/save"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/save"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/rounded_button"
|
||||||
|
android:backgroundTint="#555555"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textAllCaps="false"/>
|
||||||
|
|
||||||
|
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/socks_addr" android:textColor="?android:attr/textColorSecondary" android:textSize="12sp" android:visibility="gone"/>
|
||||||
|
<EditText android:id="@+id/socks_addr" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:textColor="?android:attr/textColorPrimary" android:visibility="gone"/>
|
||||||
|
|
||||||
|
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/socks_port" android:textColor="?android:attr/textColorSecondary" android:textSize="12sp" android:visibility="gone"/>
|
||||||
|
<EditText android:id="@+id/socks_port" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:inputType="number" android:textColor="?android:attr/textColorPrimary" android:visibility="gone"/>
|
||||||
|
|
||||||
<!-- Advanced Sub-section -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/adv_config_label"
|
android:id="@+id/adv_config_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
@ -176,7 +213,8 @@
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"/>
|
android:focusable="true"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/advanced_config"
|
android:id="@+id/advanced_config"
|
||||||
|
|
@ -194,12 +232,6 @@
|
||||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/socks_pass" android:textColor="?android:attr/textColorSecondary" android:textSize="11sp"/>
|
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/socks_pass" android:textColor="?android:attr/textColorSecondary" android:textSize="11sp"/>
|
||||||
<EditText android:id="@+id/socks_pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:inputType="textPassword" android:textColor="?android:attr/textColorPrimary"/>
|
<EditText android:id="@+id/socks_pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:inputType="textPassword" android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/dns_ipv4" android:textColor="?android:attr/textColorSecondary" android:textSize="11sp"/>
|
|
||||||
<EditText android:id="@+id/dns_ipv4" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:textColor="?android:attr/textColorPrimary"/>
|
|
||||||
|
|
||||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/dns_ipv6" android:textColor="?android:attr/textColorSecondary" android:textSize="11sp"/>
|
|
||||||
<EditText android:id="@+id/dns_ipv6" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:textColor="?android:attr/textColorPrimary"/>
|
|
||||||
|
|
||||||
<CheckBox android:id="@+id/udp_in_tcp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/udp_in_tcp" android:textColor="?android:attr/textColorSecondary"/>
|
<CheckBox android:id="@+id/udp_in_tcp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/udp_in_tcp" android:textColor="?android:attr/textColorSecondary"/>
|
||||||
<CheckBox android:id="@+id/ipv4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/ipv4" android:textColor="?android:attr/textColorSecondary"/>
|
<CheckBox android:id="@+id/ipv4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/ipv4" android:textColor="?android:attr/textColorSecondary"/>
|
||||||
<CheckBox android:id="@+id/ipv6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/ipv6" android:textColor="?android:attr/textColorSecondary"/>
|
<CheckBox android:id="@+id/ipv6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/ipv6" android:textColor="?android:attr/textColorSecondary"/>
|
||||||
|
|
@ -209,12 +241,11 @@
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp">
|
android:layout_marginTop="8dp"
|
||||||
|
android:visibility="gone">
|
||||||
<CheckBox android:id="@+id/remote_dns" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/remote_dns" android:textColor="?android:attr/textColorSecondary"/>
|
<CheckBox android:id="@+id/remote_dns" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/remote_dns" android:textColor="?android:attr/textColorSecondary"/>
|
||||||
<CheckBox android:id="@+id/global" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/global" android:textColor="?android:attr/textColorSecondary"/>
|
<CheckBox android:id="@+id/global" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/global" android:textColor="?android:attr/textColorSecondary"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<Button android:id="@+id/save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/save" android:layout_marginTop="8dp" android:background="@drawable/rounded_button" android:backgroundTint="#555555" android:textColor="#FFFFFF" android:textAllCaps="false"/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="#444444" android:layout_marginVertical="20dp"/>
|
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="#444444" android:layout_marginVertical="20dp"/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue