diff options
6 files changed, 134 insertions, 2 deletions
diff --git a/app/build.gradle b/app/build.gradle index 1ade8155..09858cd2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,6 +12,20 @@ android { resValue "string", "app_name", "Bitmask" vectorDrawables.useSupportLibrary = true buildConfigField 'boolean', 'openvpn3', 'false' + + //Build Config Fields for default donation details + + //This is the default donation URL and should be set to the donation page of LEAP + // and this should not be set/altered anywhere else. + buildConfigField 'String', 'default_donation_url', '"https://leap.se/en/about-us/donate"' + //This is the donation URL and should be set to the relevant donation page. + buildConfigField 'String', 'donation_url', 'null' + //The field to enable donations in the app. + buildConfigField 'boolean', 'enable_donation', 'true' + //The field to enable donation reminder popup in the app if enable_donation is set to 'false' this will be disabled. + buildConfigField 'boolean', 'enable_donation_reminder', 'true' + //The duration in days to trigger the donation reminder + buildConfigField 'int', 'donation_reminder_duration', '30' testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" dexOptions { jumboMode true diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java index d719e8d3..af1d55ec 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java @@ -1,5 +1,7 @@ package se.leap.bitmaskclient; +import android.text.TextUtils; + public interface Constants { ////////////////////////////////////////////// @@ -87,4 +89,16 @@ public interface Constants { // ICS-OPENVPN CONSTANTS ///////////////////////////////////////////// String DEFAULT_SHARED_PREFS_BATTERY_SAVER = "screenoff"; + + ////////////////////////////////////////////// + // CUSTOM CONSTANTS + ///////////////////////////////////////////// + boolean ENABLE_DONATION = BuildConfig.enable_donation; + boolean ENABLE_DONATION_REMINDER = BuildConfig.enable_donation_reminder; + int DONATION_REMINDER_DURATION = BuildConfig.donation_reminder_duration; + String DONATION_URL = TextUtils.isEmpty(BuildConfig.donation_url) ? + BuildConfig.default_donation_url : BuildConfig.donation_url; + String LAST_DONATION_REMINDER_DATE = "last_donation_reminder_date"; + + } diff --git a/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java b/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java index 8238df55..01b10575 100644 --- a/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java @@ -40,6 +40,7 @@ public class DrawerSettingsAdapter extends BaseAdapter { public static final int ABOUT = 2; public static final int BATTERY_SAVER = 3; public static final int ALWAYS_ON = 4; + public static final int DONATE = 5; //view types public final static int VIEW_SIMPLE_TEXT = 0; diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index 5dbec7b0..535322e5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -25,19 +25,27 @@ import android.content.ServiceConnection; import android.content.SharedPreferences; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; +import android.net.Uri; import android.os.Bundle; import android.os.IBinder; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; import android.support.v7.widget.AppCompatImageView; import android.support.v7.widget.AppCompatTextView; +import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.Locale; import java.util.Observable; import java.util.Observer; @@ -55,11 +63,16 @@ import se.leap.bitmaskclient.views.VpnStateImage; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK; +import static se.leap.bitmaskclient.Constants.DONATION_REMINDER_DURATION; import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_LOG_IN; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.Constants.DONATION_URL; +import static se.leap.bitmaskclient.Constants.ENABLE_DONATION; +import static se.leap.bitmaskclient.Constants.ENABLE_DONATION_REMINDER; +import static se.leap.bitmaskclient.Constants.LAST_DONATION_REMINDER_DATE; import static se.leap.bitmaskclient.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.ProviderAPI.USER_MESSAGE; import static se.leap.bitmaskclient.R.string.vpn_certificate_user_message; @@ -102,6 +115,9 @@ public class EipFragment extends Fragment implements Observer { private IOpenVPNServiceInternal mService; private ServiceConnection openVpnConnection; + private final String DATE_PATTERN = "dd/MM/yyyy"; + private final int ONE_DAY = 86400000; //1000*60*60*24 + @Override public void onAttach(Context context) { super.onAttach(context); @@ -152,6 +168,14 @@ public class EipFragment extends Fragment implements Observer { } @Override + public void onStart() { + super.onStart(); + if (isDonationReminderCallable()) { + showDonationReminder(); + } + } + + @Override public void onResume() { super.onResume(); //FIXME: avoid race conditions while checking certificate an logging in at about the same time @@ -180,7 +204,6 @@ public class EipFragment extends Fragment implements Observer { } else if (showPendingStartCancellation) { outState.putBoolean(KEY_SHOW_PENDING_START_CANCELLATION, true); alertDialog.dismiss(); - } } @@ -483,4 +506,68 @@ public class EipFragment extends Fragment implements Observer { mService = null; } } + + private void showDonationReminder() { + Activity activity = getActivity(); + if (activity == null) { + Log.e(TAG, "activity is null when triggering donation reminder"); + return; + } + String message = TextUtils.isEmpty(activity.getString(R.string.donate_message)) ? + activity.getString(R.string.donate_default_message) : activity.getString(R.string.donate_message); + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(activity); + alertDialog = alertBuilder.setTitle(activity.getString(R.string.donate_title)) + .setMessage(message) + .setPositiveButton(R.string.donate_button_donate, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(DONATION_URL)); + startActivity(browserIntent); + } + }) + .setNegativeButton(R.string.donate_button_remind_later, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + } + }).setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + saveLastDonationReminderDate(); + } + }).show(); + } + + private boolean isDonationReminderCallable() { + if (!ENABLE_DONATION || !ENABLE_DONATION_REMINDER) { + return false; + } + + if (preferences == null) { + Log.e(TAG, "preferences is null!"); + return false; + } + + String lastDonationReminderDate = preferences.getString(LAST_DONATION_REMINDER_DATE, null); + if (lastDonationReminderDate == null) { + return true; + } + + SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN, Locale.US); + Date lastDate; + try { + lastDate = sdf.parse(lastDonationReminderDate); + } catch (ParseException e) { + e.printStackTrace(); + Log.e(TAG, e.getMessage()); + return false; + } + + Date currentDate = new Date(); + long diffDays = (currentDate.getTime() - lastDate.getTime()) / ONE_DAY; + return diffDays >= DONATION_REMINDER_DURATION; + } + + private void saveLastDonationReminderDate() { + SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN, Locale.US); + Date lastDate = new Date(); + preferences.edit().putString(LAST_DONATION_REMINDER_DATE, sdf.format(lastDate)).apply(); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java index e7a5e460..14c2eacf 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -22,6 +22,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.v4.app.DialogFragment; @@ -46,7 +47,6 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CompoundButton; import android.widget.ListView; -import android.widget.Toast; import se.leap.bitmaskclient.ConfigHelper; import se.leap.bitmaskclient.DrawerSettingsAdapter; @@ -67,9 +67,12 @@ import static se.leap.bitmaskclient.ConfigHelper.getShowAlwaysOnDialog; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.Constants.DONATION_URL; +import static se.leap.bitmaskclient.Constants.ENABLE_DONATION; import static se.leap.bitmaskclient.DrawerSettingsAdapter.ABOUT; import static se.leap.bitmaskclient.DrawerSettingsAdapter.ALWAYS_ON; import static se.leap.bitmaskclient.DrawerSettingsAdapter.BATTERY_SAVER; +import static se.leap.bitmaskclient.DrawerSettingsAdapter.DONATE; import static se.leap.bitmaskclient.DrawerSettingsAdapter.DrawerSettingsItem.getSimpleTextInstance; import static se.leap.bitmaskclient.DrawerSettingsAdapter.DrawerSettingsItem.getSwitchInstance; import static se.leap.bitmaskclient.DrawerSettingsAdapter.LOG; @@ -77,6 +80,7 @@ import static se.leap.bitmaskclient.DrawerSettingsAdapter.SWITCH_PROVIDER; import static se.leap.bitmaskclient.R.string.about_fragment_title; import static se.leap.bitmaskclient.R.string.log_fragment_title; import static se.leap.bitmaskclient.R.string.switch_provider_menu_option; +import static se.leap.bitmaskclient.R.string.donate_title; /** * Fragment used for managing interactions for and presentation of a navigation drawer. @@ -184,6 +188,9 @@ public class NavigationDrawerFragment extends Fragment { settingsListAdapter.addItem(getSimpleTextInstance(getString(switch_provider_menu_option), SWITCH_PROVIDER)); settingsListAdapter.addItem(getSimpleTextInstance(getString(log_fragment_title), LOG)); settingsListAdapter.addItem(getSimpleTextInstance(getString(about_fragment_title), ABOUT)); + if (ENABLE_DONATION) { + settingsListAdapter.addItem(getSimpleTextInstance(getString(donate_title), DONATE)); + } mDrawerSettingsListView.setAdapter(settingsListAdapter); @@ -452,6 +459,10 @@ public class NavigationDrawerFragment extends Fragment { startActivity(intent); } break; + case DONATE: + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(DONATION_URL)); + startActivity(browserIntent); + break; default: break; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a308b5e7..3aa00124 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -113,4 +113,9 @@ <string name="always_on_vpn">Always-on VPN</string> <string name="do_not_show_again">Do not show again.</string> <string name="always_on_vpn_user_message">To enable always-on VPN in Android VPN Settings click on the configure icon [img src] and turn the switch on."</string> + <string name="donate_title">Donate</string> + <string name="donate_default_message">Please donate today if you value secure communication that is easy for both the end-user and the service provider.</string> + <string name="donate_message">LEAP depends on donations and grants. Please donate today if you value secure communication that is easy for both the end-user and the service provider.</string> + <string name="donate_button_remind_later">Remind me later</string> + <string name="donate_button_donate">Donate</string> </resources> |