[controller] maintenance, cleaning and move strings.

This commit is contained in:
Luis Guzmán 2026-03-06 11:12:23 -06:00
parent f247a1f173
commit 3fec55ca56
2 changed files with 80 additions and 71 deletions

View File

@ -10,6 +10,8 @@
package org.iiab.controller;
import android.os.Bundle;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.app.AlertDialog;
@ -22,7 +24,6 @@ import android.content.ClipboardManager;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
@ -73,8 +74,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private Button watchdogControl;
private TextView connectionLog;
private LinearLayout logActions;
private Button btnClearLog;
private Button btnCopyLog;
private LinearLayout configLayout;
private TextView configLabel;
private LinearLayout advancedConfig;
@ -83,7 +82,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private ImageButton themeToggle;
private TextView versionFooter;
private BroadcastReceiver logReceiver = new BroadcastReceiver() {
private ActivityResultLauncher<Intent> vpnPermissionLauncher;
private final BroadcastReceiver logReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (IIABWatchdog.ACTION_LOG_MESSAGE.equals(intent.getAction())) {
@ -100,45 +101,55 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
prefs = new Preferences(this);
setContentView(R.layout.main);
edittext_socks_addr = (EditText) findViewById(R.id.socks_addr);
edittext_socks_udp_addr = (EditText) findViewById(R.id.socks_udp_addr);
edittext_socks_port = (EditText) findViewById(R.id.socks_port);
edittext_socks_user = (EditText) findViewById(R.id.socks_user);
edittext_socks_pass = (EditText) findViewById(R.id.socks_pass);
edittext_dns_ipv4 = (EditText) findViewById(R.id.dns_ipv4);
edittext_dns_ipv6 = (EditText) findViewById(R.id.dns_ipv6);
checkbox_ipv4 = (CheckBox) findViewById(R.id.ipv4);
checkbox_ipv6 = (CheckBox) findViewById(R.id.ipv6);
checkbox_global = (CheckBox) findViewById(R.id.global);
checkbox_udp_in_tcp = (CheckBox) findViewById(R.id.udp_in_tcp);
checkbox_remote_dns = (CheckBox) findViewById(R.id.remote_dns);
button_apps = (Button) findViewById(R.id.apps);
button_save = (Button) findViewById(R.id.save);
button_control = (Button) findViewById(R.id.control);
// Initialize the VPN permission launcher
vpnPermissionLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK && prefs.getEnable()) {
connectVpn();
}
}
);
edittext_socks_addr = findViewById(R.id.socks_addr);
edittext_socks_udp_addr = findViewById(R.id.socks_udp_addr);
edittext_socks_port = findViewById(R.id.socks_port);
edittext_socks_user = findViewById(R.id.socks_user);
edittext_socks_pass = findViewById(R.id.socks_pass);
edittext_dns_ipv4 = findViewById(R.id.dns_ipv4);
edittext_dns_ipv6 = findViewById(R.id.dns_ipv6);
checkbox_ipv4 = findViewById(R.id.ipv4);
checkbox_ipv6 = findViewById(R.id.ipv6);
checkbox_global = findViewById(R.id.global);
checkbox_udp_in_tcp = findViewById(R.id.udp_in_tcp);
checkbox_remote_dns = findViewById(R.id.remote_dns);
button_apps = findViewById(R.id.apps);
button_save = findViewById(R.id.save);
button_control = findViewById(R.id.control);
watchdogControl = (Button) findViewById(R.id.watchdog_control);
watchdogControl = findViewById(R.id.watchdog_control);
watchdogControl.setOnClickListener(this);
logActions = (LinearLayout) findViewById(R.id.log_actions);
btnClearLog = (Button) findViewById(R.id.btn_clear_log);
btnCopyLog = (Button) findViewById(R.id.btn_copy_log);
logActions = findViewById(R.id.log_actions);
Button btnClearLog = findViewById(R.id.btn_clear_log);
Button btnCopyLog = findViewById(R.id.btn_copy_log);
btnClearLog.setOnClickListener(this);
btnCopyLog.setOnClickListener(this);
connectionLog = (TextView) findViewById(R.id.connection_log);
connectionLog = findViewById(R.id.connection_log);
connectionLog.setMovementMethod(new ScrollingMovementMethod());
// Enable text selection for copying large logs
connectionLog.setTextIsSelectable(true);
configLayout = (LinearLayout) findViewById(R.id.config_layout);
configLabel = (TextView) findViewById(R.id.config_label);
configLayout = findViewById(R.id.config_layout);
configLabel = findViewById(R.id.config_label);
configLabel.setOnClickListener(v -> toggleVisibility(configLayout, configLabel, "Configuration"));
advancedConfig = (LinearLayout) findViewById(R.id.advanced_config);
advConfigLabel = (TextView) findViewById(R.id.adv_config_label);
advancedConfig = findViewById(R.id.advanced_config);
advConfigLabel = findViewById(R.id.adv_config_label);
advConfigLabel.setOnClickListener(v -> toggleVisibility(advancedConfig, advConfigLabel, "Advanced Settings"));
logLabel = (TextView) findViewById(R.id.log_label);
logLabel = findViewById(R.id.log_label);
logLabel.setOnClickListener(v -> {
if (connectionLog.getVisibility() == View.GONE) {
readBlackBoxLogs(); // Load logs from file when expanding
@ -147,11 +158,11 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
logActions.setVisibility(connectionLog.getVisibility());
});
themeToggle = (ImageButton) findViewById(R.id.theme_toggle);
themeToggle = findViewById(R.id.theme_toggle);
themeToggle.setOnClickListener(v -> toggleTheme());
applySavedTheme();
versionFooter = (TextView) findViewById(R.id.version_text);
versionFooter = findViewById(R.id.version_text);
setVersionFooter();
checkbox_udp_in_tcp.setOnClickListener(this);
@ -164,15 +175,22 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
/* Request VPN permission */
Intent intent = VpnService.prepare(MainActivity.this);
if (intent != null)
startActivityForResult(intent, 0);
else
onActivityResult(0, RESULT_OK, null);
if (intent != null) {
vpnPermissionLauncher.launch(intent);
} else if (prefs.getEnable()) {
connectVpn();
}
checkBatteryOptimizations();
addToLog("Application Started");
}
private void connectVpn() {
Intent intent = new Intent(this, TProxyService.class);
startService(intent.setAction(TProxyService.ACTION_CONNECT));
addToLog("VPN Permission Granted. Connecting...");
}
private void readBlackBoxLogs() {
File logFile = new File(getFilesDir(), "watchdog_heartbeat_log.txt");
if (!logFile.exists()) {
@ -290,7 +308,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
super.onStart();
IntentFilter filter = new IntentFilter(IIABWatchdog.ACTION_LOG_MESSAGE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(logReceiver, filter, Context.RECEIVER_EXPORTED);
registerReceiver(logReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
} else {
registerReceiver(logReceiver, filter);
}
@ -306,16 +324,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
}
@Override
protected void onActivityResult(int request, int result, Intent data) {
super.onActivityResult(request, result, data);
if ((result == RESULT_OK) && prefs.getEnable()) {
Intent intent = new Intent(this, TProxyService.class);
startService(intent.setAction(TProxyService.ACTION_CONNECT));
addToLog("VPN Permission Granted. Connecting...");
}
}
@Override
public void onClick(View view) {
if (view == checkbox_global || view == checkbox_remote_dns) {
@ -377,9 +385,12 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
showBiometricPrompt();
} else {
BiometricManager biometricManager = BiometricManager.from(this);
int authenticators = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) ?
(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL) :
BiometricManager.Authenticators.BIOMETRIC_WEAK;
int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
// For older versions, DEVICE_CREDENTIAL behaves differently, but androidx.biometric handles fallback
authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
}
boolean isSecure = false;
android.app.KeyguardManager km = (android.app.KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
@ -418,17 +429,15 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
});
BiometricPrompt.PromptInfo.Builder promptBuilder = new BiometricPrompt.PromptInfo.Builder()
.setTitle("Authentication required")
.setSubtitle("Authenticate to disable the secure environment");
int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
promptBuilder.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG |
BiometricManager.Authenticators.DEVICE_CREDENTIAL);
} else {
promptBuilder.setDeviceCredentialAllowed(true);
}
biometricPrompt.authenticate(promptBuilder.build());
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("Authentication required")
.setSubtitle("Authenticate to disable the secure environment")
.setAllowedAuthenticators(authenticators)
.build();
biometricPrompt.authenticate(promptInfo);
}
private void showWatchdogBiometricPrompt() {
@ -441,17 +450,15 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
});
BiometricPrompt.PromptInfo.Builder promptBuilder = new BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock Master Watchdog")
.setSubtitle("Authentication required to stop Termux protection");
int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
promptBuilder.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG |
BiometricManager.Authenticators.DEVICE_CREDENTIAL);
} else {
promptBuilder.setDeviceCredentialAllowed(true);
}
biometricPrompt.authenticate(promptBuilder.build());
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock Master Watchdog")
.setSubtitle("Authentication required to stop Termux protection")
.setAllowedAuthenticators(authenticators)
.build();
biometricPrompt.authenticate(promptInfo);
}
private void toggleService(boolean isEnable) {
@ -481,10 +488,10 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
if (watchdogActive) {
watchdogControl.setText("Disable Master Watchdog");
watchdogControl.setText(R.string.watchdog_disable);
watchdogControl.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.btn_watchdog_on));
} else {
watchdogControl.setText("Enable Master Watchdog");
watchdogControl.setText(R.string.watchdog_enable);
watchdogControl.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.btn_watchdog_off));
}

View File

@ -18,4 +18,6 @@
<string name="control_enable">Enable Safe Pocket Web</string>
<string name="control_disable">Disable Safe Pocket Web</string>
<string name="vpn_description">Enable friendly URLs. Lock out the threats.</string>
<string name="watchdog_enable">Enable Master Watchdog</string>
<string name="watchdog_disable">Disable Master Watchdog</string>
</resources>