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-30 15:51:24 +00:00
|
|
|
import android.app.PendingIntent;
|
2015-10-25 14:22:55 +00:00
|
|
|
import android.content.BroadcastReceiver;
|
2015-10-30 15:51:24 +00:00
|
|
|
import android.content.ComponentName;
|
2015-10-25 14:22:55 +00:00
|
|
|
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-30 15:51:24 +00:00
|
|
|
import android.content.ServiceConnection;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.content.SharedPreferences;
|
2015-10-31 13:15:26 +00:00
|
|
|
import android.graphics.Color;
|
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;
|
2015-10-30 15:51:24 +00:00
|
|
|
import android.os.IBinder;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.preference.PreferenceManager;
|
2015-10-30 15:51:24 +00:00
|
|
|
import android.support.v4.content.LocalBroadcastManager;
|
2015-10-25 10:11:46 +00:00
|
|
|
import android.support.v4.view.MenuItemCompat;
|
2015-10-31 13:15:26 +00:00
|
|
|
import android.support.v4.widget.SwipeRefreshLayout;
|
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-11-01 06:31:36 +00:00
|
|
|
import android.text.method.LinkMovementMethod;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.util.Log;
|
2015-10-31 19:02:22 +00:00
|
|
|
import android.util.Xml;
|
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;
|
2015-10-24 18:01:55 +00:00
|
|
|
import android.widget.CompoundButton;
|
2015-11-02 05:29:09 +00:00
|
|
|
import android.widget.ImageView;
|
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
|
|
|
|
2015-10-30 15:51:24 +00:00
|
|
|
import com.android.vending.billing.IInAppBillingService;
|
|
|
|
|
|
|
|
import org.json.JSONObject;
|
2015-10-31 19:02:22 +00:00
|
|
|
import org.xml.sax.Attributes;
|
|
|
|
import org.xml.sax.InputSource;
|
|
|
|
import org.xml.sax.SAXException;
|
|
|
|
import org.xml.sax.XMLReader;
|
|
|
|
import org.xml.sax.helpers.DefaultHandler;
|
|
|
|
import org.xmlpull.v1.XmlSerializer;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2015-10-31 19:47:48 +00:00
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.OutputStream;
|
2015-10-30 15:51:24 +00:00
|
|
|
import java.util.ArrayList;
|
2015-10-31 19:02:22 +00:00
|
|
|
import java.util.HashMap;
|
2015-10-24 18:01:55 +00:00
|
|
|
import java.util.List;
|
2015-10-31 19:02:22 +00:00
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
|
|
import javax.xml.parsers.SAXParserFactory;
|
2015-10-24 18:01:55 +00:00
|
|
|
|
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;
|
2015-11-02 05:29:09 +00:00
|
|
|
private ImageView ivInteractive;
|
|
|
|
private ImageView ivWifi;
|
|
|
|
private ImageView ivOther;
|
|
|
|
private ImageView ivRoaming;
|
2015-10-31 13:15:26 +00:00
|
|
|
private SwipeRefreshLayout swipeRefresh;
|
2015-10-24 18:01:55 +00:00
|
|
|
private RuleAdapter adapter = null;
|
2015-10-29 08:56:22 +00:00
|
|
|
private MenuItem menuSearch = null;
|
2015-11-02 12:37:33 +00:00
|
|
|
private IInAppBillingService IABService = 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-30 15:51:24 +00:00
|
|
|
private static final int REQUEST_DONATION = 2;
|
2015-10-31 19:47:48 +00:00
|
|
|
private static final int REQUEST_EXPORT = 3;
|
|
|
|
private static final int REQUEST_IMPORT = 4;
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-10-30 17:44:20 +00:00
|
|
|
// adb shell pm clear com.android.vending
|
2015-11-02 13:36:14 +00:00
|
|
|
private static final String SKU_DONATE = "donation";
|
|
|
|
// private static final String SKU_DONATE = "android.test.purchased";
|
2015-10-31 08:11:23 +00:00
|
|
|
private static final String ACTION_IAB = "eu.faircode.netguard.IAB";
|
2015-10-25 09:29:49 +00:00
|
|
|
|
2015-10-31 20:48:09 +00:00
|
|
|
private static final Intent INTENT_VPN_SETTINGS = new Intent("android.net.vpn.SETTINGS");
|
|
|
|
|
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-29 16:33:06 +00:00
|
|
|
boolean enabled = prefs.getBoolean("enabled", false);
|
2015-10-24 18:01:55 +00:00
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
// Action bar
|
2015-11-02 05:29:09 +00:00
|
|
|
View actionView = getLayoutInflater().inflate(R.layout.action, null);
|
|
|
|
SwitchCompat swEnabled = (SwitchCompat) actionView.findViewById(R.id.swEnabled);
|
|
|
|
ivInteractive = (ImageView) actionView.findViewById(R.id.ivInteractive);
|
|
|
|
ivWifi = (ImageView) actionView.findViewById(R.id.ivWifi);
|
|
|
|
ivOther = (ImageView) actionView.findViewById(R.id.ivOther);
|
|
|
|
ivRoaming = (ImageView) actionView.findViewById(R.id.ivRoaming);
|
2015-10-24 18:01:55 +00:00
|
|
|
getSupportActionBar().setDisplayShowCustomEnabled(true);
|
2015-11-02 05:29:09 +00:00
|
|
|
getSupportActionBar().setCustomView(actionView);
|
2015-10-24 18:01:55 +00:00
|
|
|
|
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) {
|
|
|
|
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-29 06:47:12 +00:00
|
|
|
SinkholeService.stop(ActivityMain.this);
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-10-31 13:15:26 +00:00
|
|
|
// Disabled warning
|
|
|
|
TextView tvDisabled = (TextView) findViewById(R.id.tvDisabled);
|
|
|
|
tvDisabled.setVisibility(enabled ? View.GONE : View.VISIBLE);
|
|
|
|
|
|
|
|
// Application list
|
|
|
|
RecyclerView rvApplication = (RecyclerView) findViewById(R.id.rvApplication);
|
|
|
|
rvApplication.setHasFixedSize(true);
|
|
|
|
rvApplication.setLayoutManager(new LinearLayoutManager(this));
|
|
|
|
adapter = new RuleAdapter(ActivityMain.this);
|
|
|
|
rvApplication.setAdapter(adapter);
|
2015-10-25 09:29:49 +00:00
|
|
|
|
2015-10-31 13:23:18 +00:00
|
|
|
// Swipe to refresh
|
2015-10-31 13:15:26 +00:00
|
|
|
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
|
|
|
|
swipeRefresh.setColorSchemeColors(Color.WHITE, Color.WHITE, Color.WHITE);
|
|
|
|
swipeRefresh.setProgressBackgroundColorSchemeResource(R.color.colorPrimary);
|
|
|
|
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
|
|
|
@Override
|
|
|
|
public void onRefresh() {
|
|
|
|
updateApplicationList();
|
|
|
|
}
|
|
|
|
});
|
2015-10-31 13:23:18 +00:00
|
|
|
|
|
|
|
// Fill application list
|
|
|
|
updateApplicationList();
|
2015-10-31 13:15:26 +00:00
|
|
|
|
|
|
|
// Listen for preference changes
|
|
|
|
prefs.registerOnSharedPreferenceChangeListener(this);
|
2015-10-25 14:22:55 +00:00
|
|
|
|
2015-11-02 05:29:09 +00:00
|
|
|
// Listen for interactive state changes
|
|
|
|
IntentFilter ifInteractive = new IntentFilter();
|
|
|
|
ifInteractive.addAction(Intent.ACTION_SCREEN_ON);
|
|
|
|
ifInteractive.addAction(Intent.ACTION_SCREEN_OFF);
|
|
|
|
registerReceiver(interactiveStateReceiver, ifInteractive);
|
|
|
|
|
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);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
|
|
|
// Connect to billing
|
2015-11-02 13:48:08 +00:00
|
|
|
if (Util.hasValidFingerprint(TAG, this)) {
|
|
|
|
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
|
|
|
|
serviceIntent.setPackage("com.android.vending");
|
|
|
|
bindService(serviceIntent, IABConnection, Context.BIND_AUTO_CREATE);
|
|
|
|
}
|
2015-11-02 12:22:58 +00:00
|
|
|
|
|
|
|
// First use
|
|
|
|
if (!prefs.getBoolean("initialized", false)) {
|
|
|
|
// Create view
|
|
|
|
LayoutInflater inflater = LayoutInflater.from(this);
|
|
|
|
View view = inflater.inflate(R.layout.first, null);
|
|
|
|
TextView tvFirst = (TextView) view.findViewById(R.id.tvFirst);
|
|
|
|
tvFirst.setMovementMethod(LinkMovementMethod.getInstance());
|
|
|
|
|
|
|
|
// Show dialog
|
|
|
|
AlertDialog dialog = new AlertDialog.Builder(this)
|
|
|
|
.setView(view)
|
|
|
|
.setCancelable(false)
|
|
|
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialogInterface, int i) {
|
|
|
|
prefs.edit().putBoolean("initialized", true).apply();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialogInterface, int i) {
|
|
|
|
System.exit(0);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
|
|
|
dialog.show();
|
|
|
|
}
|
2015-10-25 14:22:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
Log.i(TAG, "Destroy");
|
|
|
|
running = false;
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
|
2015-11-02 05:29:09 +00:00
|
|
|
|
|
|
|
unregisterReceiver(interactiveStateReceiver);
|
2015-10-26 12:19:52 +00:00
|
|
|
unregisterReceiver(connectivityChangedReceiver);
|
2015-10-25 14:22:55 +00:00
|
|
|
unregisterReceiver(packageChangedReceiver);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-11-02 12:39:28 +00:00
|
|
|
if (IABService != null)
|
2015-11-02 12:37:33 +00:00
|
|
|
unbindService(IABConnection);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-10-25 14:22:55 +00:00
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
2015-11-02 05:29:09 +00:00
|
|
|
private BroadcastReceiver interactiveStateReceiver = new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
Log.i(TAG, "Received " + intent);
|
|
|
|
Util.logExtras(TAG, intent);
|
|
|
|
|
2015-11-02 12:22:58 +00:00
|
|
|
ivInteractive.setVisibility(Intent.ACTION_SCREEN_ON.equals(intent.getAction()) ? View.VISIBLE : View.INVISIBLE);
|
2015-11-02 05:29:09 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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);
|
2015-11-02 05:29:09 +00:00
|
|
|
|
|
|
|
ivWifi.setVisibility(View.GONE);
|
|
|
|
ivOther.setVisibility(View.GONE);
|
|
|
|
ivRoaming.setVisibility(View.GONE);
|
|
|
|
|
|
|
|
if (Util.isWifiActive(context))
|
|
|
|
ivWifi.setVisibility(View.VISIBLE);
|
|
|
|
else if (Util.isRoaming(context))
|
|
|
|
ivRoaming.setVisibility(View.VISIBLE);
|
|
|
|
else
|
|
|
|
ivOther.setVisibility(View.VISIBLE);
|
2015-10-26 12:19:52 +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-10-26 12:19:52 +00:00
|
|
|
Util.logExtras(TAG, intent);
|
2015-10-31 13:15:26 +00:00
|
|
|
updateApplicationList();
|
2015-10-25 14:22:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-11-02 12:37:33 +00:00
|
|
|
private ServiceConnection IABConnection = new ServiceConnection() {
|
2015-10-30 15:51:24 +00:00
|
|
|
@Override
|
|
|
|
public void onServiceDisconnected(ComponentName name) {
|
2015-11-02 12:37:33 +00:00
|
|
|
Log.i(TAG, "IAB disconnected");
|
|
|
|
IABService = null;
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
2015-11-02 12:37:33 +00:00
|
|
|
Log.i(TAG, "IAB connected");
|
|
|
|
IABService = IInAppBillingService.Stub.asInterface(service);
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-10-31 13:15:26 +00:00
|
|
|
private void updateApplicationList() {
|
2015-10-24 18:01:55 +00:00
|
|
|
new AsyncTask<Object, Object, List<Rule>>() {
|
2015-10-31 19:52:24 +00:00
|
|
|
private boolean refreshing = true;
|
|
|
|
|
2015-10-31 17:12:57 +00:00
|
|
|
@Override
|
|
|
|
protected void onPreExecute() {
|
|
|
|
swipeRefresh.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2015-10-31 19:52:24 +00:00
|
|
|
if (refreshing)
|
|
|
|
swipeRefresh.setRefreshing(true);
|
2015-10-31 17:12:57 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
@Override
|
|
|
|
protected List<Rule> doInBackground(Object... arg) {
|
2015-11-01 08:38:51 +00:00
|
|
|
return Rule.getRules(false, TAG, ActivityMain.this);
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(List<Rule> result) {
|
|
|
|
if (running) {
|
2015-10-31 17:12:57 +00:00
|
|
|
if (adapter != null)
|
|
|
|
adapter.set(result);
|
2015-11-01 13:28:03 +00:00
|
|
|
if (menuSearch != null)
|
|
|
|
MenuItemCompat.collapseActionView(menuSearch);
|
2015-10-31 19:52:24 +00:00
|
|
|
if (swipeRefresh != null) {
|
|
|
|
refreshing = false;
|
2015-10-31 13:15:26 +00:00
|
|
|
swipeRefresh.setRefreshing(false);
|
2015-10-31 19:52:24 +00:00
|
|
|
}
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}.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
|
|
|
|
2015-10-29 16:33:06 +00:00
|
|
|
// Display disabled warning
|
|
|
|
TextView tvDisabled = (TextView) findViewById(R.id.tvDisabled);
|
|
|
|
tvDisabled.setVisibility(enabled ? View.GONE : View.VISIBLE);
|
|
|
|
|
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-29 08:56:22 +00:00
|
|
|
menuSearch = menu.findItem(R.id.menu_search);
|
|
|
|
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuSearch);
|
2015-10-25 10:11:46 +00:00
|
|
|
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-11-01 06:38:52 +00:00
|
|
|
menu.findItem(R.id.menu_whitelist_wifi).setChecked(prefs.getBoolean("whitelist_wifi", true));
|
|
|
|
menu.findItem(R.id.menu_whitelist_other).setChecked(prefs.getBoolean("whitelist_other", true));
|
2015-11-01 13:16:57 +00:00
|
|
|
menu.findItem(R.id.menu_whitelist_roaming).setChecked(prefs.getBoolean("whitelist_roaming", true));
|
2015-11-01 06:38:52 +00:00
|
|
|
menu.findItem(R.id.menu_system).setChecked(prefs.getBoolean("manage_system", false));
|
|
|
|
menu.findItem(R.id.menu_export).setEnabled(getIntentCreateDocument().resolveActivity(getPackageManager()) != null);
|
|
|
|
menu.findItem(R.id.menu_import).setEnabled(getIntentOpenDocument().resolveActivity(getPackageManager()) != null);
|
|
|
|
menu.findItem(R.id.menu_theme).setChecked(prefs.getBoolean("dark_theme", false));
|
|
|
|
menu.findItem(R.id.menu_vpn_settings).setEnabled(INTENT_VPN_SETTINGS.resolveActivity(getPackageManager()) != null);
|
|
|
|
menu.findItem(R.id.menu_support).setEnabled(getIntentSupport().resolveActivity(getPackageManager()) != null);
|
2015-10-31 20:48:09 +00:00
|
|
|
|
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-25 22:04:10 +00:00
|
|
|
case R.id.menu_whitelist_wifi:
|
2015-10-30 07:57:36 +00:00
|
|
|
menu_whitelist_wifi(prefs);
|
2015-10-25 11:52:54 +00:00
|
|
|
return true;
|
|
|
|
|
2015-10-25 22:04:10 +00:00
|
|
|
case R.id.menu_whitelist_other:
|
2015-10-30 07:57:36 +00:00
|
|
|
menu_whitelist_other(prefs);
|
2015-10-25 11:52:54 +00:00
|
|
|
return true;
|
|
|
|
|
2015-11-01 13:16:57 +00:00
|
|
|
case R.id.menu_whitelist_roaming:
|
|
|
|
menu_whitelist_roaming(prefs);
|
|
|
|
return true;
|
|
|
|
|
2015-10-31 17:07:21 +00:00
|
|
|
case R.id.menu_system:
|
|
|
|
menu_system(prefs);
|
|
|
|
return true;
|
|
|
|
|
2015-10-31 19:02:22 +00:00
|
|
|
case R.id.menu_export:
|
2015-11-01 06:38:52 +00:00
|
|
|
startActivityForResult(getIntentCreateDocument(), REQUEST_EXPORT);
|
2015-10-31 19:02:22 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.menu_import:
|
2015-11-01 06:38:52 +00:00
|
|
|
startActivityForResult(getIntentOpenDocument(), REQUEST_IMPORT);
|
2015-10-31 19:02:22 +00:00
|
|
|
return true;
|
|
|
|
|
2015-10-30 07:57:36 +00:00
|
|
|
case R.id.menu_theme:
|
|
|
|
menu_theme(prefs);
|
2015-10-26 17:47:31 +00:00
|
|
|
return true;
|
|
|
|
|
2015-10-25 09:29:49 +00:00
|
|
|
case R.id.menu_vpn_settings:
|
2015-10-31 20:48:09 +00:00
|
|
|
startActivity(INTENT_VPN_SETTINGS);
|
2015-10-25 15:48:41 +00:00
|
|
|
return true;
|
|
|
|
|
2015-10-30 07:05:47 +00:00
|
|
|
case R.id.menu_support:
|
2015-10-31 20:48:09 +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;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
|
}
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-30 07:57:36 +00:00
|
|
|
private void menu_whitelist_wifi(SharedPreferences prefs) {
|
|
|
|
prefs.edit().putBoolean("whitelist_wifi", !prefs.getBoolean("whitelist_wifi", true)).apply();
|
2015-10-31 13:15:26 +00:00
|
|
|
updateApplicationList();
|
2015-10-30 07:57:36 +00:00
|
|
|
SinkholeService.reload("wifi", this);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void menu_whitelist_other(SharedPreferences prefs) {
|
|
|
|
prefs.edit().putBoolean("whitelist_other", !prefs.getBoolean("whitelist_other", true)).apply();
|
2015-10-31 13:15:26 +00:00
|
|
|
updateApplicationList();
|
2015-10-30 07:57:36 +00:00
|
|
|
SinkholeService.reload("other", this);
|
|
|
|
}
|
|
|
|
|
2015-11-01 13:16:57 +00:00
|
|
|
private void menu_whitelist_roaming(SharedPreferences prefs) {
|
|
|
|
prefs.edit().putBoolean("whitelist_roaming", !prefs.getBoolean("whitelist_roaming", true)).apply();
|
|
|
|
updateApplicationList();
|
|
|
|
SinkholeService.reload("other", this);
|
|
|
|
}
|
|
|
|
|
2015-10-31 17:07:21 +00:00
|
|
|
private void menu_system(SharedPreferences prefs) {
|
2015-11-01 13:17:20 +00:00
|
|
|
prefs.edit().putBoolean("manage_system", !prefs.getBoolean("manage_system", false)).apply();
|
2015-10-31 17:07:21 +00:00
|
|
|
updateApplicationList();
|
|
|
|
SinkholeService.reload(null, this);
|
|
|
|
}
|
|
|
|
|
2015-10-30 07:57:36 +00:00
|
|
|
private void menu_theme(SharedPreferences prefs) {
|
|
|
|
prefs.edit().putBoolean("dark_theme", !prefs.getBoolean("dark_theme", false)).apply();
|
|
|
|
recreate();
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
View view = inflater.inflate(R.layout.about, null);
|
|
|
|
TextView tvVersion = (TextView) view.findViewById(R.id.tvVersion);
|
2015-10-30 15:51:24 +00:00
|
|
|
final Button btnDonate = (Button) view.findViewById(R.id.btnDonate);
|
|
|
|
final TextView tvThanks = (TextView) view.findViewById(R.id.tvThanks);
|
2015-11-01 06:31:36 +00:00
|
|
|
TextView tvLicense = (TextView) view.findViewById(R.id.tvLicense);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
|
|
|
// Show version
|
2015-10-30 07:57:36 +00:00
|
|
|
tvVersion.setText(Util.getSelfVersionName(this));
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-11-01 06:31:36 +00:00
|
|
|
// Handle license
|
|
|
|
tvLicense.setMovementMethod(LinkMovementMethod.getInstance());
|
|
|
|
|
2015-10-30 15:51:24 +00:00
|
|
|
// Handle logcat
|
2015-11-02 13:48:08 +00:00
|
|
|
if (Util.hasValidFingerprint(TAG, this))
|
2015-10-31 08:11:23 +00:00
|
|
|
view.setOnClickListener(new View.OnClickListener() {
|
|
|
|
private short tap = 0;
|
2015-10-30 07:57:36 +00:00
|
|
|
|
2015-10-31 08:11:23 +00:00
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
if (++tap == 7) {
|
|
|
|
tap = 0;
|
|
|
|
Util.sendLogcat(TAG, ActivityMain.this);
|
|
|
|
}
|
2015-10-30 07:57:36 +00:00
|
|
|
}
|
2015-10-31 08:11:23 +00:00
|
|
|
});
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-10-30 19:30:16 +00:00
|
|
|
// Handle donate
|
2015-10-31 08:11:23 +00:00
|
|
|
final Intent donate = new Intent(Intent.ACTION_VIEW);
|
|
|
|
donate.setData(Uri.parse("http://www.netguard.me/"));
|
2015-10-30 15:51:24 +00:00
|
|
|
btnDonate.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
2015-11-02 13:48:08 +00:00
|
|
|
if (IABService != null)
|
2015-10-31 08:11:23 +00:00
|
|
|
IABinitiate();
|
|
|
|
else
|
|
|
|
startActivity(donate);
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Handle donated
|
2015-10-31 08:11:23 +00:00
|
|
|
final BroadcastReceiver onIABsuccess = new BroadcastReceiver() {
|
2015-10-30 15:51:24 +00:00
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
btnDonate.setVisibility(View.GONE);
|
|
|
|
tvThanks.setVisibility(View.VISIBLE);
|
|
|
|
}
|
|
|
|
};
|
2015-10-31 08:11:23 +00:00
|
|
|
IntentFilter iff = new IntentFilter(ACTION_IAB);
|
|
|
|
LocalBroadcastManager.getInstance(this).registerReceiver(onIABsuccess, iff);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
|
|
|
// Show dialog
|
2015-10-30 07:57:36 +00:00
|
|
|
AlertDialog dialog = new AlertDialog.Builder(this)
|
|
|
|
.setView(view)
|
2015-10-30 15:51:24 +00:00
|
|
|
.setCancelable(true)
|
|
|
|
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
|
@Override
|
|
|
|
public void onDismiss(DialogInterface dialogInterface) {
|
2015-10-31 08:11:23 +00:00
|
|
|
LocalBroadcastManager.getInstance(ActivityMain.this).unregisterReceiver(onIABsuccess);
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
2015-10-30 07:57:36 +00:00
|
|
|
dialog.show();
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-10-31 08:11:23 +00:00
|
|
|
// Validate IAB
|
2015-11-02 13:48:08 +00:00
|
|
|
if (IABService != null)
|
2015-10-31 08:11:23 +00:00
|
|
|
new AsyncTask<Object, Object, Boolean>() {
|
2015-10-30 15:51:24 +00:00
|
|
|
@Override
|
2015-10-31 08:11:23 +00:00
|
|
|
protected Boolean doInBackground(Object... objects) {
|
|
|
|
return IABvalidate();
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2015-10-31 08:11:23 +00:00
|
|
|
protected void onPostExecute(Boolean ok) {
|
|
|
|
btnDonate.setVisibility(ok ? View.GONE : View.VISIBLE);
|
|
|
|
tvThanks.setVisibility(ok ? View.VISIBLE : View.GONE);
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
}.execute();
|
2015-10-31 08:11:23 +00:00
|
|
|
else
|
|
|
|
btnDonate.setVisibility(donate.resolveActivity(getPackageManager()) == null ? View.GONE : View.VISIBLE);
|
2015-10-30 07:57:36 +00:00
|
|
|
}
|
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
@Override
|
2015-10-31 19:47:48 +00:00
|
|
|
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
|
2015-10-30 18:57:18 +00:00
|
|
|
Log.i(TAG, "onActivityResult request=" + requestCode + " result=" + requestCode + " ok=" + (resultCode == RESULT_OK));
|
2015-11-02 12:44:22 +00:00
|
|
|
Util.logExtras(TAG, data);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
2015-10-24 18:01:55 +00:00
|
|
|
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)
|
2015-10-29 06:47:12 +00:00
|
|
|
SinkholeService.start(this);
|
2015-10-30 15:51:24 +00:00
|
|
|
|
|
|
|
} else if (requestCode == REQUEST_DONATION) {
|
|
|
|
if (resultCode == RESULT_OK) {
|
|
|
|
// Handle donation
|
2015-10-31 08:11:23 +00:00
|
|
|
Intent intent = new Intent(ACTION_IAB);
|
2015-10-30 15:51:24 +00:00
|
|
|
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
|
2015-11-02 13:36:14 +00:00
|
|
|
} else {
|
|
|
|
int response = (data == null ? -1 : data.getIntExtra("RESPONSE_CODE", -1));
|
2015-11-02 12:37:33 +00:00
|
|
|
Log.i(TAG, "IAB response=" + getIABResult(response));
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
|
|
|
|
2015-10-31 19:47:48 +00:00
|
|
|
} else if (requestCode == REQUEST_EXPORT) {
|
|
|
|
if (resultCode == RESULT_OK && data != null)
|
|
|
|
new AsyncTask<Object, Object, Throwable>() {
|
|
|
|
@Override
|
|
|
|
protected Throwable doInBackground(Object... objects) {
|
|
|
|
OutputStream out = null;
|
|
|
|
try {
|
|
|
|
out = getContentResolver().openOutputStream(data.getData());
|
|
|
|
Log.i(TAG, "Writing URI=" + data.getData());
|
|
|
|
xmlExport(out);
|
|
|
|
return null;
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
return ex;
|
|
|
|
} finally {
|
|
|
|
if (out != null)
|
|
|
|
try {
|
|
|
|
out.close();
|
|
|
|
} catch (IOException ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Throwable ex) {
|
2015-11-02 12:22:58 +00:00
|
|
|
if (ex == null)
|
|
|
|
Toast.makeText(ActivityMain.this, R.string.msg_completed, Toast.LENGTH_LONG).show();
|
|
|
|
else
|
2015-10-31 19:47:48 +00:00
|
|
|
Toast.makeText(ActivityMain.this, ex.toString(), Toast.LENGTH_LONG).show();
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
|
|
|
|
} else if (requestCode == REQUEST_IMPORT) {
|
|
|
|
if (resultCode == RESULT_OK && data != null)
|
|
|
|
new AsyncTask<Object, Object, Throwable>() {
|
|
|
|
@Override
|
|
|
|
protected Throwable doInBackground(Object... objects) {
|
|
|
|
InputStream in = null;
|
|
|
|
try {
|
|
|
|
in = getContentResolver().openInputStream(data.getData());
|
|
|
|
Log.i(TAG, "Reading URI=" + data.getData());
|
|
|
|
xmlImport(in);
|
|
|
|
return null;
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
return ex;
|
|
|
|
} finally {
|
|
|
|
if (in != null)
|
|
|
|
try {
|
|
|
|
in.close();
|
|
|
|
} catch (IOException ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Throwable ex) {
|
|
|
|
if (ex == null) {
|
|
|
|
SinkholeService.reload(null, ActivityMain.this);
|
|
|
|
recreate();
|
2015-11-02 12:22:58 +00:00
|
|
|
Toast.makeText(ActivityMain.this, R.string.msg_completed, Toast.LENGTH_LONG).show();
|
2015-10-31 19:47:48 +00:00
|
|
|
} else
|
|
|
|
Toast.makeText(ActivityMain.this, ex.toString(), Toast.LENGTH_LONG).show();
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
|
2015-10-30 15:51:24 +00:00
|
|
|
} else {
|
|
|
|
Log.w(TAG, "Unknown activity result request=" + requestCode);
|
2015-10-24 18:01:55 +00:00
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
2015-10-30 15:51:24 +00:00
|
|
|
}
|
2015-10-24 18:01:55 +00:00
|
|
|
}
|
2015-10-30 18:57:18 +00:00
|
|
|
|
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);
|
|
|
|
intent.setData(Uri.parse("http://forum.xda-developers.com/showthread.php?t=3233012"));
|
|
|
|
return intent;
|
|
|
|
}
|
|
|
|
|
2015-11-01 06:38:52 +00:00
|
|
|
private static Intent getIntentCreateDocument() {
|
|
|
|
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
|
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
|
|
intent.setType("text/xml");
|
|
|
|
intent.putExtra(Intent.EXTRA_TITLE, "netguard.xml");
|
|
|
|
return intent;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static Intent getIntentOpenDocument() {
|
|
|
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
|
|
intent.setType("text/xml");
|
|
|
|
return intent;
|
|
|
|
}
|
|
|
|
|
2015-10-31 08:11:23 +00:00
|
|
|
private boolean IABvalidate() {
|
|
|
|
try {
|
|
|
|
// Get available SKUs
|
|
|
|
ArrayList<String> skuList = new ArrayList<>();
|
|
|
|
skuList.add(SKU_DONATE);
|
|
|
|
Bundle query = new Bundle();
|
|
|
|
query.putStringArrayList("ITEM_ID_LIST", skuList);
|
2015-11-02 12:37:33 +00:00
|
|
|
Bundle details = IABService.getSkuDetails(3, getPackageName(), "inapp", query);
|
|
|
|
Log.i(TAG, "IAB.getSkuDetails");
|
2015-10-31 08:11:23 +00:00
|
|
|
Util.logBundle(TAG, details);
|
2015-11-02 13:36:14 +00:00
|
|
|
int details_response = (details == null ? -1 : details.getInt("RESPONSE_CODE", -1));
|
2015-11-02 12:37:33 +00:00
|
|
|
Log.i(TAG, "IAB response=" + getIABResult(details_response));
|
2015-10-31 08:11:23 +00:00
|
|
|
if (details_response != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Check available SKUs
|
|
|
|
boolean found = false;
|
2015-11-02 13:36:14 +00:00
|
|
|
if (details.containsKey("DETAILS_LIST"))
|
|
|
|
for (String item : details.getStringArrayList("DETAILS_LIST")) {
|
|
|
|
JSONObject object = new JSONObject(item);
|
|
|
|
if (SKU_DONATE.equals(object.getString("productId"))) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
2015-10-31 08:11:23 +00:00
|
|
|
}
|
|
|
|
Log.i(TAG, SKU_DONATE + "=" + found);
|
|
|
|
if (!found)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Get purchases
|
2015-11-02 12:37:33 +00:00
|
|
|
Bundle purchases = IABService.getPurchases(3, getPackageName(), "inapp", null);
|
|
|
|
Log.i(TAG, "IAB.getPurchases");
|
2015-10-31 08:11:23 +00:00
|
|
|
Util.logBundle(TAG, purchases);
|
2015-11-02 13:36:14 +00:00
|
|
|
int purchases_response = (purchases == null ? -1 : purchases.getInt("RESPONSE_CODE", -1));
|
2015-11-02 12:37:33 +00:00
|
|
|
Log.i(TAG, "IAB response=" + getIABResult(purchases_response));
|
2015-10-31 08:11:23 +00:00
|
|
|
if (purchases_response != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Check purchases
|
2015-11-02 13:36:14 +00:00
|
|
|
if (!purchases.containsKey("INAPP_PURCHASE_ITEM_LIST"))
|
|
|
|
return false;
|
2015-10-31 08:11:23 +00:00
|
|
|
ArrayList<String> skus = purchases.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
|
|
|
|
return skus.contains(SKU_DONATE);
|
|
|
|
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
2015-10-31 19:02:22 +00:00
|
|
|
Toast.makeText(ActivityMain.this, ex.toString(), Toast.LENGTH_LONG).show();
|
2015-10-31 08:11:23 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void IABinitiate() {
|
|
|
|
try {
|
2015-11-02 12:37:33 +00:00
|
|
|
Bundle bundle = IABService.getBuyIntent(3, getPackageName(), SKU_DONATE, "inapp", "");
|
|
|
|
Log.i(TAG, "IAB.getBuyIntent");
|
2015-10-31 08:11:23 +00:00
|
|
|
Util.logBundle(TAG, bundle);
|
2015-11-02 13:36:14 +00:00
|
|
|
int response = (bundle == null ? -1 : bundle.getInt("RESPONSE_CODE", -1));
|
2015-11-02 12:37:33 +00:00
|
|
|
Log.i(TAG, "IAB response=" + getIABResult(response));
|
2015-11-02 13:36:14 +00:00
|
|
|
if (response == 0 && bundle.containsKey("BUY_INTENT")) {
|
2015-10-31 08:11:23 +00:00
|
|
|
PendingIntent pi = bundle.getParcelable("BUY_INTENT");
|
|
|
|
startIntentSenderForResult(
|
|
|
|
pi.getIntentSender(),
|
|
|
|
REQUEST_DONATION,
|
|
|
|
new Intent(),
|
|
|
|
Integer.valueOf(0),
|
|
|
|
Integer.valueOf(0),
|
|
|
|
Integer.valueOf(0));
|
|
|
|
}
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
Toast.makeText(ActivityMain.this, ex.toString(), Toast.LENGTH_LONG).show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static String getIABResult(int responseCode) {
|
2015-10-30 18:57:18 +00:00
|
|
|
switch (responseCode) {
|
|
|
|
case 0:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "OK";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 1:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "USER_CANCELED";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 2:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "SERVICE_UNAVAILABLE";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 3:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "BILLING_UNAVAILABLE";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 4:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "ITEM_UNAVAILABLE";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 5:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "DEVELOPER_ERROR";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 6:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "ERROR";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 7:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "ITEM_ALREADY_OWNED";
|
2015-10-30 18:57:18 +00:00
|
|
|
case 8:
|
2015-11-02 12:37:33 +00:00
|
|
|
return "ITEM_NOT_OWNED";
|
2015-10-30 18:57:18 +00:00
|
|
|
default:
|
|
|
|
return Integer.toString(responseCode);
|
|
|
|
}
|
|
|
|
}
|
2015-10-31 19:02:22 +00:00
|
|
|
|
2015-10-31 19:47:48 +00:00
|
|
|
private void xmlExport(OutputStream out) throws IOException {
|
|
|
|
XmlSerializer serializer = Xml.newSerializer();
|
|
|
|
serializer.setOutput(out, "UTF-8");
|
|
|
|
serializer.startDocument(null, Boolean.valueOf(true));
|
|
|
|
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
|
|
|
serializer.startTag(null, "netguard");
|
|
|
|
|
|
|
|
serializer.startTag(null, "application");
|
|
|
|
xmlExport(PreferenceManager.getDefaultSharedPreferences(this), serializer);
|
|
|
|
serializer.endTag(null, "application");
|
|
|
|
|
|
|
|
serializer.startTag(null, "wifi");
|
|
|
|
xmlExport(getSharedPreferences("wifi", Context.MODE_PRIVATE), serializer);
|
|
|
|
serializer.endTag(null, "wifi");
|
|
|
|
|
|
|
|
serializer.startTag(null, "mobile");
|
|
|
|
xmlExport(getSharedPreferences("other", Context.MODE_PRIVATE), serializer);
|
|
|
|
serializer.endTag(null, "mobile");
|
|
|
|
|
|
|
|
serializer.startTag(null, "unused");
|
|
|
|
xmlExport(getSharedPreferences("unused", Context.MODE_PRIVATE), serializer);
|
|
|
|
serializer.endTag(null, "unused");
|
|
|
|
|
|
|
|
serializer.endTag(null, "netguard");
|
|
|
|
serializer.endDocument();
|
|
|
|
serializer.flush();
|
2015-10-31 19:02:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void xmlExport(SharedPreferences prefs, XmlSerializer serializer) throws IOException {
|
|
|
|
Map<String, ?> settings = prefs.getAll();
|
|
|
|
for (String key : settings.keySet()) {
|
|
|
|
Object value = settings.get(key);
|
|
|
|
if (value instanceof Boolean) {
|
|
|
|
serializer.startTag(null, "setting");
|
|
|
|
serializer.attribute(null, "key", key);
|
|
|
|
serializer.attribute(null, "type", "boolean");
|
|
|
|
serializer.attribute(null, "value", value.toString());
|
|
|
|
serializer.endTag(null, "setting");
|
|
|
|
} else
|
|
|
|
Log.e(TAG, "Unknown key=" + key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-31 19:47:48 +00:00
|
|
|
private void xmlImport(InputStream in) throws IOException, SAXException, ParserConfigurationException {
|
|
|
|
XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
|
|
|
XmlImportHandler handler = new XmlImportHandler();
|
|
|
|
reader.setContentHandler(handler);
|
|
|
|
reader.parse(new InputSource(in));
|
2015-10-31 19:02:22 +00:00
|
|
|
|
2015-10-31 19:47:48 +00:00
|
|
|
xmlImport(handler.application, PreferenceManager.getDefaultSharedPreferences(this));
|
|
|
|
xmlImport(handler.wifi, getSharedPreferences("wifi", Context.MODE_PRIVATE));
|
|
|
|
xmlImport(handler.mobile, getSharedPreferences("other", Context.MODE_PRIVATE));
|
|
|
|
xmlImport(handler.unused, getSharedPreferences("unused", Context.MODE_PRIVATE));
|
2015-10-31 19:02:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void xmlImport(Map<String, Object> settings, SharedPreferences prefs) {
|
|
|
|
SharedPreferences.Editor editor = prefs.edit();
|
|
|
|
|
|
|
|
for (String key : prefs.getAll().keySet())
|
|
|
|
editor.remove(key);
|
|
|
|
|
|
|
|
for (String key : settings.keySet()) {
|
|
|
|
Object value = settings.get(key);
|
|
|
|
if (value instanceof Boolean)
|
|
|
|
editor.putBoolean(key, (Boolean) value);
|
|
|
|
else
|
|
|
|
Log.e(TAG, "Unknown type=" + value.getClass());
|
|
|
|
}
|
|
|
|
|
|
|
|
editor.apply();
|
|
|
|
}
|
|
|
|
|
|
|
|
private class XmlImportHandler extends DefaultHandler {
|
|
|
|
public Map<String, Object> application = new HashMap<>();
|
|
|
|
public Map<String, Object> wifi = new HashMap<>();
|
|
|
|
public Map<String, Object> mobile = new HashMap<>();
|
|
|
|
public Map<String, Object> unused = new HashMap<>();
|
|
|
|
private Map<String, Object> current = null;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
|
|
|
if (qName.equals("netguard"))
|
|
|
|
; // Ignore
|
|
|
|
|
|
|
|
else if (qName.equals("application"))
|
|
|
|
current = application;
|
|
|
|
|
|
|
|
else if (qName.equals("wifi"))
|
|
|
|
current = wifi;
|
|
|
|
|
|
|
|
else if (qName.equals("mobile"))
|
|
|
|
current = mobile;
|
|
|
|
|
|
|
|
else if (qName.equals("unused"))
|
|
|
|
current = unused;
|
|
|
|
|
|
|
|
else if (qName.equals("setting")) {
|
|
|
|
String key = attributes.getValue("key");
|
|
|
|
String type = attributes.getValue("type");
|
|
|
|
String value = attributes.getValue("value");
|
|
|
|
|
|
|
|
if (current == null)
|
|
|
|
Log.e(TAG, "No current key=" + key);
|
|
|
|
else {
|
|
|
|
if ("boolean".equals(type))
|
|
|
|
current.put(key, Boolean.parseBoolean(value));
|
|
|
|
else
|
|
|
|
Log.e(TAG, "Unknown type key=" + key);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else
|
|
|
|
Log.e(TAG, "Unknown element qname=" + qName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|