2015-10-24 18:01:55 +00:00
|
|
|
package eu.faircode.netguard;
|
|
|
|
|
2015-11-03 17:57:29 +00:00
|
|
|
/*
|
|
|
|
This file is part of NetGuard.
|
|
|
|
|
|
|
|
NetGuard is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
NetGuard is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with NetGuard. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2018-12-31 16:12:49 +00:00
|
|
|
Copyright 2015-2019 by Marcel Bokhorst (M66B)
|
2015-11-03 17:57:29 +00:00
|
|
|
*/
|
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.Context;
|
2015-10-30 15:51:24 +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-12-02 09:42:24 +00:00
|
|
|
import android.content.pm.PackageManager;
|
2016-07-24 16:02:56 +00:00
|
|
|
import android.content.res.Configuration;
|
2015-10-31 13:15:26 +00:00
|
|
|
import android.graphics.Color;
|
2016-02-20 07:53:39 +00:00
|
|
|
import android.graphics.drawable.Drawable;
|
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;
|
2015-11-29 08:01:24 +00:00
|
|
|
import android.os.Build;
|
2018-10-07 06:22:28 +00:00
|
|
|
import android.os.Bundle;
|
2016-03-15 07:05:48 +00:00
|
|
|
import android.provider.Settings;
|
2018-07-08 07:56:55 +00:00
|
|
|
import android.text.SpannableString;
|
2016-07-29 07:46:20 +00:00
|
|
|
import android.text.SpannableStringBuilder;
|
|
|
|
import android.text.Spanned;
|
2017-10-15 12:31:51 +00:00
|
|
|
import android.text.TextUtils;
|
2015-11-01 06:31:36 +00:00
|
|
|
import android.text.method.LinkMovementMethod;
|
2016-07-29 07:46:20 +00:00
|
|
|
import android.text.style.ImageSpan;
|
2018-07-08 07:56:55 +00:00
|
|
|
import android.text.style.UnderlineSpan;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.util.Log;
|
2016-01-02 12:22:18 +00:00
|
|
|
import android.util.TypedValue;
|
2016-02-18 08:44:12 +00:00
|
|
|
import android.view.Gravity;
|
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;
|
2015-10-30 15:51:24 +00:00
|
|
|
import android.widget.Button;
|
2016-03-15 07:05:48 +00:00
|
|
|
import android.widget.CheckBox;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.widget.CompoundButton;
|
2016-02-18 08:44:12 +00:00
|
|
|
import android.widget.ImageView;
|
2016-04-11 12:54:57 +00:00
|
|
|
import android.widget.LinearLayout;
|
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
|
|
|
|
2018-11-17 16:32:36 +00:00
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.appcompat.app.AlertDialog;
|
|
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
|
|
import androidx.appcompat.widget.SearchView;
|
|
|
|
import androidx.appcompat.widget.SwitchCompat;
|
|
|
|
import androidx.core.graphics.drawable.DrawableCompat;
|
|
|
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
2020-01-09 18:24:55 +00:00
|
|
|
import androidx.preference.PreferenceManager;
|
2018-11-17 16:32:36 +00:00
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
|
|
|
|
2019-04-18 17:25:17 +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;
|
2016-02-19 08:43:14 +00:00
|
|
|
private ImageView ivIcon;
|
2016-02-19 07:49:31 +00:00
|
|
|
private ImageView ivQueue;
|
2016-02-19 08:43:14 +00:00
|
|
|
private SwitchCompat swEnabled;
|
2016-02-18 08:44:12 +00:00
|
|
|
private ImageView ivMetered;
|
2015-10-31 13:15:26 +00:00
|
|
|
private SwipeRefreshLayout swipeRefresh;
|
2016-02-13 08:45:03 +00:00
|
|
|
private AdapterRule adapter = null;
|
2015-10-29 08:56:22 +00:00
|
|
|
private MenuItem menuSearch = null;
|
2015-11-02 18:53:56 +00:00
|
|
|
private AlertDialog dialogFirst = null;
|
2015-11-03 11:21:34 +00:00
|
|
|
private AlertDialog dialogVpn = null;
|
2016-03-15 07:05:48 +00:00
|
|
|
private AlertDialog dialogDoze = null;
|
2016-02-19 11:35:10 +00:00
|
|
|
private AlertDialog dialogLegend = null;
|
2015-11-02 18:53:56 +00:00
|
|
|
private AlertDialog dialogAbout = null;
|
2015-10-24 18:01:55 +00:00
|
|
|
|
2016-02-12 06:52:19 +00:00
|
|
|
private IAB iab = null;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
private static final int REQUEST_VPN = 1;
|
2015-12-30 08:00:34 +00:00
|
|
|
private static final int REQUEST_INVITE = 2;
|
|
|
|
private static final int REQUEST_LOGCAT = 3;
|
|
|
|
public static final int REQUEST_ROAMING = 4;
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2018-10-17 13:57:38 +00:00
|
|
|
private static final int MIN_SDK = Build.VERSION_CODES.LOLLIPOP_MR1;
|
2015-11-29 08:01:24 +00:00
|
|
|
|
2015-11-25 19:05:17 +00:00
|
|
|
public static final String ACTION_RULES_CHANGED = "eu.faircode.netguard.ACTION_RULES_CHANGED";
|
2016-02-19 07:49:31 +00:00
|
|
|
public static final String ACTION_QUEUE_CHANGED = "eu.faircode.netguard.ACTION_QUEUE_CHANGED";
|
2016-02-16 06:25:57 +00:00
|
|
|
public static final String EXTRA_REFRESH = "Refresh";
|
2015-12-25 21:58:23 +00:00
|
|
|
public static final String EXTRA_SEARCH = "Search";
|
2017-07-05 05:02:43 +00:00
|
|
|
public static final String EXTRA_RELATED = "Related";
|
2016-02-02 07:43:53 +00:00
|
|
|
public static final String EXTRA_APPROVE = "Approve";
|
2016-02-14 12:30:36 +00:00
|
|
|
public static final String EXTRA_LOGCAT = "Logcat";
|
2016-02-19 07:49:31 +00:00
|
|
|
public static final String EXTRA_CONNECTED = "Connected";
|
|
|
|
public static final String EXTRA_METERED = "Metered";
|
|
|
|
public static final String EXTRA_SIZE = "Size";
|
2015-11-25 19:05:17 +00:00
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
2016-03-09 07:24:16 +00:00
|
|
|
Log.i(TAG, "Create version=" + Util.getSelfVersionName(this) + "/" + Util.getSelfVersionCode(this));
|
2016-02-14 12:30:36 +00:00
|
|
|
Util.logExtras(getIntent());
|
2015-10-26 17:47:31 +00:00
|
|
|
|
2017-11-04 15:39:06 +00:00
|
|
|
// Check minimum Android version
|
2015-11-29 08:01:24 +00:00
|
|
|
if (Build.VERSION.SDK_INT < MIN_SDK) {
|
2017-11-04 15:39:06 +00:00
|
|
|
Log.i(TAG, "SDK=" + Build.VERSION.SDK_INT);
|
2015-11-29 08:01:24 +00:00
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
setContentView(R.layout.android);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-04 15:39:06 +00:00
|
|
|
// Check for Xposed
|
2018-01-12 06:26:24 +00:00
|
|
|
if (Util.hasXposed(this)) {
|
2017-11-17 07:15:40 +00:00
|
|
|
Log.i(TAG, "Xposed running");
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
setContentView(R.layout.xposed);
|
|
|
|
return;
|
|
|
|
}
|
2017-11-04 08:52:16 +00:00
|
|
|
|
2016-01-02 15:38:24 +00:00
|
|
|
Util.setTheme(this);
|
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;
|
2016-01-02 15:38:24 +00:00
|
|
|
|
|
|
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
2015-10-29 16:33:06 +00:00
|
|
|
boolean enabled = prefs.getBoolean("enabled", false);
|
2015-11-21 09:53:03 +00:00
|
|
|
boolean initialized = prefs.getBoolean("initialized", false);
|
|
|
|
|
|
|
|
// Upgrade
|
2017-11-05 14:17:09 +00:00
|
|
|
ReceiverAutostart.upgrade(initialized, this);
|
2015-10-24 18:01:55 +00:00
|
|
|
|
2016-02-02 07:43:53 +00:00
|
|
|
if (!getIntent().hasExtra(EXTRA_APPROVE)) {
|
|
|
|
if (enabled)
|
2016-03-11 06:47:52 +00:00
|
|
|
ServiceSinkhole.start("UI", this);
|
2016-02-02 07:43:53 +00:00
|
|
|
else
|
2017-07-22 12:48:00 +00:00
|
|
|
ServiceSinkhole.stop("UI", this, false);
|
2016-02-02 07:43:53 +00:00
|
|
|
}
|
2015-11-04 19:48:27 +00:00
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
// Action bar
|
2016-02-18 22:05:02 +00:00
|
|
|
final View actionView = getLayoutInflater().inflate(R.layout.actionmain, null, false);
|
2017-08-05 08:27:27 +00:00
|
|
|
ivIcon = actionView.findViewById(R.id.ivIcon);
|
|
|
|
ivQueue = actionView.findViewById(R.id.ivQueue);
|
|
|
|
swEnabled = actionView.findViewById(R.id.swEnabled);
|
|
|
|
ivMetered = actionView.findViewById(R.id.ivMetered);
|
2015-11-10 13:41:32 +00:00
|
|
|
|
2016-02-21 11:39:24 +00:00
|
|
|
// Icon
|
2016-02-19 10:07:04 +00:00
|
|
|
ivIcon.setOnLongClickListener(new View.OnLongClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onLongClick(View view) {
|
|
|
|
menu_about();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-02-21 11:39:24 +00:00
|
|
|
// Title
|
|
|
|
getSupportActionBar().setTitle(null);
|
|
|
|
|
2016-02-19 09:39:29 +00:00
|
|
|
// Netguard is busy
|
|
|
|
ivQueue.setOnLongClickListener(new View.OnLongClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onLongClick(View view) {
|
2016-02-19 10:07:04 +00:00
|
|
|
int location[] = new int[2];
|
|
|
|
actionView.getLocationOnScreen(location);
|
2016-02-19 09:39:29 +00:00
|
|
|
Toast toast = Toast.makeText(ActivityMain.this, R.string.msg_queue, Toast.LENGTH_LONG);
|
2016-02-19 10:07:04 +00:00
|
|
|
toast.setGravity(
|
2016-03-31 07:51:43 +00:00
|
|
|
Gravity.TOP | Gravity.LEFT,
|
2016-02-19 10:07:04 +00:00
|
|
|
location[0] + ivQueue.getLeft(),
|
|
|
|
Math.round(location[1] + ivQueue.getBottom() - toast.getView().getPaddingTop()));
|
2016-02-19 09:39:29 +00:00
|
|
|
toast.show();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-10-24 19:50:29 +00:00
|
|
|
// On/off switch
|
2015-10-29 16:33:06 +00:00
|
|
|
swEnabled.setChecked(enabled);
|
2015-10-24 18:01:55 +00:00
|
|
|
swEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
2016-01-11 10:58:53 +00:00
|
|
|
Log.i(TAG, "Switch=" + isChecked);
|
2015-11-12 15:13:03 +00:00
|
|
|
prefs.edit().putBoolean("enabled", isChecked).apply();
|
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
if (isChecked) {
|
2017-10-15 12:31:51 +00:00
|
|
|
String alwaysOn = Settings.Secure.getString(getContentResolver(), "always_on_vpn_app");
|
|
|
|
Log.i(TAG, "Always-on=" + alwaysOn);
|
2018-10-07 06:22:28 +00:00
|
|
|
if (!TextUtils.isEmpty(alwaysOn))
|
|
|
|
if (getPackageName().equals(alwaysOn)) {
|
2018-10-12 13:31:26 +00:00
|
|
|
if (prefs.getBoolean("filter", false)) {
|
|
|
|
int lockdown = Settings.Secure.getInt(getContentResolver(), "always_on_vpn_lockdown", 0);
|
|
|
|
Log.i(TAG, "Lockdown=" + lockdown);
|
|
|
|
if (lockdown != 0) {
|
|
|
|
swEnabled.setChecked(false);
|
|
|
|
Toast.makeText(ActivityMain.this, R.string.msg_always_on_lockdown, Toast.LENGTH_LONG).show();
|
|
|
|
return;
|
|
|
|
}
|
2018-10-07 06:22:28 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
swEnabled.setChecked(false);
|
|
|
|
Toast.makeText(ActivityMain.this, R.string.msg_always_on, Toast.LENGTH_LONG).show();
|
|
|
|
return;
|
|
|
|
}
|
2017-10-15 12:31:51 +00:00
|
|
|
|
2019-10-29 07:54:33 +00:00
|
|
|
boolean filter = prefs.getBoolean("filter", false);
|
2019-10-29 07:59:05 +00:00
|
|
|
if (filter && Util.isPrivateDns(ActivityMain.this))
|
2019-10-29 07:54:33 +00:00
|
|
|
Toast.makeText(ActivityMain.this, R.string.msg_private_dns, Toast.LENGTH_LONG).show();
|
|
|
|
|
2015-11-22 19:30:29 +00:00
|
|
|
try {
|
|
|
|
final Intent prepare = VpnService.prepare(ActivityMain.this);
|
|
|
|
if (prepare == null) {
|
2015-11-23 10:05:16 +00:00
|
|
|
Log.i(TAG, "Prepare done");
|
2015-11-22 19:30:29 +00:00
|
|
|
onActivityResult(REQUEST_VPN, RESULT_OK, null);
|
|
|
|
} else {
|
|
|
|
// Show dialog
|
|
|
|
LayoutInflater inflater = LayoutInflater.from(ActivityMain.this);
|
2016-02-13 14:55:22 +00:00
|
|
|
View view = inflater.inflate(R.layout.vpn, null, false);
|
2015-11-22 19:30:29 +00:00
|
|
|
dialogVpn = new AlertDialog.Builder(ActivityMain.this)
|
|
|
|
.setView(view)
|
|
|
|
.setCancelable(false)
|
|
|
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
if (running) {
|
|
|
|
Log.i(TAG, "Start intent=" + prepare);
|
|
|
|
try {
|
2016-05-14 16:28:15 +00:00
|
|
|
// com.android.vpndialogs.ConfirmDialog required
|
2015-11-22 19:30:29 +00:00
|
|
|
startActivityForResult(prepare, REQUEST_VPN);
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
onActivityResult(REQUEST_VPN, RESULT_CANCELED, null);
|
2015-11-27 08:26:34 +00:00
|
|
|
prefs.edit().putBoolean("enabled", false).apply();
|
2015-11-22 19:30:29 +00:00
|
|
|
}
|
2015-11-03 11:21:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-22 19:30:29 +00:00
|
|
|
})
|
|
|
|
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
|
@Override
|
|
|
|
public void onDismiss(DialogInterface dialogInterface) {
|
|
|
|
dialogVpn = null;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
|
|
|
dialogVpn.show();
|
|
|
|
}
|
|
|
|
} catch (Throwable ex) {
|
2015-11-27 08:26:34 +00:00
|
|
|
// Prepare failed
|
2015-11-22 19:30:29 +00:00
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
2015-11-27 08:26:34 +00:00
|
|
|
prefs.edit().putBoolean("enabled", false).apply();
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
2015-11-27 08:26:34 +00:00
|
|
|
|
2016-01-11 10:58:53 +00:00
|
|
|
} else
|
2017-07-22 12:48:00 +00:00
|
|
|
ServiceSinkhole.stop("switch off", ActivityMain.this, false);
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
});
|
2019-10-08 11:27:25 +00:00
|
|
|
if (enabled)
|
2016-03-15 07:05:48 +00:00
|
|
|
checkDoze();
|
2015-10-24 18:01:55 +00:00
|
|
|
|
2016-02-18 08:44:12 +00:00
|
|
|
// Network is metered
|
|
|
|
ivMetered.setOnLongClickListener(new View.OnLongClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onLongClick(View view) {
|
2016-02-19 10:07:04 +00:00
|
|
|
int location[] = new int[2];
|
|
|
|
actionView.getLocationOnScreen(location);
|
2016-02-18 08:44:12 +00:00
|
|
|
Toast toast = Toast.makeText(ActivityMain.this, R.string.msg_metered, Toast.LENGTH_LONG);
|
2016-02-19 10:07:04 +00:00
|
|
|
toast.setGravity(
|
2016-03-31 07:51:43 +00:00
|
|
|
Gravity.TOP | Gravity.LEFT,
|
2016-02-19 10:07:04 +00:00
|
|
|
location[0] + ivMetered.getLeft(),
|
|
|
|
Math.round(location[1] + ivMetered.getBottom() - toast.getView().getPaddingTop()));
|
2016-02-18 08:44:12 +00:00
|
|
|
toast.show();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-02-18 22:05:02 +00:00
|
|
|
getSupportActionBar().setDisplayShowCustomEnabled(true);
|
|
|
|
getSupportActionBar().setCustomView(actionView);
|
|
|
|
|
2015-10-31 13:15:26 +00:00
|
|
|
// Disabled warning
|
2017-08-05 08:27:27 +00:00
|
|
|
TextView tvDisabled = findViewById(R.id.tvDisabled);
|
2015-10-31 13:15:26 +00:00
|
|
|
tvDisabled.setVisibility(enabled ? View.GONE : View.VISIBLE);
|
|
|
|
|
|
|
|
// Application list
|
2017-08-05 08:27:27 +00:00
|
|
|
RecyclerView rvApplication = findViewById(R.id.rvApplication);
|
2018-02-01 13:42:56 +00:00
|
|
|
rvApplication.setHasFixedSize(false);
|
|
|
|
LinearLayoutManager llm = new LinearLayoutManager(this);
|
|
|
|
llm.setAutoMeasureEnabled(true);
|
|
|
|
rvApplication.setLayoutManager(llm);
|
2018-02-04 08:04:59 +00:00
|
|
|
adapter = new AdapterRule(this, findViewById(R.id.vwPopupAnchor));
|
2015-10-31 13:15:26 +00:00
|
|
|
rvApplication.setAdapter(adapter);
|
2015-10-25 09:29:49 +00:00
|
|
|
|
2015-10-31 13:23:18 +00:00
|
|
|
// Swipe to refresh
|
2016-01-02 12:22:18 +00:00
|
|
|
TypedValue tv = new TypedValue();
|
|
|
|
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
|
2017-08-05 08:27:27 +00:00
|
|
|
swipeRefresh = findViewById(R.id.swipeRefresh);
|
2015-10-31 13:15:26 +00:00
|
|
|
swipeRefresh.setColorSchemeColors(Color.WHITE, Color.WHITE, Color.WHITE);
|
2016-01-02 12:22:18 +00:00
|
|
|
swipeRefresh.setProgressBackgroundColorSchemeColor(tv.data);
|
2015-10-31 13:15:26 +00:00
|
|
|
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
|
|
|
@Override
|
|
|
|
public void onRefresh() {
|
2016-03-14 16:33:22 +00:00
|
|
|
Rule.clearCache(ActivityMain.this);
|
2017-07-22 12:48:00 +00:00
|
|
|
ServiceSinkhole.reload("pull", ActivityMain.this, false);
|
2016-01-30 19:37:07 +00:00
|
|
|
updateApplicationList(null);
|
2015-10-31 13:15:26 +00:00
|
|
|
}
|
|
|
|
});
|
2015-10-31 13:23:18 +00:00
|
|
|
|
2016-07-24 18:13:26 +00:00
|
|
|
// Hint usage
|
2017-08-05 08:27:27 +00:00
|
|
|
final LinearLayout llUsage = findViewById(R.id.llUsage);
|
|
|
|
Button btnUsage = findViewById(R.id.btnUsage);
|
2016-07-24 18:13:26 +00:00
|
|
|
boolean hintUsage = prefs.getBoolean("hint_usage", true);
|
|
|
|
llUsage.setVisibility(hintUsage ? View.VISIBLE : View.GONE);
|
|
|
|
btnUsage.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
prefs.edit().putBoolean("hint_usage", false).apply();
|
|
|
|
llUsage.setVisibility(View.GONE);
|
2016-07-24 20:34:08 +00:00
|
|
|
showHints();
|
2016-07-24 18:13:26 +00:00
|
|
|
}
|
|
|
|
});
|
2019-04-16 18:03:48 +00:00
|
|
|
|
|
|
|
final LinearLayout llFairEmail = findViewById(R.id.llFairEmail);
|
|
|
|
TextView tvFairEmail = findViewById(R.id.tvFairEmail);
|
|
|
|
tvFairEmail.setMovementMethod(LinkMovementMethod.getInstance());
|
|
|
|
Button btnFairEmail = findViewById(R.id.btnFairEmail);
|
|
|
|
boolean hintFairEmail = prefs.getBoolean("hint_fairemail", true);
|
|
|
|
llFairEmail.setVisibility(hintFairEmail ? View.VISIBLE : View.GONE);
|
|
|
|
btnFairEmail.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
prefs.edit().putBoolean("hint_fairemail", false).apply();
|
|
|
|
llFairEmail.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-07-24 20:34:08 +00:00
|
|
|
showHints();
|
2016-04-11 12:54:57 +00:00
|
|
|
|
2015-11-14 10:04:27 +00:00
|
|
|
// Listen for preference changes
|
|
|
|
prefs.registerOnSharedPreferenceChangeListener(this);
|
|
|
|
|
2015-11-25 19:05:17 +00:00
|
|
|
// Listen for rule set changes
|
2016-02-19 07:49:31 +00:00
|
|
|
IntentFilter ifr = new IntentFilter(ACTION_RULES_CHANGED);
|
|
|
|
LocalBroadcastManager.getInstance(this).registerReceiver(onRulesChanged, ifr);
|
|
|
|
|
|
|
|
// Listen for queue changes
|
|
|
|
IntentFilter ifq = new IntentFilter(ACTION_QUEUE_CHANGED);
|
|
|
|
LocalBroadcastManager.getInstance(this).registerReceiver(onQueueChanged, ifq);
|
2015-11-25 19:05:17 +00:00
|
|
|
|
2015-11-14 10:04:27 +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);
|
|
|
|
|
2015-11-02 12:22:58 +00:00
|
|
|
// First use
|
2018-05-22 06:46:31 +00:00
|
|
|
if (!initialized) {
|
2015-11-02 12:22:58 +00:00
|
|
|
// Create view
|
|
|
|
LayoutInflater inflater = LayoutInflater.from(this);
|
2016-02-13 14:55:22 +00:00
|
|
|
View view = inflater.inflate(R.layout.first, null, false);
|
2016-07-08 06:40:31 +00:00
|
|
|
|
2017-08-05 08:27:27 +00:00
|
|
|
TextView tvFirst = view.findViewById(R.id.tvFirst);
|
2018-07-14 15:37:33 +00:00
|
|
|
TextView tvEula = view.findViewById(R.id.tvEula);
|
2017-08-14 07:22:34 +00:00
|
|
|
TextView tvPrivacy = view.findViewById(R.id.tvPrivacy);
|
2015-11-02 12:22:58 +00:00
|
|
|
tvFirst.setMovementMethod(LinkMovementMethod.getInstance());
|
2018-07-14 15:37:33 +00:00
|
|
|
tvEula.setMovementMethod(LinkMovementMethod.getInstance());
|
2017-08-14 07:22:34 +00:00
|
|
|
tvPrivacy.setMovementMethod(LinkMovementMethod.getInstance());
|
2015-11-02 12:22:58 +00:00
|
|
|
|
|
|
|
// Show dialog
|
2015-11-02 18:53:56 +00:00
|
|
|
dialogFirst = new AlertDialog.Builder(this)
|
2015-11-02 12:22:58 +00:00
|
|
|
.setView(view)
|
|
|
|
.setCancelable(false)
|
2016-07-12 18:23:59 +00:00
|
|
|
.setPositiveButton(R.string.app_agree, new DialogInterface.OnClickListener() {
|
2015-11-02 12:22:58 +00:00
|
|
|
@Override
|
2015-11-06 22:49:03 +00:00
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
2016-07-27 11:47:31 +00:00
|
|
|
if (running) {
|
2015-11-02 18:53:56 +00:00
|
|
|
prefs.edit().putBoolean("initialized", true).apply();
|
2016-07-27 11:47:31 +00:00
|
|
|
}
|
2015-11-02 12:22:58 +00:00
|
|
|
}
|
|
|
|
})
|
2016-07-12 18:23:59 +00:00
|
|
|
.setNegativeButton(R.string.app_disagree, new DialogInterface.OnClickListener() {
|
2015-11-02 12:22:58 +00:00
|
|
|
@Override
|
2015-11-06 22:49:03 +00:00
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
2016-02-07 08:28:02 +00:00
|
|
|
if (running)
|
|
|
|
finish();
|
2015-11-02 12:22:58 +00:00
|
|
|
}
|
|
|
|
})
|
2015-11-02 18:53:56 +00:00
|
|
|
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
|
@Override
|
|
|
|
public void onDismiss(DialogInterface dialogInterface) {
|
|
|
|
dialogFirst = null;
|
|
|
|
}
|
|
|
|
})
|
2015-11-02 12:22:58 +00:00
|
|
|
.create();
|
2015-11-02 18:53:56 +00:00
|
|
|
dialogFirst.show();
|
2015-11-02 12:22:58 +00:00
|
|
|
}
|
2015-11-18 07:36:53 +00:00
|
|
|
|
|
|
|
// Fill application list
|
2015-12-25 21:58:23 +00:00
|
|
|
updateApplicationList(getIntent().getStringExtra(EXTRA_SEARCH));
|
2015-12-30 08:58:21 +00:00
|
|
|
|
|
|
|
// Update IAB SKUs
|
|
|
|
try {
|
2016-02-12 06:52:19 +00:00
|
|
|
iab = new IAB(new IAB.Delegate() {
|
2015-12-30 08:58:21 +00:00
|
|
|
@Override
|
2016-02-18 08:16:18 +00:00
|
|
|
public void onReady(IAB iab) {
|
2015-12-30 08:58:21 +00:00
|
|
|
try {
|
2015-12-31 15:55:39 +00:00
|
|
|
iab.updatePurchases();
|
2016-01-03 08:10:12 +00:00
|
|
|
|
2016-01-06 07:35:07 +00:00
|
|
|
if (!IAB.isPurchased(ActivityPro.SKU_LOG, ActivityMain.this))
|
|
|
|
prefs.edit().putBoolean("log", false).apply();
|
2016-01-03 08:10:12 +00:00
|
|
|
if (!IAB.isPurchased(ActivityPro.SKU_THEME, ActivityMain.this)) {
|
|
|
|
if (!"teal".equals(prefs.getString("theme", "teal")))
|
|
|
|
prefs.edit().putString("theme", "teal").apply();
|
|
|
|
}
|
2017-01-06 18:20:00 +00:00
|
|
|
if (!IAB.isPurchased(ActivityPro.SKU_NOTIFY, ActivityMain.this))
|
|
|
|
prefs.edit().putBoolean("install", false).apply();
|
2016-01-03 08:10:12 +00:00
|
|
|
if (!IAB.isPurchased(ActivityPro.SKU_SPEED, ActivityMain.this))
|
|
|
|
prefs.edit().putBoolean("show_stats", false).apply();
|
2015-12-30 08:58:21 +00:00
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
2016-02-01 12:07:20 +00:00
|
|
|
} finally {
|
|
|
|
iab.unbind();
|
2015-12-30 08:58:21 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-12 06:52:19 +00:00
|
|
|
}, this);
|
|
|
|
iab.bind();
|
2015-12-30 08:58:21 +00:00
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
}
|
2016-02-02 07:43:53 +00:00
|
|
|
|
2018-07-08 07:56:55 +00:00
|
|
|
// Support
|
|
|
|
LinearLayout llSupport = findViewById(R.id.llSupport);
|
|
|
|
TextView tvSupport = findViewById(R.id.tvSupport);
|
|
|
|
|
|
|
|
SpannableString content = new SpannableString(getString(R.string.app_support));
|
|
|
|
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
|
|
|
|
tvSupport.setText(content);
|
|
|
|
|
|
|
|
llSupport.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
2018-07-09 06:40:27 +00:00
|
|
|
startActivity(getIntentPro(ActivityMain.this));
|
2018-07-08 07:56:55 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-07-24 16:02:56 +00:00
|
|
|
// Handle intent
|
2016-02-14 12:30:36 +00:00
|
|
|
checkExtras(getIntent());
|
2015-12-25 21:58:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onNewIntent(Intent intent) {
|
|
|
|
Log.i(TAG, "New intent");
|
2016-02-14 12:30:36 +00:00
|
|
|
Util.logExtras(intent);
|
2015-12-25 21:58:23 +00:00
|
|
|
super.onNewIntent(intent);
|
2016-02-14 12:30:36 +00:00
|
|
|
|
2017-11-17 07:15:40 +00:00
|
|
|
if (Build.VERSION.SDK_INT < MIN_SDK || Util.hasXposed(this))
|
|
|
|
return;
|
|
|
|
|
2017-02-20 18:49:00 +00:00
|
|
|
setIntent(intent);
|
|
|
|
|
2016-02-14 12:30:36 +00:00
|
|
|
if (Build.VERSION.SDK_INT >= MIN_SDK) {
|
2016-02-16 06:25:57 +00:00
|
|
|
if (intent.hasExtra(EXTRA_REFRESH))
|
|
|
|
updateApplicationList(intent.getStringExtra(EXTRA_SEARCH));
|
|
|
|
else
|
|
|
|
updateSearch(intent.getStringExtra(EXTRA_SEARCH));
|
2016-02-14 12:30:36 +00:00
|
|
|
checkExtras(intent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-04 12:00:33 +00:00
|
|
|
@Override
|
|
|
|
protected void onResume() {
|
2016-07-25 13:45:18 +00:00
|
|
|
Log.i(TAG, "Resume");
|
|
|
|
|
2017-11-17 07:15:40 +00:00
|
|
|
if (Build.VERSION.SDK_INT < MIN_SDK || Util.hasXposed(this)) {
|
|
|
|
super.onResume();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-10 11:50:51 +00:00
|
|
|
DatabaseHelper.getInstance(this).addAccessChangedListener(accessChangedListener);
|
2016-02-04 13:06:33 +00:00
|
|
|
if (adapter != null)
|
|
|
|
adapter.notifyDataSetChanged();
|
2016-07-25 06:11:16 +00:00
|
|
|
|
2018-07-09 06:40:27 +00:00
|
|
|
PackageManager pm = getPackageManager();
|
2018-07-08 07:56:55 +00:00
|
|
|
LinearLayout llSupport = findViewById(R.id.llSupport);
|
2018-07-09 06:40:27 +00:00
|
|
|
llSupport.setVisibility(
|
|
|
|
IAB.isPurchasedAny(this) || getIntentPro(this).resolveActivity(pm) == null
|
|
|
|
? View.GONE : View.VISIBLE);
|
2018-07-08 07:56:55 +00:00
|
|
|
|
2016-02-04 12:00:33 +00:00
|
|
|
super.onResume();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPause() {
|
2016-07-25 13:45:18 +00:00
|
|
|
Log.i(TAG, "Pause");
|
2016-02-04 12:00:33 +00:00
|
|
|
super.onPause();
|
2016-07-25 13:45:18 +00:00
|
|
|
|
2017-11-17 07:15:40 +00:00
|
|
|
if (Build.VERSION.SDK_INT < MIN_SDK || Util.hasXposed(this))
|
|
|
|
return;
|
|
|
|
|
2016-02-10 11:50:51 +00:00
|
|
|
DatabaseHelper.getInstance(this).removeAccessChangedListener(accessChangedListener);
|
2016-07-25 13:45:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onConfigurationChanged(Configuration newConfig) {
|
|
|
|
Log.i(TAG, "Config");
|
|
|
|
super.onConfigurationChanged(newConfig);
|
|
|
|
|
2017-11-17 07:15:40 +00:00
|
|
|
if (Build.VERSION.SDK_INT < MIN_SDK || Util.hasXposed(this))
|
|
|
|
return;
|
2016-02-04 12:00:33 +00:00
|
|
|
}
|
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
@Override
|
2015-11-14 10:04:27 +00:00
|
|
|
public void onDestroy() {
|
|
|
|
Log.i(TAG, "Destroy");
|
2015-11-29 08:01:24 +00:00
|
|
|
|
2017-11-17 07:15:40 +00:00
|
|
|
if (Build.VERSION.SDK_INT < MIN_SDK || Util.hasXposed(this)) {
|
2015-11-29 08:01:24 +00:00
|
|
|
super.onDestroy();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-11-14 10:04:27 +00:00
|
|
|
running = false;
|
2016-11-10 07:54:32 +00:00
|
|
|
adapter = null;
|
2015-11-14 09:49:37 +00:00
|
|
|
|
2015-11-14 10:04:27 +00:00
|
|
|
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
|
2015-11-14 10:04:18 +00:00
|
|
|
|
2016-02-19 07:49:31 +00:00
|
|
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(onRulesChanged);
|
|
|
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(onQueueChanged);
|
2015-10-25 14:22:55 +00:00
|
|
|
unregisterReceiver(packageChangedReceiver);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-11-03 11:21:34 +00:00
|
|
|
if (dialogFirst != null) {
|
2015-11-02 18:53:56 +00:00
|
|
|
dialogFirst.dismiss();
|
2015-11-03 11:21:34 +00:00
|
|
|
dialogFirst = null;
|
|
|
|
}
|
|
|
|
if (dialogVpn != null) {
|
|
|
|
dialogVpn.dismiss();
|
|
|
|
dialogVpn = null;
|
|
|
|
}
|
2016-03-15 07:05:48 +00:00
|
|
|
if (dialogDoze != null) {
|
|
|
|
dialogDoze.dismiss();
|
|
|
|
dialogDoze = null;
|
|
|
|
}
|
2016-02-19 11:35:10 +00:00
|
|
|
if (dialogLegend != null) {
|
|
|
|
dialogLegend.dismiss();
|
|
|
|
dialogLegend = null;
|
|
|
|
}
|
2015-11-03 11:21:34 +00:00
|
|
|
if (dialogAbout != null) {
|
2015-11-02 18:53:56 +00:00
|
|
|
dialogAbout.dismiss();
|
2015-11-03 11:21:34 +00:00
|
|
|
dialogAbout = null;
|
|
|
|
}
|
2015-11-02 18:53:56 +00:00
|
|
|
|
2016-02-12 06:52:19 +00:00
|
|
|
if (iab != null) {
|
|
|
|
iab.unbind();
|
|
|
|
iab = null;
|
|
|
|
}
|
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
2015-11-04 19:20:30 +00:00
|
|
|
@Override
|
|
|
|
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
|
|
|
|
Log.i(TAG, "onActivityResult request=" + requestCode + " result=" + requestCode + " ok=" + (resultCode == RESULT_OK));
|
2015-11-20 10:34:23 +00:00
|
|
|
Util.logExtras(data);
|
2015-11-04 19:20:30 +00:00
|
|
|
|
|
|
|
if (requestCode == REQUEST_VPN) {
|
|
|
|
// Handle VPN approval
|
2015-11-05 09:55:34 +00:00
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
prefs.edit().putBoolean("enabled", resultCode == RESULT_OK).apply();
|
2016-03-15 07:05:48 +00:00
|
|
|
if (resultCode == RESULT_OK) {
|
2016-03-11 06:47:52 +00:00
|
|
|
ServiceSinkhole.start("prepared", this);
|
2017-05-12 05:55:22 +00:00
|
|
|
|
|
|
|
Toast on = Toast.makeText(ActivityMain.this, R.string.msg_on, Toast.LENGTH_LONG);
|
|
|
|
on.setGravity(Gravity.CENTER, 0, 0);
|
|
|
|
on.show();
|
|
|
|
|
2016-03-15 07:05:48 +00:00
|
|
|
checkDoze();
|
2016-12-21 21:12:52 +00:00
|
|
|
} else if (resultCode == RESULT_CANCELED)
|
|
|
|
Toast.makeText(this, R.string.msg_vpn_cancelled, Toast.LENGTH_LONG).show();
|
2015-11-04 19:20:30 +00:00
|
|
|
|
2015-11-07 17:18:37 +00:00
|
|
|
} else if (requestCode == REQUEST_INVITE) {
|
2015-11-08 09:14:56 +00:00
|
|
|
// Do nothing
|
2015-11-07 17:18:37 +00:00
|
|
|
|
2015-11-26 19:34:03 +00:00
|
|
|
} else if (requestCode == REQUEST_LOGCAT) {
|
|
|
|
// Send logcat by e-mail
|
2016-01-31 14:12:35 +00:00
|
|
|
if (resultCode == RESULT_OK) {
|
|
|
|
Uri target = data.getData();
|
|
|
|
if (data.hasExtra("org.openintents.extra.DIR_PATH"))
|
|
|
|
target = Uri.parse(target + "/logcat.txt");
|
2016-02-02 06:46:50 +00:00
|
|
|
Log.i(TAG, "Export URI=" + target);
|
2016-01-31 14:12:35 +00:00
|
|
|
Util.sendLogcat(target, this);
|
|
|
|
}
|
2015-11-26 19:34:03 +00:00
|
|
|
|
2015-11-04 19:20:30 +00:00
|
|
|
} else {
|
|
|
|
Log.w(TAG, "Unknown activity result request=" + requestCode);
|
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-02 09:42:24 +00:00
|
|
|
@Override
|
2016-01-31 15:38:38 +00:00
|
|
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
2015-12-02 09:42:24 +00:00
|
|
|
if (requestCode == REQUEST_ROAMING)
|
|
|
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
2017-07-22 12:48:00 +00:00
|
|
|
ServiceSinkhole.reload("permission granted", this, false);
|
2015-12-02 09:42:24 +00:00
|
|
|
}
|
|
|
|
|
2015-11-04 19:20:30 +00:00
|
|
|
@Override
|
|
|
|
public void onSharedPreferenceChanged(SharedPreferences prefs, String name) {
|
|
|
|
Log.i(TAG, "Preference " + name + "=" + prefs.getAll().get(name));
|
|
|
|
if ("enabled".equals(name)) {
|
|
|
|
// Get enabled
|
|
|
|
boolean enabled = prefs.getBoolean(name, false);
|
|
|
|
|
|
|
|
// Display disabled warning
|
2017-08-05 08:27:27 +00:00
|
|
|
TextView tvDisabled = findViewById(R.id.tvDisabled);
|
2015-11-04 19:20:30 +00:00
|
|
|
tvDisabled.setVisibility(enabled ? View.GONE : View.VISIBLE);
|
|
|
|
|
|
|
|
// Check switch state
|
2017-08-05 08:27:27 +00:00
|
|
|
SwitchCompat swEnabled = getSupportActionBar().getCustomView().findViewById(R.id.swEnabled);
|
2015-11-04 19:20:30 +00:00
|
|
|
if (swEnabled.isChecked() != enabled)
|
|
|
|
swEnabled.setChecked(enabled);
|
2015-11-04 22:44:17 +00:00
|
|
|
|
|
|
|
} else if ("whitelist_wifi".equals(name) ||
|
2016-12-21 15:03:09 +00:00
|
|
|
"screen_on".equals(name) ||
|
2015-11-21 08:48:33 +00:00
|
|
|
"screen_wifi".equals(name) ||
|
2015-11-30 13:02:00 +00:00
|
|
|
"whitelist_other".equals(name) ||
|
2015-11-21 08:48:33 +00:00
|
|
|
"screen_other".equals(name) ||
|
2015-11-04 22:44:17 +00:00
|
|
|
"whitelist_roaming".equals(name) ||
|
2015-12-26 08:58:28 +00:00
|
|
|
"show_user".equals(name) ||
|
|
|
|
"show_system".equals(name) ||
|
2015-12-27 08:54:25 +00:00
|
|
|
"show_nointernet".equals(name) ||
|
|
|
|
"show_disabled".equals(name) ||
|
2015-12-28 08:09:07 +00:00
|
|
|
"sort".equals(name) ||
|
2016-06-27 08:18:39 +00:00
|
|
|
"imported".equals(name)) {
|
2016-01-30 19:37:07 +00:00
|
|
|
updateApplicationList(null);
|
2015-11-04 22:44:17 +00:00
|
|
|
|
2017-08-05 08:27:27 +00:00
|
|
|
final LinearLayout llWhitelist = findViewById(R.id.llWhitelist);
|
2016-12-21 15:03:09 +00:00
|
|
|
boolean screen_on = prefs.getBoolean("screen_on", true);
|
2016-06-27 08:18:39 +00:00
|
|
|
boolean whitelist_wifi = prefs.getBoolean("whitelist_wifi", false);
|
|
|
|
boolean whitelist_other = prefs.getBoolean("whitelist_other", false);
|
|
|
|
boolean hintWhitelist = prefs.getBoolean("hint_whitelist", true);
|
2016-12-21 15:03:09 +00:00
|
|
|
llWhitelist.setVisibility(!(whitelist_wifi || whitelist_other) && screen_on && hintWhitelist ? View.VISIBLE : View.GONE);
|
2016-06-27 08:18:39 +00:00
|
|
|
|
|
|
|
} else if ("manage_system".equals(name)) {
|
2015-12-26 08:58:28 +00:00
|
|
|
invalidateOptionsMenu();
|
2016-01-30 19:37:07 +00:00
|
|
|
updateApplicationList(null);
|
2016-06-27 08:18:39 +00:00
|
|
|
|
2017-08-05 08:27:27 +00:00
|
|
|
LinearLayout llSystem = findViewById(R.id.llSystem);
|
2016-04-11 12:54:57 +00:00
|
|
|
boolean system = prefs.getBoolean("manage_system", false);
|
|
|
|
boolean hint = prefs.getBoolean("hint_system", true);
|
|
|
|
llSystem.setVisibility(!system && hint ? View.VISIBLE : View.GONE);
|
2015-12-26 08:58:28 +00:00
|
|
|
|
2016-01-02 15:38:24 +00:00
|
|
|
} else if ("theme".equals(name) || "dark_theme".equals(name))
|
2015-11-04 22:44:17 +00:00
|
|
|
recreate();
|
2015-11-04 19:20:30 +00:00
|
|
|
}
|
|
|
|
|
2016-01-30 11:46:00 +00:00
|
|
|
private DatabaseHelper.AccessChangedListener accessChangedListener = new DatabaseHelper.AccessChangedListener() {
|
|
|
|
@Override
|
2016-02-04 10:49:43 +00:00
|
|
|
public void onChanged() {
|
2016-01-30 11:46:00 +00:00
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2016-12-25 09:23:20 +00:00
|
|
|
if (adapter != null && adapter.isLive())
|
2016-01-30 11:46:00 +00:00
|
|
|
adapter.notifyDataSetChanged();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-02-19 07:49:31 +00:00
|
|
|
private BroadcastReceiver onRulesChanged = new BroadcastReceiver() {
|
2015-11-25 19:05:17 +00:00
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
Log.i(TAG, "Received " + intent);
|
|
|
|
Util.logExtras(intent);
|
|
|
|
|
2017-02-12 08:44:26 +00:00
|
|
|
if (adapter != null)
|
2016-02-19 07:49:31 +00:00
|
|
|
if (intent.hasExtra(EXTRA_CONNECTED) && intent.hasExtra(EXTRA_METERED)) {
|
2017-02-12 09:11:11 +00:00
|
|
|
ivIcon.setImageResource(Util.isNetworkActive(ActivityMain.this)
|
|
|
|
? R.drawable.ic_security_white_24dp
|
|
|
|
: R.drawable.ic_security_white_24dp_60);
|
2016-02-19 08:25:01 +00:00
|
|
|
if (intent.getBooleanExtra(EXTRA_CONNECTED, false)) {
|
2016-02-19 07:49:31 +00:00
|
|
|
if (intent.getBooleanExtra(EXTRA_METERED, false))
|
2015-12-25 12:10:00 +00:00
|
|
|
adapter.setMobileActive();
|
|
|
|
else
|
|
|
|
adapter.setWifiActive();
|
2016-02-19 08:25:01 +00:00
|
|
|
ivMetered.setVisibility(Util.isMeteredNetwork(ActivityMain.this) ? View.VISIBLE : View.INVISIBLE);
|
|
|
|
} else {
|
2015-12-25 12:10:00 +00:00
|
|
|
adapter.setDisconnected();
|
2016-02-19 08:25:01 +00:00
|
|
|
ivMetered.setVisibility(View.INVISIBLE);
|
|
|
|
}
|
2016-02-18 08:44:12 +00:00
|
|
|
} else
|
2016-01-30 19:37:07 +00:00
|
|
|
updateApplicationList(null);
|
2015-11-25 19:05:17 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-02-19 07:49:31 +00:00
|
|
|
private BroadcastReceiver onQueueChanged = new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
Log.i(TAG, "Received " + intent);
|
|
|
|
Util.logExtras(intent);
|
|
|
|
int size = intent.getIntExtra(EXTRA_SIZE, -1);
|
2016-02-19 08:43:14 +00:00
|
|
|
ivIcon.setVisibility(size == 0 ? View.VISIBLE : View.GONE);
|
|
|
|
ivQueue.setVisibility(size == 0 ? View.GONE : View.VISIBLE);
|
2016-02-19 07:49:31 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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-11-20 10:34:23 +00:00
|
|
|
Util.logExtras(intent);
|
2016-01-30 19:37:07 +00:00
|
|
|
updateApplicationList(null);
|
2015-10-25 14:22:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
@Override
|
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
|
|
if (Build.VERSION.SDK_INT < MIN_SDK)
|
|
|
|
return false;
|
2016-01-07 07:04:16 +00:00
|
|
|
|
2018-07-08 17:16:28 +00:00
|
|
|
PackageManager pm = getPackageManager();
|
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
MenuInflater inflater = getMenuInflater();
|
|
|
|
inflater.inflate(R.menu.main, menu);
|
2015-10-31 19:52:24 +00:00
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
// Search
|
|
|
|
menuSearch = menu.findItem(R.id.menu_search);
|
2017-08-05 08:27:27 +00:00
|
|
|
menuSearch.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
|
2015-10-31 17:12:57 +00:00
|
|
|
@Override
|
2016-07-25 05:53:23 +00:00
|
|
|
public boolean onMenuItemActionExpand(MenuItem item) {
|
|
|
|
return true;
|
2015-10-31 17:12:57 +00:00
|
|
|
}
|
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
@Override
|
2016-07-25 05:53:23 +00:00
|
|
|
public boolean onMenuItemActionCollapse(MenuItem item) {
|
2017-07-05 05:02:43 +00:00
|
|
|
if (getIntent().hasExtra(EXTRA_SEARCH) && !getIntent().getBooleanExtra(EXTRA_RELATED, false))
|
2016-07-25 05:53:23 +00:00
|
|
|
finish();
|
|
|
|
return true;
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
2016-07-25 05:53:23 +00:00
|
|
|
});
|
2015-10-24 18:01:55 +00:00
|
|
|
|
2017-08-05 08:27:27 +00:00
|
|
|
final SearchView searchView = (SearchView) menuSearch.getActionView();
|
2016-07-25 05:53:23 +00:00
|
|
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
2015-10-24 18:01:55 +00:00
|
|
|
@Override
|
2016-07-25 05:53:23 +00:00
|
|
|
public boolean onQueryTextSubmit(String query) {
|
|
|
|
if (adapter != null)
|
|
|
|
adapter.getFilter().filter(query);
|
|
|
|
searchView.clearFocus();
|
|
|
|
return true;
|
|
|
|
}
|
2016-01-30 19:37:07 +00:00
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
@Override
|
|
|
|
public boolean onQueryTextChange(String newText) {
|
|
|
|
if (adapter != null)
|
|
|
|
adapter.getFilter().filter(newText);
|
|
|
|
return true;
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
2016-07-25 05:53:23 +00:00
|
|
|
});
|
|
|
|
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onClose() {
|
2017-02-20 18:49:00 +00:00
|
|
|
Intent intent = getIntent();
|
|
|
|
intent.removeExtra(EXTRA_SEARCH);
|
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
if (adapter != null)
|
|
|
|
adapter.getFilter().filter(null);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
2017-02-20 18:49:00 +00:00
|
|
|
String search = getIntent().getStringExtra(EXTRA_SEARCH);
|
|
|
|
if (search != null) {
|
2017-08-05 08:27:27 +00:00
|
|
|
menuSearch.expandActionView();
|
2017-02-20 18:49:00 +00:00
|
|
|
searchView.setQuery(search, true);
|
|
|
|
}
|
2016-07-25 05:53:23 +00:00
|
|
|
|
2016-07-29 07:46:20 +00:00
|
|
|
markPro(menu.findItem(R.id.menu_log), ActivityPro.SKU_LOG);
|
|
|
|
if (!IAB.isPurchasedAny(this))
|
|
|
|
markPro(menu.findItem(R.id.menu_pro), null);
|
|
|
|
|
2018-07-08 17:16:28 +00:00
|
|
|
if (!Util.hasValidFingerprint(this) || getIntentInvite(this).resolveActivity(pm) == null)
|
2016-07-25 05:53:23 +00:00
|
|
|
menu.removeItem(R.id.menu_invite);
|
|
|
|
|
|
|
|
if (getIntentSupport().resolveActivity(getPackageManager()) == null)
|
|
|
|
menu.removeItem(R.id.menu_support);
|
|
|
|
|
2018-07-08 17:16:28 +00:00
|
|
|
menu.findItem(R.id.menu_apps).setEnabled(getIntentApps(this).resolveActivity(pm) != null);
|
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
return true;
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
|
2016-07-29 07:46:20 +00:00
|
|
|
private void markPro(MenuItem menu, String sku) {
|
|
|
|
if (sku == null || !IAB.isPurchased(sku, this)) {
|
2016-10-06 11:57:07 +00:00
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
boolean dark = prefs.getBoolean("dark_theme", false);
|
2016-07-29 07:46:20 +00:00
|
|
|
SpannableStringBuilder ssb = new SpannableStringBuilder(" " + menu.getTitle());
|
2016-10-06 11:57:07 +00:00
|
|
|
ssb.setSpan(new ImageSpan(this, dark ? R.drawable.ic_shopping_cart_white_24dp : R.drawable.ic_shopping_cart_black_24dp), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
2016-07-29 07:46:20 +00:00
|
|
|
menu.setTitle(ssb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
@Override
|
|
|
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
|
|
|
if (prefs.getBoolean("manage_system", false)) {
|
|
|
|
menu.findItem(R.id.menu_app_user).setChecked(prefs.getBoolean("show_user", true));
|
|
|
|
menu.findItem(R.id.menu_app_system).setChecked(prefs.getBoolean("show_system", false));
|
|
|
|
} else {
|
|
|
|
Menu submenu = menu.findItem(R.id.menu_filter).getSubMenu();
|
|
|
|
submenu.removeItem(R.id.menu_app_user);
|
|
|
|
submenu.removeItem(R.id.menu_app_system);
|
2015-12-27 08:54:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
menu.findItem(R.id.menu_app_nointernet).setChecked(prefs.getBoolean("show_nointernet", true));
|
|
|
|
menu.findItem(R.id.menu_app_disabled).setChecked(prefs.getBoolean("show_disabled", true));
|
|
|
|
|
2015-12-28 08:09:07 +00:00
|
|
|
String sort = prefs.getString("sort", "name");
|
2017-03-24 06:09:04 +00:00
|
|
|
if ("uid".equals(sort))
|
2016-03-09 17:21:38 +00:00
|
|
|
menu.findItem(R.id.menu_sort_uid).setChecked(true);
|
2015-12-29 10:04:13 +00:00
|
|
|
else
|
|
|
|
menu.findItem(R.id.menu_sort_name).setChecked(true);
|
2015-12-28 08:09:07 +00:00
|
|
|
|
2017-03-21 08:06:04 +00:00
|
|
|
menu.findItem(R.id.menu_lockdown).setChecked(prefs.getBoolean("lockdown", false));
|
|
|
|
|
2015-12-26 08:58:28 +00:00
|
|
|
return super.onPrepareOptionsMenu(menu);
|
|
|
|
}
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
2015-12-31 09:18:00 +00:00
|
|
|
Log.i(TAG, "Menu=" + item.getTitle());
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
// Handle item selection
|
2015-12-26 08:58:28 +00:00
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
2015-12-27 15:04:22 +00:00
|
|
|
switch (item.getItemId()) {
|
2015-12-26 08:58:28 +00:00
|
|
|
case R.id.menu_app_user:
|
2016-01-02 12:31:47 +00:00
|
|
|
item.setChecked(!item.isChecked());
|
|
|
|
prefs.edit().putBoolean("show_user", item.isChecked()).apply();
|
2015-12-26 08:58:28 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.menu_app_system:
|
2016-01-02 12:31:47 +00:00
|
|
|
item.setChecked(!item.isChecked());
|
|
|
|
prefs.edit().putBoolean("show_system", item.isChecked()).apply();
|
2015-12-26 08:58:28 +00:00
|
|
|
return true;
|
|
|
|
|
2015-12-27 08:54:25 +00:00
|
|
|
case R.id.menu_app_nointernet:
|
2016-01-02 12:31:47 +00:00
|
|
|
item.setChecked(!item.isChecked());
|
|
|
|
prefs.edit().putBoolean("show_nointernet", item.isChecked()).apply();
|
2015-12-27 08:54:25 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.menu_app_disabled:
|
2016-01-02 12:31:47 +00:00
|
|
|
item.setChecked(!item.isChecked());
|
|
|
|
prefs.edit().putBoolean("show_disabled", item.isChecked()).apply();
|
2015-12-27 08:54:25 +00:00
|
|
|
return true;
|
|
|
|
|
2015-12-28 08:09:07 +00:00
|
|
|
case R.id.menu_sort_name:
|
2016-01-01 08:29:19 +00:00
|
|
|
item.setChecked(true);
|
|
|
|
prefs.edit().putString("sort", "name").apply();
|
2015-12-28 08:09:07 +00:00
|
|
|
return true;
|
|
|
|
|
2016-03-09 17:21:38 +00:00
|
|
|
case R.id.menu_sort_uid:
|
|
|
|
item.setChecked(true);
|
|
|
|
prefs.edit().putString("sort", "uid").apply();
|
|
|
|
return true;
|
|
|
|
|
2017-03-21 08:06:04 +00:00
|
|
|
case R.id.menu_lockdown:
|
2017-03-23 07:29:32 +00:00
|
|
|
menu_lockdown(item);
|
2017-03-21 08:06:04 +00:00
|
|
|
return true;
|
|
|
|
|
2016-01-05 12:40:02 +00:00
|
|
|
case R.id.menu_log:
|
2017-04-11 05:49:28 +00:00
|
|
|
if (Util.canFilter(this))
|
|
|
|
if (IAB.isPurchased(ActivityPro.SKU_LOG, this))
|
|
|
|
startActivity(new Intent(this, ActivityLog.class));
|
|
|
|
else
|
|
|
|
startActivity(new Intent(this, ActivityPro.class));
|
2016-01-05 12:40:02 +00:00
|
|
|
else
|
2017-04-11 05:49:28 +00:00
|
|
|
Toast.makeText(this, R.string.msg_unavailable, Toast.LENGTH_SHORT).show();
|
2016-01-05 12:40:02 +00:00
|
|
|
return true;
|
|
|
|
|
2015-11-04 22:44:17 +00:00
|
|
|
case R.id.menu_settings:
|
2015-12-27 15:04:22 +00:00
|
|
|
startActivity(new Intent(this, ActivitySettings.class));
|
2015-10-26 17:47:31 +00:00
|
|
|
return true;
|
|
|
|
|
2015-12-30 08:58:21 +00:00
|
|
|
case R.id.menu_pro:
|
|
|
|
startActivity(new Intent(ActivityMain.this, ActivityPro.class));
|
|
|
|
return true;
|
|
|
|
|
2015-11-07 11:43:30 +00:00
|
|
|
case R.id.menu_invite:
|
|
|
|
startActivityForResult(getIntentInvite(this), REQUEST_INVITE);
|
|
|
|
return true;
|
|
|
|
|
2016-02-19 11:35:10 +00:00
|
|
|
case R.id.menu_legend:
|
|
|
|
menu_legend();
|
|
|
|
return true;
|
|
|
|
|
2015-10-30 07:05:47 +00:00
|
|
|
case R.id.menu_support:
|
2015-11-17 14:12:33 +00:00
|
|
|
startActivity(getIntentSupport());
|
2015-10-29 14:01:41 +00:00
|
|
|
return true;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
case R.id.menu_about:
|
2015-10-30 07:57:36 +00:00
|
|
|
menu_about();
|
2015-10-25 09:29:49 +00:00
|
|
|
return true;
|
|
|
|
|
2018-07-08 17:16:28 +00:00
|
|
|
case R.id.menu_apps:
|
|
|
|
menu_apps();
|
|
|
|
return true;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
default:
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
|
}
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
|
2016-07-25 05:53:23 +00:00
|
|
|
private void showHints() {
|
|
|
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
boolean hintUsage = prefs.getBoolean("hint_usage", true);
|
|
|
|
|
|
|
|
// Hint white listing
|
2017-08-05 08:27:27 +00:00
|
|
|
final LinearLayout llWhitelist = findViewById(R.id.llWhitelist);
|
|
|
|
Button btnWhitelist = findViewById(R.id.btnWhitelist);
|
2016-07-25 05:53:23 +00:00
|
|
|
boolean whitelist_wifi = prefs.getBoolean("whitelist_wifi", false);
|
|
|
|
boolean whitelist_other = prefs.getBoolean("whitelist_other", false);
|
|
|
|
boolean hintWhitelist = prefs.getBoolean("hint_whitelist", true);
|
|
|
|
llWhitelist.setVisibility(!(whitelist_wifi || whitelist_other) && hintWhitelist && !hintUsage ? View.VISIBLE : View.GONE);
|
|
|
|
btnWhitelist.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
prefs.edit().putBoolean("hint_whitelist", false).apply();
|
|
|
|
llWhitelist.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Hint push messages
|
2017-08-05 08:27:27 +00:00
|
|
|
final LinearLayout llPush = findViewById(R.id.llPush);
|
|
|
|
Button btnPush = findViewById(R.id.btnPush);
|
2016-07-25 05:53:23 +00:00
|
|
|
boolean hintPush = prefs.getBoolean("hint_push", true);
|
|
|
|
llPush.setVisibility(hintPush && !hintUsage ? View.VISIBLE : View.GONE);
|
|
|
|
btnPush.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
prefs.edit().putBoolean("hint_push", false).apply();
|
|
|
|
llPush.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Hint system applications
|
2017-08-05 08:27:27 +00:00
|
|
|
final LinearLayout llSystem = findViewById(R.id.llSystem);
|
|
|
|
Button btnSystem = findViewById(R.id.btnSystem);
|
2016-07-25 05:53:23 +00:00
|
|
|
boolean system = prefs.getBoolean("manage_system", false);
|
|
|
|
boolean hintSystem = prefs.getBoolean("hint_system", true);
|
2016-12-26 10:24:18 +00:00
|
|
|
llSystem.setVisibility(!system && hintSystem ? View.VISIBLE : View.GONE);
|
2016-07-25 05:53:23 +00:00
|
|
|
btnSystem.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
prefs.edit().putBoolean("hint_system", false).apply();
|
|
|
|
llSystem.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkExtras(Intent intent) {
|
|
|
|
// Approve request
|
|
|
|
if (intent.hasExtra(EXTRA_APPROVE)) {
|
|
|
|
Log.i(TAG, "Requesting VPN approval");
|
|
|
|
swEnabled.toggle();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (intent.hasExtra(EXTRA_LOGCAT)) {
|
|
|
|
Log.i(TAG, "Requesting logcat");
|
|
|
|
Intent logcat = getIntentLogcat();
|
|
|
|
if (logcat.resolveActivity(getPackageManager()) != null)
|
|
|
|
startActivityForResult(logcat, REQUEST_LOGCAT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateApplicationList(final String search) {
|
|
|
|
Log.i(TAG, "Update search=" + search);
|
|
|
|
|
|
|
|
new AsyncTask<Object, Object, List<Rule>>() {
|
|
|
|
private boolean refreshing = true;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPreExecute() {
|
|
|
|
swipeRefresh.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
if (refreshing)
|
|
|
|
swipeRefresh.setRefreshing(true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected List<Rule> doInBackground(Object... arg) {
|
2017-11-05 17:26:41 +00:00
|
|
|
return Rule.getRules(false, ActivityMain.this);
|
2016-07-25 05:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(List<Rule> result) {
|
|
|
|
if (running) {
|
|
|
|
if (adapter != null) {
|
|
|
|
adapter.set(result);
|
|
|
|
updateSearch(search);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (swipeRefresh != null) {
|
|
|
|
refreshing = false;
|
|
|
|
swipeRefresh.setRefreshing(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-07-02 06:56:37 +00:00
|
|
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
2016-07-25 05:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void updateSearch(String search) {
|
|
|
|
if (menuSearch != null) {
|
2017-08-05 08:27:27 +00:00
|
|
|
SearchView searchView = (SearchView) menuSearch.getActionView();
|
2016-07-25 05:53:23 +00:00
|
|
|
if (search == null) {
|
|
|
|
if (menuSearch.isActionViewExpanded())
|
|
|
|
adapter.getFilter().filter(searchView.getQuery().toString());
|
|
|
|
} else {
|
2017-08-05 08:27:27 +00:00
|
|
|
menuSearch.expandActionView();
|
2016-07-25 05:53:23 +00:00
|
|
|
searchView.setQuery(search, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkDoze() {
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
|
final Intent doze = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
|
|
|
|
if (Util.batteryOptimizing(this) && getPackageManager().resolveActivity(doze, 0) != null) {
|
|
|
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
if (!prefs.getBoolean("nodoze", false)) {
|
|
|
|
LayoutInflater inflater = LayoutInflater.from(this);
|
|
|
|
View view = inflater.inflate(R.layout.doze, null, false);
|
2017-08-05 08:27:27 +00:00
|
|
|
final CheckBox cbDontAsk = view.findViewById(R.id.cbDontAsk);
|
2016-07-25 05:53:23 +00:00
|
|
|
dialogDoze = new AlertDialog.Builder(this)
|
|
|
|
.setView(view)
|
|
|
|
.setCancelable(true)
|
|
|
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
prefs.edit().putBoolean("nodoze", cbDontAsk.isChecked()).apply();
|
|
|
|
startActivity(doze);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
prefs.edit().putBoolean("nodoze", cbDontAsk.isChecked()).apply();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
|
@Override
|
|
|
|
public void onDismiss(DialogInterface dialogInterface) {
|
|
|
|
dialogDoze = null;
|
|
|
|
checkDataSaving();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
|
|
|
dialogDoze.show();
|
|
|
|
} else
|
|
|
|
checkDataSaving();
|
|
|
|
} else
|
|
|
|
checkDataSaving();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkDataSaving() {
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
|
|
final Intent settings = new Intent(
|
|
|
|
Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS,
|
|
|
|
Uri.parse("package:" + getPackageName()));
|
2019-08-04 13:47:38 +00:00
|
|
|
if (Util.dataSaving(this) && getPackageManager().resolveActivity(settings, 0) != null)
|
|
|
|
try {
|
|
|
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
if (!prefs.getBoolean("nodata", false)) {
|
|
|
|
LayoutInflater inflater = LayoutInflater.from(this);
|
|
|
|
View view = inflater.inflate(R.layout.datasaving, null, false);
|
|
|
|
final CheckBox cbDontAsk = view.findViewById(R.id.cbDontAsk);
|
|
|
|
dialogDoze = new AlertDialog.Builder(this)
|
|
|
|
.setView(view)
|
|
|
|
.setCancelable(true)
|
|
|
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
prefs.edit().putBoolean("nodata", cbDontAsk.isChecked()).apply();
|
|
|
|
startActivity(settings);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
prefs.edit().putBoolean("nodata", cbDontAsk.isChecked()).apply();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
|
@Override
|
|
|
|
public void onDismiss(DialogInterface dialogInterface) {
|
|
|
|
dialogDoze = null;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
|
|
|
dialogDoze.show();
|
|
|
|
}
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex + "\n" + ex.getStackTrace());
|
2016-07-25 05:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-19 11:35:10 +00:00
|
|
|
private void menu_legend() {
|
2016-02-20 07:53:39 +00:00
|
|
|
TypedValue tv = new TypedValue();
|
|
|
|
getTheme().resolveAttribute(R.attr.colorOn, tv, true);
|
|
|
|
int colorOn = tv.data;
|
|
|
|
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
|
|
|
|
int colorOff = tv.data;
|
|
|
|
|
2016-02-19 11:35:10 +00:00
|
|
|
// Create view
|
|
|
|
LayoutInflater inflater = LayoutInflater.from(this);
|
|
|
|
View view = inflater.inflate(R.layout.legend, null, false);
|
2017-08-05 08:27:27 +00:00
|
|
|
ImageView ivLockdownOn = view.findViewById(R.id.ivLockdownOn);
|
|
|
|
ImageView ivWifiOn = view.findViewById(R.id.ivWifiOn);
|
|
|
|
ImageView ivWifiOff = view.findViewById(R.id.ivWifiOff);
|
|
|
|
ImageView ivOtherOn = view.findViewById(R.id.ivOtherOn);
|
|
|
|
ImageView ivOtherOff = view.findViewById(R.id.ivOtherOff);
|
|
|
|
ImageView ivScreenOn = view.findViewById(R.id.ivScreenOn);
|
|
|
|
ImageView ivHostAllowed = view.findViewById(R.id.ivHostAllowed);
|
|
|
|
ImageView ivHostBlocked = view.findViewById(R.id.ivHostBlocked);
|
2016-02-20 07:53:39 +00:00
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
2017-03-21 08:06:04 +00:00
|
|
|
Drawable wrapLockdownOn = DrawableCompat.wrap(ivLockdownOn.getDrawable());
|
2016-02-20 07:53:39 +00:00
|
|
|
Drawable wrapWifiOn = DrawableCompat.wrap(ivWifiOn.getDrawable());
|
|
|
|
Drawable wrapWifiOff = DrawableCompat.wrap(ivWifiOff.getDrawable());
|
|
|
|
Drawable wrapOtherOn = DrawableCompat.wrap(ivOtherOn.getDrawable());
|
|
|
|
Drawable wrapOtherOff = DrawableCompat.wrap(ivOtherOff.getDrawable());
|
|
|
|
Drawable wrapScreenOn = DrawableCompat.wrap(ivScreenOn.getDrawable());
|
|
|
|
Drawable wrapHostAllowed = DrawableCompat.wrap(ivHostAllowed.getDrawable());
|
|
|
|
Drawable wrapHostBlocked = DrawableCompat.wrap(ivHostBlocked.getDrawable());
|
|
|
|
|
2017-03-21 08:06:04 +00:00
|
|
|
DrawableCompat.setTint(wrapLockdownOn, colorOff);
|
2016-02-20 07:53:39 +00:00
|
|
|
DrawableCompat.setTint(wrapWifiOn, colorOn);
|
|
|
|
DrawableCompat.setTint(wrapWifiOff, colorOff);
|
|
|
|
DrawableCompat.setTint(wrapOtherOn, colorOn);
|
|
|
|
DrawableCompat.setTint(wrapOtherOff, colorOff);
|
|
|
|
DrawableCompat.setTint(wrapScreenOn, colorOn);
|
|
|
|
DrawableCompat.setTint(wrapHostAllowed, colorOn);
|
|
|
|
DrawableCompat.setTint(wrapHostBlocked, colorOff);
|
|
|
|
}
|
|
|
|
|
2016-02-19 11:35:10 +00:00
|
|
|
|
|
|
|
// Show dialog
|
|
|
|
dialogLegend = new AlertDialog.Builder(this)
|
|
|
|
.setView(view)
|
|
|
|
.setCancelable(true)
|
|
|
|
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
|
@Override
|
|
|
|
public void onDismiss(DialogInterface dialogInterface) {
|
|
|
|
dialogLegend = null;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
|
|
|
dialogLegend.show();
|
|
|
|
}
|
|
|
|
|
2017-03-23 07:29:32 +00:00
|
|
|
private void menu_lockdown(MenuItem item) {
|
|
|
|
item.setChecked(!item.isChecked());
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
prefs.edit().putBoolean("lockdown", item.isChecked()).apply();
|
2017-07-22 12:48:00 +00:00
|
|
|
ServiceSinkhole.reload("lockdown", this, false);
|
2017-03-23 07:29:32 +00:00
|
|
|
WidgetLockdown.updateWidgets(this);
|
|
|
|
}
|
|
|
|
|
2015-10-30 07:57:36 +00:00
|
|
|
private void menu_about() {
|
2015-10-30 15:51:24 +00:00
|
|
|
// Create view
|
2015-10-30 07:57:36 +00:00
|
|
|
LayoutInflater inflater = LayoutInflater.from(this);
|
2016-02-13 14:55:22 +00:00
|
|
|
View view = inflater.inflate(R.layout.about, null, false);
|
2017-08-05 08:27:27 +00:00
|
|
|
TextView tvVersionName = view.findViewById(R.id.tvVersionName);
|
|
|
|
TextView tvVersionCode = view.findViewById(R.id.tvVersionCode);
|
|
|
|
Button btnRate = view.findViewById(R.id.btnRate);
|
2018-07-14 15:37:33 +00:00
|
|
|
TextView tvEula = view.findViewById(R.id.tvEula);
|
2017-08-14 07:22:34 +00:00
|
|
|
TextView tvPrivacy = view.findViewById(R.id.tvPrivacy);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
|
|
|
// Show version
|
2016-03-05 14:06:51 +00:00
|
|
|
tvVersionName.setText(Util.getSelfVersionName(this));
|
2015-11-20 10:34:23 +00:00
|
|
|
if (!Util.hasValidFingerprint(this))
|
2016-03-05 14:06:51 +00:00
|
|
|
tvVersionName.setTextColor(Color.GRAY);
|
|
|
|
tvVersionCode.setText(Integer.toString(Util.getSelfVersionCode(this)));
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-12-30 08:00:34 +00:00
|
|
|
// Handle license
|
2018-07-14 15:37:33 +00:00
|
|
|
tvEula.setMovementMethod(LinkMovementMethod.getInstance());
|
2017-08-14 07:22:34 +00:00
|
|
|
tvPrivacy.setMovementMethod(LinkMovementMethod.getInstance());
|
2015-11-01 06:31:36 +00:00
|
|
|
|
2015-10-30 15:51:24 +00:00
|
|
|
// Handle logcat
|
2015-11-13 11:38:02 +00:00
|
|
|
view.setOnClickListener(new View.OnClickListener() {
|
|
|
|
private short tap = 0;
|
2015-11-20 20:16:10 +00:00
|
|
|
private Toast toast = Toast.makeText(ActivityMain.this, "", Toast.LENGTH_SHORT);
|
2015-11-13 11:38:02 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
2015-11-20 20:16:10 +00:00
|
|
|
tap++;
|
|
|
|
if (tap == 7) {
|
2015-11-13 11:38:02 +00:00
|
|
|
tap = 0;
|
2015-11-20 20:16:10 +00:00
|
|
|
toast.cancel();
|
2015-11-26 19:34:03 +00:00
|
|
|
|
|
|
|
Intent intent = getIntentLogcat();
|
|
|
|
if (intent.resolveActivity(getPackageManager()) != null)
|
2016-01-31 12:32:58 +00:00
|
|
|
startActivityForResult(intent, REQUEST_LOGCAT);
|
2015-11-26 19:34:03 +00:00
|
|
|
|
2015-11-20 20:16:10 +00:00
|
|
|
} else if (tap > 3) {
|
|
|
|
toast.setText(Integer.toString(7 - tap));
|
|
|
|
toast.show();
|
2015-10-30 07:57:36 +00:00
|
|
|
}
|
2015-11-13 11:38:02 +00:00
|
|
|
}
|
|
|
|
});
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-11-07 16:51:13 +00:00
|
|
|
// Handle rate
|
|
|
|
btnRate.setVisibility(getIntentRate(this).resolveActivity(getPackageManager()) == null ? View.GONE : View.VISIBLE);
|
|
|
|
btnRate.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
startActivity(getIntentRate(ActivityMain.this));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-10-30 15:51:24 +00:00
|
|
|
// Show dialog
|
2015-11-02 18:53:56 +00:00
|
|
|
dialogAbout = new AlertDialog.Builder(this)
|
2015-10-30 07:57:36 +00:00
|
|
|
.setView(view)
|
2015-10-30 15:51:24 +00:00
|
|
|
.setCancelable(true)
|
|
|
|
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
|
@Override
|
|
|
|
public void onDismiss(DialogInterface dialogInterface) {
|
2015-11-02 18:53:56 +00:00
|
|
|
dialogAbout = null;
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
2015-11-02 18:53:56 +00:00
|
|
|
dialogAbout.show();
|
2015-10-30 07:57:36 +00:00
|
|
|
}
|
|
|
|
|
2018-07-08 17:16:28 +00:00
|
|
|
private void menu_apps() {
|
|
|
|
startActivity(getIntentApps(this));
|
|
|
|
}
|
|
|
|
|
2018-07-09 06:40:27 +00:00
|
|
|
private static Intent getIntentPro(Context context) {
|
2018-09-29 13:04:30 +00:00
|
|
|
if (Util.isPlayStoreInstall(context))
|
|
|
|
return new Intent(context, ActivityPro.class);
|
|
|
|
else {
|
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
|
intent.setData(Uri.parse("https://contact.faircode.eu/?product=netguardstandalone"));
|
|
|
|
return intent;
|
|
|
|
}
|
2018-07-09 06:40:27 +00:00
|
|
|
}
|
|
|
|
|
2015-11-07 11:43:30 +00:00
|
|
|
private static Intent getIntentInvite(Context context) {
|
2018-12-16 09:17:49 +00:00
|
|
|
Intent intent = new Intent(Intent.ACTION_SEND);
|
|
|
|
intent.setType("text/plain");
|
|
|
|
intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.app_name));
|
|
|
|
intent.putExtra(Intent.EXTRA_TEXT, context.getString(R.string.msg_try) + "\n\nhttps://www.netguard.me/\n\n");
|
2015-11-08 09:14:56 +00:00
|
|
|
return intent;
|
2015-11-07 11:43:30 +00:00
|
|
|
}
|
|
|
|
|
2018-07-08 17:16:28 +00:00
|
|
|
private static Intent getIntentApps(Context context) {
|
2018-08-16 19:23:52 +00:00
|
|
|
return new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/dev?id=8420080860664580239"));
|
2018-07-08 17:16:28 +00:00
|
|
|
}
|
|
|
|
|
2015-11-07 16:51:13 +00:00
|
|
|
private static Intent getIntentRate(Context context) {
|
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName()));
|
|
|
|
if (intent.resolveActivity(context.getPackageManager()) == null)
|
|
|
|
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName()));
|
|
|
|
return intent;
|
|
|
|
}
|
|
|
|
|
2015-11-01 06:38:52 +00:00
|
|
|
private static Intent getIntentSupport() {
|
2015-10-31 20:48:09 +00:00
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
2015-11-17 15:24:13 +00:00
|
|
|
intent.setData(Uri.parse("https://github.com/M66B/NetGuard/blob/master/FAQ.md"));
|
2015-10-31 20:48:09 +00:00
|
|
|
return intent;
|
|
|
|
}
|
2015-11-26 19:34:03 +00:00
|
|
|
|
|
|
|
private Intent getIntentLogcat() {
|
2016-06-26 17:32:06 +00:00
|
|
|
Intent intent;
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
|
|
|
if (Util.isPackageInstalled("org.openintents.filemanager", this)) {
|
|
|
|
intent = new Intent("org.openintents.action.PICK_DIRECTORY");
|
|
|
|
} else {
|
|
|
|
intent = new Intent(Intent.ACTION_VIEW);
|
|
|
|
intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=org.openintents.filemanager"));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
|
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
|
|
intent.setType("text/plain");
|
|
|
|
intent.putExtra(Intent.EXTRA_TITLE, "logcat.txt");
|
|
|
|
}
|
2015-11-26 19:34:03 +00:00
|
|
|
return intent;
|
|
|
|
}
|
2016-02-19 09:39:29 +00:00
|
|
|
}
|