Make all convenience features pro

This commit is contained in:
M66B 2015-12-27 12:06:10 +01:00
parent 28f4ac1de3
commit 8dd27f1117
4 changed files with 168 additions and 48 deletions

View File

@ -60,6 +60,7 @@ import java.util.List;
public class ActivityMain extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { public class ActivityMain extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "NetGuard.Main"; private static final String TAG = "NetGuard.Main";
private boolean pro = false;
private boolean running = false; private boolean running = false;
private SwipeRefreshLayout swipeRefresh; private SwipeRefreshLayout swipeRefresh;
private RuleAdapter adapter = null; private RuleAdapter adapter = null;
@ -248,6 +249,14 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences
// Fill application list // Fill application list
updateApplicationList(getIntent().getStringExtra(EXTRA_SEARCH)); updateApplicationList(getIntent().getStringExtra(EXTRA_SEARCH));
// Check if donated
new Thread(new Runnable() {
@Override
public void run() {
pro = new IAB(ActivityMain.this).hasPro();
}
}).start();
} }
@Override @Override
@ -510,7 +519,20 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection // Handle item selection
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
switch (item.getItemId()) {
int id = item.getItemId();
if (!pro &&
(id == R.id.menu_app_user ||
id == R.id.menu_app_system ||
id == R.id.menu_app_nointernet ||
id == R.id.menu_app_disabled) &&
item.isChecked()) {
Toast.makeText(this, getString(R.string.msg_pro), Toast.LENGTH_SHORT).show();
return true;
}
switch (id) {
case R.id.menu_app_user: case R.id.menu_app_user:
item.setChecked(!item.isChecked()); item.setChecked(!item.isChecked());
prefs.edit().putBoolean("show_user", item.isChecked()).apply(); prefs.edit().putBoolean("show_user", item.isChecked()).apply();
@ -532,7 +554,9 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences
return true; return true;
case R.id.menu_settings: case R.id.menu_settings:
startActivity(new Intent(this, ActivitySettings.class)); Intent settings = new Intent(this, ActivitySettings.class);
settings.putExtra(ActivitySettings.EXTRA_PRO, pro);
startActivity(settings);
return true; return true;
case R.id.menu_invite: case R.id.menu_invite:
@ -681,7 +705,7 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences
// Connect to billing // Connect to billing
if (Util.hasValidFingerprint(this)) if (Util.hasValidFingerprint(this))
iab.bind(); iab.bind(null);
} }

View File

@ -73,8 +73,11 @@ import javax.xml.parsers.SAXParserFactory;
public class ActivitySettings extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { public class ActivitySettings extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "NetGuard.Settings"; private static final String TAG = "NetGuard.Settings";
private boolean pro = false;
private boolean phone_state = false; private boolean phone_state = false;
public static final String EXTRA_PRO = "Pro";
private static final int REQUEST_EXPORT = 1; private static final int REQUEST_EXPORT = 1;
private static final int REQUEST_IMPORT = 2; private static final int REQUEST_IMPORT = 2;
private static final int REQUEST_METERED = 3; private static final int REQUEST_METERED = 3;
@ -88,6 +91,8 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
pro = getIntent().getBooleanExtra(EXTRA_PRO, false);
getFragmentManager().beginTransaction().replace(android.R.id.content, new FragmentSettings()).commit(); getFragmentManager().beginTransaction().replace(android.R.id.content, new FragmentSettings()).commit();
getSupportActionBar().setTitle(R.string.menu_settings); getSupportActionBar().setTitle(R.string.menu_settings);
} }
@ -140,7 +145,10 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
pref_export.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { pref_export.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
if (pro)
startActivityForResult(getIntentCreateDocument(), ActivitySettings.REQUEST_EXPORT); startActivityForResult(getIntentCreateDocument(), ActivitySettings.REQUEST_EXPORT);
else
Toast.makeText(ActivitySettings.this, getString(R.string.msg_pro), Toast.LENGTH_SHORT).show();
return true; return true;
} }
}); });
@ -151,7 +159,10 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
pref_import.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { pref_import.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
if (pro)
startActivityForResult(getIntentOpenDocument(), ActivitySettings.REQUEST_IMPORT); startActivityForResult(getIntentOpenDocument(), ActivitySettings.REQUEST_IMPORT);
else
Toast.makeText(ActivitySettings.this, getString(R.string.msg_pro), Toast.LENGTH_SHORT).show();
return true; return true;
} }
}); });
@ -292,26 +303,34 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
} else } else
SinkholeService.reload("other", "setting changed", this); SinkholeService.reload("other", "setting changed", this);
} else if ("show_stats".equals(name)) { } else if ("manage_system".equals(name)) {
if (!Util.isPlayStoreInstall(this)) SharedPreferences.Editor editor = prefs.edit();
SinkholeService.reloadStats("setting changed", this); if (prefs.getBoolean(name, false)) {
editor.putBoolean("show_system", true);
editor.putBoolean("show_user", true);
} else {
editor.putBoolean("show_user", true);
editor.putBoolean("show_system", false);
}
editor.apply();
SinkholeService.reload(null, "setting changed", this);
} else if ("stats_base".equals(name)) { } else if ("auto_enable".equals(name)) {
if (!Util.isPlayStoreInstall(this)) if (!pro) {
getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_base, prefs.getString(name, "5"))); prefs.edit().putString(name, "0").apply();
Toast.makeText(ActivitySettings.this, getString(R.string.msg_pro), Toast.LENGTH_SHORT).show();
} else if ("stats_frequency".equals(name)) { }
if (!Util.isPlayStoreInstall(this))
getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_frequency, prefs.getString(name, "1000")));
} else if ("stats_samples".equals(name)) {
if (!Util.isPlayStoreInstall(this))
getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_samples, prefs.getString(name, "90")));
} else if ("auto_enable".equals(name))
getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_auto, prefs.getString(name, "0"))); getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_auto, prefs.getString(name, "0")));
else if ("wifi_homes".equals(name)) { } else if ("dark_theme".equals(name)) {
if (!pro) {
prefs.edit().putBoolean(name, false);
((SwitchPreference) getPreferenceScreen().findPreference(name)).setChecked(false);
Toast.makeText(ActivitySettings.this, getString(R.string.msg_pro), Toast.LENGTH_SHORT).show();
}
recreate();
} else if ("wifi_homes".equals(name)) {
MultiSelectListPreference pref_wifi_homes = (MultiSelectListPreference) getPreferenceScreen().findPreference(name); MultiSelectListPreference pref_wifi_homes = (MultiSelectListPreference) getPreferenceScreen().findPreference(name);
Set<String> ssid = prefs.getStringSet(name, new HashSet<String>()); Set<String> ssid = prefs.getStringSet(name, new HashSet<String>());
if (ssid.size() > 0) if (ssid.size() > 0)
@ -343,24 +362,32 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
} else } else
SinkholeService.reload("other", "setting changed", this); SinkholeService.reload("other", "setting changed", this);
} else if ("manage_system".equals(name)) { } else if ("show_stats".equals(name)) {
SharedPreferences.Editor editor = prefs.edit(); if (pro)
if (prefs.getBoolean(name, false)) { SinkholeService.reloadStats("setting changed", this);
editor.putBoolean("show_system", true); else {
editor.putBoolean("show_user", true); prefs.edit().putBoolean(name, false);
} else { ((SwitchPreference) getPreferenceScreen().findPreference(name)).setChecked(false);
editor.putBoolean("show_user", true); Toast.makeText(ActivitySettings.this, getString(R.string.msg_pro), Toast.LENGTH_SHORT).show();
editor.putBoolean("show_system", false);
} }
editor.apply();
SinkholeService.reload(null, "setting changed", this);
} else if ("dark_theme".equals(name)) } else if ("stats_base".equals(name)) {
recreate(); if (!Util.isPlayStoreInstall(this))
getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_base, prefs.getString(name, "5")));
} else if ("stats_frequency".equals(name)) {
if (!Util.isPlayStoreInstall(this))
getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_frequency, prefs.getString(name, "1000")));
} else if ("stats_samples".equals(name)) {
if (!Util.isPlayStoreInstall(this))
getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_samples, prefs.getString(name, "90")));
}
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
PreferenceScreen screen = getPreferenceScreen(); PreferenceScreen screen = getPreferenceScreen();
if (requestCode == REQUEST_METERED) if (requestCode == REQUEST_METERED)

View File

@ -25,6 +25,7 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
@ -37,26 +38,35 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
public class IAB implements ServiceConnection { public class IAB implements ServiceConnection {
private static final String TAG = "Netguard.IAB"; private static final String TAG = "Netguard.IAB";
private Context context; private Context context;
private Event event;
private boolean available = false; private boolean available = false;
private IInAppBillingService service = null; private IInAppBillingService service = null;
private static final int IAB_VERSION = 3; private static final int IAB_VERSION = 3;
// adb shell pm clear com.android.vending // adb shell pm clear com.android.vending
// adb shell am start -n eu.faircode.netguard/eu.faircode.netguard.ActivityMain // adb shell am start -n eu.faircode.netguard/eu.faircode.netguard.ActivityMain
private static final String SKU_PRO = "pro";
private static final String SKU_DONATE = "donation"; private static final String SKU_DONATE = "donation";
// private static final String SKU_DONATE = "android.test.purchased"; // private static final String SKU_DONATE = "android.test.purchased";
public static final String ACTION_IAB = "eu.faircode.netguard.IAB"; public static final String ACTION_IAB = "eu.faircode.netguard.IAB";
public interface Event {
void bound();
}
public IAB(Context context) { public IAB(Context context) {
this.context = context; this.context = context;
} }
public void bind() { public void bind(Event event) {
this.event = event;
try { try {
Log.i(TAG, "Bind"); Log.i(TAG, "Bind");
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
@ -87,9 +97,10 @@ public class IAB implements ServiceConnection {
@Override @Override
public void onServiceConnected(ComponentName name, IBinder binder) { public void onServiceConnected(ComponentName name, IBinder binder) {
Log.i(TAG, "Connected"); Log.i(TAG, "Connected");
try {
service = IInAppBillingService.Stub.asInterface(binder); service = IInAppBillingService.Stub.asInterface(binder);
if (this.event == null)
try {
if (isPurchased(SKU_DONATE)) { if (isPurchased(SKU_DONATE)) {
Intent intent = new Intent(ACTION_IAB); Intent intent = new Intent(ACTION_IAB);
intent.putExtra("RESULT_CODE", Activity.RESULT_OK); intent.putExtra("RESULT_CODE", Activity.RESULT_OK);
@ -101,6 +112,8 @@ public class IAB implements ServiceConnection {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
Util.sendCrashReport(ex, context); Util.sendCrashReport(ex, context);
} }
else
event.bound();
} }
@Override @Override
@ -146,6 +159,61 @@ public class IAB implements ServiceConnection {
} }
} }
public boolean hasPro() {
boolean pro = false;
final CountDownLatch latch = new CountDownLatch(1);
if (Util.isDebuggable(context))
return true;
bind(new Event() {
@Override
public void bound() {
try {
SharedPreferences prefs = context.getSharedPreferences("IAB", Context.MODE_PRIVATE);
boolean pro = false;
long now = new Date().getTime();
long refreshed = prefs.getLong("refreshed", 0);
if (!prefs.getBoolean("pro", false) || refreshed < now - 3 * 24 * 3600 * 1000L) {
Log.i(TAG, "Refreshing pro");
try {
pro = isPurchased(SKU_PRO);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("pro", pro);
editor.putLong("refreshed", now);
editor.apply();
Log.i(TAG, "Refreshed pro=" + pro);
} catch (RemoteException ignored) {
if (refreshed >= now - 5 * 24 * 3600 * 1000L) {
pro = prefs.getBoolean("pro", false);
Log.i(TAG, "Grace pro=" + pro);
} else {
SharedPreferences.Editor editor = prefs.edit();
editor.remove("pro");
editor.remove("refreshed");
editor.apply();
Log.i(TAG, "Cache expired");
}
}
} else {
pro = prefs.getBoolean("pro", false);
Log.i(TAG, "Cached pro=" + pro);
}
} finally {
try {
latch.await();
} catch (InterruptedException ignored) {
}
}
}
});
latch.countDown();
return pro;
}
private boolean isPurchased(String sku) throws RemoteException { private boolean isPurchased(String sku) throws RemoteException {
try { try {
// Get purchases // Get purchases

View File

@ -80,6 +80,7 @@ Since NetGuard has no internet permission, you know your internet traffic is not
<string name="msg_mbday">&#177; %1$.3f&#9650; %2$.3f&#9660; MB/day</string> <string name="msg_mbday">&#177; %1$.3f&#9650; %2$.3f&#9660; MB/day</string>
<string name="msg_kbsec">%7.3f KB/s</string> <string name="msg_kbsec">%7.3f KB/s</string>
<string name="msg_mbsec">%7.3f MB/s</string> <string name="msg_mbsec">%7.3f MB/s</string>
<string name="msg_pro">This is a pro feature</string>
<string name="title_screen_wifi">Allow Wi-Fi when screen is on</string> <string name="title_screen_wifi">Allow Wi-Fi when screen is on</string>
<string name="title_screen_other">Allow mobile when screen is on</string> <string name="title_screen_other">Allow mobile when screen is on</string>