2015-10-24 18:01:55 +00:00
|
|
|
package eu.faircode.netguard;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
import android.app.AlertDialog;
|
2015-10-25 14:22:55 +00:00
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.Context;
|
2015-10-26 07:25:29 +00:00
|
|
|
import android.content.DialogInterface;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.content.Intent;
|
2015-10-25 14:22:55 +00:00
|
|
|
import android.content.IntentFilter;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.content.SharedPreferences;
|
2015-10-26 12:19:52 +00:00
|
|
|
import android.net.ConnectivityManager;
|
2015-10-25 15:48:41 +00:00
|
|
|
import android.net.Uri;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.net.VpnService;
|
|
|
|
import android.os.AsyncTask;
|
|
|
|
import android.preference.PreferenceManager;
|
2015-10-26 12:19:52 +00:00
|
|
|
import android.provider.Settings;
|
2015-10-25 10:11:46 +00:00
|
|
|
import android.support.v4.view.MenuItemCompat;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.support.v7.app.AppCompatActivity;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.support.v7.widget.LinearLayoutManager;
|
|
|
|
import android.support.v7.widget.RecyclerView;
|
2015-10-25 10:11:46 +00:00
|
|
|
import android.support.v7.widget.SearchView;
|
2015-10-26 16:28:47 +00:00
|
|
|
import android.support.v7.widget.SwitchCompat;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.util.Log;
|
2015-10-25 09:29:49 +00:00
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuInflater;
|
|
|
|
import android.view.MenuItem;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.view.View;
|
|
|
|
import android.widget.CompoundButton;
|
2015-10-25 09:29:49 +00:00
|
|
|
import android.widget.TextView;
|
2015-10-25 18:02:33 +00:00
|
|
|
import android.widget.Toast;
|
2015-10-24 18:01:55 +00:00
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
public class ActivityMain extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
2015-10-24 18:01:55 +00:00
|
|
|
private static final String TAG = "NetGuard.Main";
|
|
|
|
|
|
|
|
private boolean running = false;
|
|
|
|
private RuleAdapter adapter = null;
|
2015-10-27 07:04:39 +00:00
|
|
|
private MenuItem searchItem = null;
|
2015-10-24 18:01:55 +00:00
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
private static final int REQUEST_VPN = 1;
|
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
2015-10-25 09:29:49 +00:00
|
|
|
Log.i(TAG, "Create");
|
2015-10-26 17:47:31 +00:00
|
|
|
|
|
|
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
setTheme(prefs.getBoolean("dark_theme", false) ? R.style.AppThemeDark : R.style.AppTheme);
|
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
setContentView(R.layout.main);
|
2015-10-25 09:29:49 +00:00
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
running = true;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
// Action bar
|
2015-10-24 18:01:55 +00:00
|
|
|
View view = getLayoutInflater().inflate(R.layout.actionbar, null);
|
|
|
|
getSupportActionBar().setDisplayShowCustomEnabled(true);
|
|
|
|
getSupportActionBar().setCustomView(view);
|
|
|
|
|
2015-10-24 19:50:29 +00:00
|
|
|
// On/off switch
|
2015-10-26 16:28:47 +00:00
|
|
|
SwitchCompat swEnabled = (SwitchCompat) view.findViewById(R.id.swEnabled);
|
2015-10-25 17:30:44 +00:00
|
|
|
swEnabled.setChecked(prefs.getBoolean("enabled", false));
|
2015-10-24 18:01:55 +00:00
|
|
|
swEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
if (isChecked) {
|
2015-10-25 10:55:49 +00:00
|
|
|
Log.i(TAG, "Switch on");
|
2015-10-25 18:02:33 +00:00
|
|
|
Intent prepare = VpnService.prepare(ActivityMain.this);
|
|
|
|
if (prepare == null) {
|
2015-10-24 18:01:55 +00:00
|
|
|
Log.e(TAG, "Prepare done");
|
|
|
|
onActivityResult(REQUEST_VPN, RESULT_OK, null);
|
|
|
|
} else {
|
2015-10-25 18:02:33 +00:00
|
|
|
Log.i(TAG, "Start intent=" + prepare);
|
|
|
|
try {
|
|
|
|
startActivityForResult(prepare, REQUEST_VPN);
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
onActivityResult(REQUEST_VPN, RESULT_CANCELED, null);
|
|
|
|
Toast.makeText(ActivityMain.this, ex.toString(), Toast.LENGTH_LONG).show();
|
|
|
|
}
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
} else {
|
2015-10-25 10:55:49 +00:00
|
|
|
Log.i(TAG, "Switch off");
|
2015-10-25 09:29:49 +00:00
|
|
|
prefs.edit().putBoolean("enabled", false).apply();
|
2015-10-26 16:23:41 +00:00
|
|
|
BlackHoleService.stop(ActivityMain.this);
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-10-25 15:28:41 +00:00
|
|
|
// Listen for preference changes
|
2015-10-25 09:29:49 +00:00
|
|
|
prefs.registerOnSharedPreferenceChangeListener(this);
|
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
// Fill application list
|
2015-10-25 15:28:41 +00:00
|
|
|
fillApplicationList();
|
2015-10-25 14:22:55 +00:00
|
|
|
|
2015-10-26 16:32:03 +00:00
|
|
|
// Listen for connectivity updates
|
2015-10-26 12:19:52 +00:00
|
|
|
IntentFilter ifConnectivity = new IntentFilter();
|
|
|
|
ifConnectivity.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
|
|
|
registerReceiver(connectivityChangedReceiver, ifConnectivity);
|
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
// Listen for added/removed applications
|
|
|
|
IntentFilter intentFilter = new IntentFilter();
|
|
|
|
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
|
|
|
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
|
|
|
intentFilter.addDataScheme("package");
|
|
|
|
registerReceiver(packageChangedReceiver, intentFilter);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
Log.i(TAG, "Destroy");
|
|
|
|
running = false;
|
|
|
|
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
|
2015-10-26 12:19:52 +00:00
|
|
|
unregisterReceiver(connectivityChangedReceiver);
|
2015-10-25 14:22:55 +00:00
|
|
|
unregisterReceiver(packageChangedReceiver);
|
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
2015-10-26 12:19:52 +00:00
|
|
|
private BroadcastReceiver connectivityChangedReceiver = new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
Log.i(TAG, "Received " + intent);
|
|
|
|
Util.logExtras(TAG, intent);
|
|
|
|
invalidateOptionsMenu();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
private BroadcastReceiver packageChangedReceiver = new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
Log.i(TAG, "Received " + intent);
|
2015-10-26 12:19:52 +00:00
|
|
|
Util.logExtras(TAG, intent);
|
2015-10-25 15:28:41 +00:00
|
|
|
fillApplicationList();
|
2015-10-25 14:22:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-10-25 15:28:41 +00:00
|
|
|
private void fillApplicationList() {
|
|
|
|
// Get recycler view
|
2015-10-24 18:01:55 +00:00
|
|
|
final RecyclerView rvApplication = (RecyclerView) findViewById(R.id.rvApplication);
|
|
|
|
rvApplication.setHasFixedSize(true);
|
|
|
|
rvApplication.setLayoutManager(new LinearLayoutManager(this));
|
|
|
|
|
2015-10-25 15:28:41 +00:00
|
|
|
// Get/set application list
|
2015-10-24 18:01:55 +00:00
|
|
|
new AsyncTask<Object, Object, List<Rule>>() {
|
|
|
|
@Override
|
|
|
|
protected List<Rule> doInBackground(Object... arg) {
|
|
|
|
return Rule.getRules(ActivityMain.this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(List<Rule> result) {
|
|
|
|
if (running) {
|
2015-10-27 07:04:39 +00:00
|
|
|
if (searchItem != null)
|
|
|
|
MenuItemCompat.collapseActionView(searchItem);
|
2015-10-25 16:52:33 +00:00
|
|
|
adapter = new RuleAdapter(result, ActivityMain.this);
|
2015-10-24 18:01:55 +00:00
|
|
|
rvApplication.setAdapter(adapter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
@Override
|
|
|
|
public void onSharedPreferenceChanged(SharedPreferences prefs, String name) {
|
2015-10-25 17:37:09 +00:00
|
|
|
Log.i(TAG, "Preference " + name + "=" + prefs.getAll().get(name));
|
2015-10-25 09:29:49 +00:00
|
|
|
if ("enabled".equals(name)) {
|
2015-10-25 15:28:41 +00:00
|
|
|
// Get enabled
|
2015-10-25 09:29:49 +00:00
|
|
|
boolean enabled = prefs.getBoolean(name, false);
|
2015-10-25 15:28:41 +00:00
|
|
|
|
|
|
|
// Check switch state
|
2015-10-26 16:28:47 +00:00
|
|
|
SwitchCompat swEnabled = (SwitchCompat) getSupportActionBar().getCustomView().findViewById(R.id.swEnabled);
|
2015-10-25 09:29:49 +00:00
|
|
|
if (swEnabled.isChecked() != enabled)
|
|
|
|
swEnabled.setChecked(enabled);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
|
|
MenuInflater inflater = getMenuInflater();
|
|
|
|
inflater.inflate(R.menu.main, menu);
|
2015-10-25 10:11:46 +00:00
|
|
|
|
2015-10-25 15:28:41 +00:00
|
|
|
// Search
|
2015-10-27 07:04:39 +00:00
|
|
|
searchItem = menu.findItem(R.id.menu_search);
|
2015-10-25 10:11:46 +00:00
|
|
|
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
|
|
|
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onQueryTextSubmit(String query) {
|
2015-10-25 11:52:54 +00:00
|
|
|
if (adapter != null)
|
|
|
|
adapter.getFilter().filter(query);
|
2015-10-25 10:11:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onQueryTextChange(String newText) {
|
2015-10-25 11:52:54 +00:00
|
|
|
if (adapter != null)
|
|
|
|
adapter.getFilter().filter(newText);
|
2015-10-25 10:11:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onClose() {
|
2015-10-25 11:52:54 +00:00
|
|
|
if (adapter != null)
|
|
|
|
adapter.getFilter().filter(null);
|
2015-10-25 10:11:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-10-25 22:04:10 +00:00
|
|
|
@Override
|
|
|
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
2015-10-26 12:19:52 +00:00
|
|
|
MenuItem network = menu.findItem(R.id.menu_network);
|
|
|
|
network.setIcon(Util.isWifiActive(this) ? R.drawable.ic_network_wifi_white_24dp : R.drawable.ic_network_cell_white_24dp);
|
|
|
|
|
|
|
|
MenuItem wifi = menu.findItem(R.id.menu_whitelist_wifi);
|
|
|
|
wifi.setChecked(prefs.getBoolean("whitelist_wifi", true));
|
2015-10-25 22:04:10 +00:00
|
|
|
|
2015-10-26 12:19:52 +00:00
|
|
|
MenuItem other = menu.findItem(R.id.menu_whitelist_other);
|
|
|
|
other.setChecked(prefs.getBoolean("whitelist_other", true));
|
2015-10-25 22:04:10 +00:00
|
|
|
|
2015-10-26 17:47:31 +00:00
|
|
|
MenuItem dark = menu.findItem(R.id.menu_dark);
|
|
|
|
dark.setChecked(prefs.getBoolean("dark_theme", false));
|
|
|
|
|
2015-10-25 22:04:10 +00:00
|
|
|
return super.onPrepareOptionsMenu(menu);
|
|
|
|
}
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
2015-10-25 22:04:10 +00:00
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
// Handle item selection
|
|
|
|
switch (item.getItemId()) {
|
2015-10-26 12:19:52 +00:00
|
|
|
case R.id.menu_network:
|
|
|
|
Intent settings = new Intent(Util.isWifiActive(this)
|
|
|
|
? Settings.ACTION_WIFI_SETTINGS : Settings.ACTION_WIRELESS_SETTINGS);
|
|
|
|
if (settings.resolveActivity(getPackageManager()) != null)
|
|
|
|
startActivity(settings);
|
|
|
|
else
|
|
|
|
Log.w(TAG, settings + " not available");
|
|
|
|
return true;
|
|
|
|
|
2015-10-25 22:04:10 +00:00
|
|
|
case R.id.menu_whitelist_wifi:
|
|
|
|
prefs.edit().putBoolean("whitelist_wifi", !prefs.getBoolean("whitelist_wifi", true)).apply();
|
|
|
|
fillApplicationList();
|
|
|
|
BlackHoleService.reload("wifi", this);
|
2015-10-25 11:52:54 +00:00
|
|
|
return true;
|
|
|
|
|
2015-10-25 22:04:10 +00:00
|
|
|
case R.id.menu_whitelist_other:
|
|
|
|
prefs.edit().putBoolean("whitelist_other", !prefs.getBoolean("whitelist_other", true)).apply();
|
|
|
|
fillApplicationList();
|
|
|
|
BlackHoleService.reload("other", this);
|
2015-10-25 11:52:54 +00:00
|
|
|
return true;
|
|
|
|
|
2015-10-26 07:25:29 +00:00
|
|
|
case R.id.menu_reset_wifi:
|
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
.setMessage(R.string.msg_sure)
|
|
|
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
reset("wifi");
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.setNegativeButton(android.R.string.no, null)
|
|
|
|
.show();
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.menu_reset_other:
|
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
.setMessage(R.string.msg_sure)
|
|
|
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
reset("other");
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.setNegativeButton(android.R.string.no, null)
|
|
|
|
.show();
|
|
|
|
return true;
|
|
|
|
|
2015-10-26 17:47:31 +00:00
|
|
|
case R.id.menu_dark:
|
|
|
|
prefs.edit().putBoolean("dark_theme", !prefs.getBoolean("dark_theme", false)).apply();
|
|
|
|
recreate();
|
|
|
|
return true;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
case R.id.menu_vpn_settings:
|
2015-10-25 15:28:41 +00:00
|
|
|
// Open VPN settings
|
2015-10-25 15:48:41 +00:00
|
|
|
Intent vpn = new Intent("android.net.vpn.SETTINGS");
|
|
|
|
if (vpn.resolveActivity(getPackageManager()) != null)
|
|
|
|
startActivity(vpn);
|
2015-10-25 09:29:49 +00:00
|
|
|
else
|
2015-10-25 15:48:41 +00:00
|
|
|
Log.w(TAG, vpn + " not available");
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.menu_support:
|
|
|
|
Intent xda = new Intent(Intent.ACTION_VIEW);
|
|
|
|
xda.setData(Uri.parse("http://forum.xda-developers.com/showthread.php?t=3233012"));
|
|
|
|
if (xda.resolveActivity(getPackageManager()) != null)
|
|
|
|
startActivity(xda);
|
|
|
|
else
|
|
|
|
Log.w(TAG, xda + " not available");
|
2015-10-25 09:29:49 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.menu_about:
|
2015-10-25 15:28:41 +00:00
|
|
|
// Show about
|
2015-10-25 09:29:49 +00:00
|
|
|
LayoutInflater inflater = LayoutInflater.from(this);
|
|
|
|
View view = inflater.inflate(R.layout.about, null);
|
|
|
|
TextView tvVersion = (TextView) view.findViewById(R.id.tvVersion);
|
|
|
|
tvVersion.setText(Util.getSelfVersionName(this));
|
|
|
|
AlertDialog dialog = new AlertDialog.Builder(this)
|
|
|
|
.setView(view)
|
|
|
|
.setCancelable(true).create();
|
|
|
|
dialog.show();
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
|
}
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-26 16:32:03 +00:00
|
|
|
private void reset(String network) {
|
|
|
|
SharedPreferences other = getSharedPreferences(network, Context.MODE_PRIVATE);
|
2015-10-26 07:25:29 +00:00
|
|
|
SharedPreferences.Editor edit = other.edit();
|
|
|
|
for (String key : other.getAll().keySet())
|
|
|
|
edit.remove(key);
|
|
|
|
edit.apply();
|
|
|
|
fillApplicationList();
|
2015-10-26 16:32:03 +00:00
|
|
|
BlackHoleService.reload(network, ActivityMain.this);
|
2015-10-26 07:25:29 +00:00
|
|
|
}
|
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
@Override
|
|
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
|
|
if (requestCode == REQUEST_VPN) {
|
2015-10-25 15:28:41 +00:00
|
|
|
// Update enabled state
|
2015-10-25 09:29:49 +00:00
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
prefs.edit().putBoolean("enabled", resultCode == RESULT_OK).apply();
|
|
|
|
|
2015-10-25 15:28:41 +00:00
|
|
|
// Start service
|
2015-10-26 16:23:41 +00:00
|
|
|
if (resultCode == RESULT_OK)
|
|
|
|
BlackHoleService.start(this);
|
2015-10-24 18:01:55 +00:00
|
|
|
} else
|
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
|
|
}
|
|
|
|
}
|