From 14ba6c81a5ec60732481e84eb02d62d6490c27f8 Mon Sep 17 00:00:00 2001 From: Fup Duck <fupduck@sacknagel.com> Date: Thu, 23 Nov 2017 11:34:52 +0100 Subject: [PATCH] Add Splash StartActivity * added Splash StartActivity to handle updates and initialization * created global Constants * move EIPConstants to Constants * create update possibility * use VectorDrawable as background for StartActivity --- app/build.gradle | 6 +- .../se/leap/bitmaskclient/test/TestEIP.java | 8 +- .../test/TestGatewaysManager.java | 4 +- .../se/leap/bitmaskclient/ProviderAPI.java | 9 +- .../bitmaskclient/ProviderDetailFragment.java | 9 +- app/src/main/AndroidManifest.xml | 8 ++ .../blinkt/openvpn/fragments/LogFragment.java | 39 ----- .../BaseConfigurationWizard.java | 7 +- .../java/se/leap/bitmaskclient/Constants.java | 38 +++++ .../java/se/leap/bitmaskclient/Dashboard.java | 34 +---- .../bitmaskclient/FeatureVersionCode.java | 5 + .../se/leap/bitmaskclient/LeapSRPSession.java | 3 - .../se/leap/bitmaskclient/OnBootReceiver.java | 5 +- .../leap/bitmaskclient/ProviderApiBase.java | 7 +- .../se/leap/bitmaskclient/StartActivity.java | 135 ++++++++++++++++++ .../se/leap/bitmaskclient/VpnFragment.java | 32 +++-- .../se/leap/bitmaskclient/eip/Constants.java | 44 ------ .../java/se/leap/bitmaskclient/eip/EIP.java | 34 +++-- .../bitmaskclient/eip/GatewaysManager.java | 5 +- .../bitmaskclient/eip/VoidVpnLauncher.java | 4 +- .../bitmaskclient/eip/VoidVpnService.java | 4 +- .../bitmaskclient/eip/VpnConfigGenerator.java | 4 +- app/src/main/res/drawable-ldpi/mask.png | Bin 0 -> 8743 bytes app/src/main/res/drawable-mdpi/mask.png | Bin 0 -> 6324 bytes app/src/main/res/drawable-xxxhdpi/mask.png | Bin 0 -> 43251 bytes app/src/main/res/drawable/ic_colorsquare.xml | 52 +++++++ app/src/main/res/drawable/splash_page.xml | 11 ++ app/src/main/res/values/attrs.xml | 8 -- app/src/main/res/values/colors.xml | 23 +++ app/src/main/res/values/themes.xml | 12 ++ .../se/leap/bitmaskclient/ProviderAPI.java | 9 +- .../bitmaskclient/ProviderDetailFragment.java | 10 +- .../eip/GatewaysManagerTest.java | 5 +- build.gradle | 8 ++ 34 files changed, 377 insertions(+), 205 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/Constants.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/StartActivity.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/Constants.java create mode 100644 app/src/main/res/drawable-ldpi/mask.png create mode 100644 app/src/main/res/drawable-mdpi/mask.png create mode 100644 app/src/main/res/drawable-xxxhdpi/mask.png create mode 100644 app/src/main/res/drawable/ic_colorsquare.xml create mode 100644 app/src/main/res/drawable/splash_page.xml delete mode 100644 app/src/main/res/values/attrs.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/themes.xml diff --git a/app/build.gradle b/app/build.gradle index cdeccb6c..35665852 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,6 +10,7 @@ android { defaultConfig { applicationId "se.leap.bitmaskclient" resValue "string", "app_name", "Bitmask" + vectorDrawables.useSupportLibrary = true } signingConfigs { @@ -75,8 +76,9 @@ dependencies { compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' compile 'com.squareup.okhttp3:okhttp:3.9.0' compile 'mbanje.kurt:fabbutton:1.1.4' - compile 'com.android.support:support-annotations:25.3.1' - compile 'com.android.support:support-v4:26.0.0-alpha1' + compile 'com.android.support:support-annotations:27.0.1' + compile 'com.android.support:support-v4:26.1.0' + compile 'com.android.support:appcompat-v7:26.1.0' } def processFileInplace(file, Closure processText) { diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEIP.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEIP.java index 15bb53e1..c5a6e809 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEIP.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEIP.java @@ -59,14 +59,14 @@ public class TestEIP extends ServiceTestCase<EIP> { } private void testEmptyCertificate() { - preferences.edit().putString(Constants.VPN_CERTIFICATE, "").apply(); - startService(Constants.ACTION_CHECK_CERT_VALIDITY); + preferences.edit().putString(Constants.PROVIDER_VPN_CERTIFICATE, "").apply(); + startService(Constants.EIP_ACTION_CHECK_CERT_VALIDITY); } private void testExpiredCertificate() { String expired_certificate = "expired certificate"; - preferences.edit().putString(Constants.VPN_CERTIFICATE, expired_certificate).apply(); - startService(Constants.ACTION_CHECK_CERT_VALIDITY); + preferences.edit().putString(Constants.PROVIDER_VPN_CERTIFICATE, expired_certificate).apply(); + startService(Constants.EIP_ACTION_CHECK_CERT_VALIDITY); } private void startService(String action) { diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java index 0a76638f..b8cc9715 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java @@ -25,7 +25,7 @@ import org.json.*; import java.io.IOException; import java.util.Arrays; -import se.leap.bitmaskclient.*; +import se.leap.bitmaskclient.Constants; import se.leap.bitmaskclient.eip.*; /** @@ -109,7 +109,7 @@ public class TestGatewaysManager extends InstrumentationTestCase { private void mockGatewaysManager() { context = getInstrumentation().getContext(); - preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE); + preferences = context.getSharedPreferences(Constants.SHARED_PREFERENCES, Activity.MODE_PRIVATE); gateways_manager = new GatewaysManager(context, preferences); } diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java index 87fff283..7689c343 100644 --- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java @@ -45,7 +45,6 @@ import javax.net.ssl.X509TrustManager; import okhttp3.OkHttpClient; import se.leap.bitmaskclient.ProviderListContent.ProviderItem; -import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.eip.EIP; import static se.leap.bitmaskclient.R.string.certificate_error; @@ -138,8 +137,8 @@ public class ProviderAPI extends ProviderApiBase { //TODO setProviderName(name); preferences.edit().putString(Provider.KEY, provider_json.toString()).commit(); - preferences.edit().putBoolean(Constants.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.ALLOWED_ANON)).commit(); - preferences.edit().putBoolean(Constants.ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.ALLOWED_REGISTERED)).commit(); + preferences.edit().putBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS)).commit(); + preferences.edit().putBoolean(Constants.PROVIDER_ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.PROVIDER_ALLOWED_REGISTERED)).commit(); result.putBoolean(RESULT_KEY, true); } catch (JSONException e) { @@ -168,7 +167,7 @@ public class ProviderAPI extends ProviderApiBase { JSONObject eip_service_json = new JSONObject(eip_service_json_string); eip_service_json.getInt(Provider.API_RETURN_SERIAL); - preferences.edit().putString(Constants.KEY, eip_service_json.toString()).commit(); + preferences.edit().putString(Constants.PROVIDER_KEY, eip_service_json.toString()).commit(); result.putBoolean(RESULT_KEY, true); } catch (NullPointerException | JSONException e) { @@ -191,7 +190,7 @@ public class ProviderAPI extends ProviderApiBase { JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); String provider_main_url = provider_json.getString(Provider.API_URL); - URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + Constants.VPN_CERTIFICATE); + URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + Constants.PROVIDER_VPN_CERTIFICATE); String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), last_danger_on); diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailFragment.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailFragment.java index 629867e6..390d4aeb 100644 --- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailFragment.java +++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailFragment.java @@ -2,7 +2,6 @@ package se.leap.bitmaskclient; import org.json.*; -import se.leap.bitmaskclient.eip.*; import se.leap.bitmaskclient.ProviderListContent.ProviderItem; import android.app.*; @@ -23,7 +22,7 @@ public class ProviderDetailFragment extends DialogFragment { LayoutInflater inflater = getActivity().getLayoutInflater(); View provider_detail_view = inflater.inflate(R.layout.provider_detail_fragment, null); - JSONObject provider_json = new JSONObject(getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, getActivity().MODE_PRIVATE).getString(Provider.KEY, "")); + JSONObject provider_json = new JSONObject(getActivity().getSharedPreferences(Constants.SHARED_PREFERENCES, getActivity().MODE_PRIVATE).getString(Provider.KEY, "")); final TextView domain = (TextView) provider_detail_view.findViewById(R.id.provider_detail_domain); domain.setText(provider_json.getString(Provider.DOMAIN)); @@ -60,7 +59,7 @@ public class ProviderDetailFragment extends DialogFragment { private boolean anon_allowed(JSONObject provider_json) { try { JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); - return service_description.has(Constants.ALLOWED_ANON) && service_description.getBoolean(Constants.ALLOWED_ANON); + return service_description.has(Constants.PROVIDER_ALLOW_ANONYMOUS) && service_description.getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS); } catch (JSONException e) { return false; } @@ -78,8 +77,8 @@ public class ProviderDetailFragment extends DialogFragment { @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); - SharedPreferences.Editor editor = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit(); - editor.remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(Constants.ALLOWED_ANON).remove(Constants.KEY).commit(); + SharedPreferences.Editor editor = getActivity().getSharedPreferences(Constants.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit(); + editor.remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(Constants.PROVIDER_ALLOW_ANONYMOUS).remove(Constants.PROVIDER_KEY).commit(); interface_with_configuration_wizard.cancelAndShowAllProviders(); } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8c6b25d5..16168e0f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -88,6 +88,14 @@ android:uiOptions="splitActionBarWhenNarrow" android:launchMode="singleTop" > + </activity> + <activity + android:name="se.leap.bitmaskclient.StartActivity" + android:label="@string/app_name" + android:launchMode="singleTop" + android:noHistory="true" + android:theme="@style/SplashTheme" + > <intent-filter android:label="@string/app_name"> <action android:name="android.intent.action.MAIN" /> diff --git a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index a1fc7cdc..d5931c83 100644 --- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -423,45 +423,6 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. private TextView mSpeedView; - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.clearlog) { - ladapter.clearLog(); - return true; - } else if (item.getItemId() == R.id.cancel) { - Intent intent = new Intent(getActivity(), DisconnectVPN.class); - startActivity(intent); - return true; - } else if (item.getItemId() == R.id.send) { - ladapter.shareLog(); - } else if (item.getItemId() == R.id.edit_vpn) { - VpnProfile lastConnectedprofile = ProfileManager.get(getActivity(), VpnStatus.getLastConnectedVPNProfile()); - - if (lastConnectedprofile != null) { - Intent vprefintent = new Intent(getActivity(), Dashboard.class) - .putExtra(VpnProfile.EXTRA_PROFILEUUID, lastConnectedprofile.getUUIDString()); - startActivityForResult(vprefintent, START_VPN_CONFIG); - } else { - Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show(); - } - } else if (item.getItemId() == R.id.toggle_time) { - showHideOptionsPanel(); - } else if (item.getItemId() == android.R.id.home) { - // This is called when the Home (Up) button is pressed - // in the Action Bar. - Intent parentActivityIntent = new Intent(getActivity(), Dashboard.class); - parentActivityIntent.addFlags( - Intent.FLAG_ACTIVITY_CLEAR_TOP | - Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(parentActivityIntent); - getActivity().finish(); - return true; - - } - return super.onOptionsItemSelected(item); - - } - private void showHideOptionsPanel() { boolean optionsVisible = (mOptionsLayout.getVisibility() != View.GONE); diff --git a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java index 4f6163bc..21520dc4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java +++ b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java @@ -51,7 +51,6 @@ import javax.inject.Inject; import butterknife.ButterKnife; import butterknife.InjectView; import butterknife.OnItemClick; -import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.userstatus.SessionDialog; import static android.view.View.GONE; @@ -134,7 +133,7 @@ public abstract class BaseConfigurationWizard extends Activity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); + preferences = getSharedPreferences(Constants.SHARED_PREFERENCES, MODE_PRIVATE); fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); provider_manager = ProviderManager.getInstance(getAssets(), getExternalFilesDir(null)); @@ -220,7 +219,7 @@ public abstract class BaseConfigurationWizard extends Activity e.printStackTrace(); } - if (preferences.getBoolean(Constants.ALLOWED_ANON, false)) { + if (preferences.getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS, false)) { mConfigState.putExtra(SERVICES_RETRIEVED, true); downloadVpnCertificate(); @@ -297,7 +296,7 @@ public abstract class BaseConfigurationWizard extends Activity public void cancelSettingUpProvider() { mConfigState.setAction(PROVIDER_NOT_SET); adapter.showAllProviders(); - preferences.edit().remove(Provider.KEY).remove(Constants.ALLOWED_ANON).remove(Constants.KEY).apply(); + preferences.edit().remove(Provider.KEY).remove(Constants.PROVIDER_ALLOW_ANONYMOUS).remove(Constants.PROVIDER_KEY).apply(); } private void askDashboardToQuitApp() { diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java new file mode 100644 index 00000000..8723191c --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java @@ -0,0 +1,38 @@ +package se.leap.bitmaskclient; + +public interface Constants { + + ////////////////////////////////////////////// + // PREFERENCES CONSTANTS + ///////////////////////////////////////////// + + String SHARED_PREFERENCES = "LEAPPreferences"; + String PREFERENCES_APP_VERSION = "bitmask version"; + + + ////////////////////////////////////////////// + // EIP CONSTANTS + ///////////////////////////////////////////// + + String EIP_ACTION_CHECK_CERT_VALIDITY = "EIP.CHECK_CERT_VALIDITY"; + String EIP_ACTION_START = "EIP.START"; + String EIP_ACTION_STOP = "EIP.STOP"; + String EIP_ACTION_UPDATE = "EIP.UPDATE"; + String EIP_ACTION_IS_RUNNING = "EIP.IS_RUNNING"; + String EIP_ACTION_BLOCK_VPN_PROFILE = "EIP.ACTION_BLOCK_VPN_PROFILE"; + + String EIP_NOTIFICATION = "EIP.NOTIFICATION"; + String EIP_RECEIVER = "EIP.RECEIVER"; + String EIP_REQUEST = "EIP.REQUEST"; + + + ////////////////////////////////////////////// + // PROVIDER CONSTANTS + ///////////////////////////////////////////// + String PROVIDER_ALLOW_ANONYMOUS = "allow_anonymous"; + String PROVIDER_ALLOWED_REGISTERED = "allow_registration"; + String PROVIDER_VPN_CERTIFICATE = "cert"; + String PROVIDER_PRIVATE_KEY = "Constants.PROVIDER_PRIVATE_KEY"; + String PROVIDER_KEY = "Constants.PROVIDER_KEY"; + String PROVIDER_CONFIGURED = "Constants.PROVIDER_CONFIGURED"; +} diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 3f1663d0..1f0477c9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -1,20 +1,4 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -/** +/* * Copyright (c) 2013 LEAP Encryption Access Project and contributers * * This program is free software: you can redistribute it and/or modify @@ -57,8 +41,6 @@ import java.net.URL; import butterknife.ButterKnife; import butterknife.InjectView; -import de.blinkt.openvpn.core.VpnStatus; -import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.userstatus.SessionDialog; import se.leap.bitmaskclient.userstatus.User; import se.leap.bitmaskclient.userstatus.UserStatusFragment; @@ -76,7 +58,6 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec protected static final int SWITCH_PROVIDER = 1; public static final String TAG = Dashboard.class.getSimpleName(); - public static final String SHARED_PREFERENCES = "LEAPPreferences"; public static final String ACTION_QUIT = "quit"; public static final String ACTION_ASK_TO_CANCEL_VPN = "ask to cancel vpn"; public static final String REQUEST_CODE = "request_code"; @@ -84,7 +65,6 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec public static final String START_ON_BOOT = "dashboard start on boot"; //FIXME: remove OR FIX ON_BOOT public static final String ON_BOOT = "dashboard on boot"; - public static final String APP_VERSION = "bitmask version"; private static Context app; protected static SharedPreferences preferences; @@ -102,18 +82,14 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + preferences = getSharedPreferences(Constants.SHARED_PREFERENCES, MODE_PRIVATE); fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); - ProviderAPICommand.initialize(this); providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler(), this); if (app == null) { app = this; - - VpnStatus.initLogCache(getApplicationContext().getCacheDir()); handleVersion(); - User.init(getString(R.string.default_username)); } boolean provider_exists = previousProviderExists(savedInstanceState); if (provider_exists) { @@ -179,13 +155,11 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec private void handleVersion() { try { int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; - int lastDetectedVersion = preferences.getInt(APP_VERSION, 0); - preferences.edit().putInt(APP_VERSION, versionCode).apply(); switch (versionCode) { case 91: // 0.6.0 without Bug #5999 case 101: // 0.8.0 - if (!preferences.getString(Constants.KEY, "").isEmpty()) + if (!preferences.getString(Constants.PROVIDER_KEY, "").isEmpty()) eip_fragment.updateEipService(); break; } @@ -341,7 +315,7 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec public void downloadVpnCertificate() { boolean is_authenticated = User.loggedIn(); - boolean allowed_anon = preferences.getBoolean(Constants.ALLOWED_ANON, false); + boolean allowed_anon = preferences.getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS, false); if (allowed_anon || is_authenticated) ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_CERTIFICATE, providerAPI_result_receiver); else diff --git a/app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java b/app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java new file mode 100644 index 00000000..b2a39c1a --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java @@ -0,0 +1,5 @@ +package se.leap.bitmaskclient; + +public interface FeatureVersionCode { + int MULTIPLE_PROFILES = 132; +} diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java index 49cf3774..3a1fd6e0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java +++ b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java @@ -72,7 +72,6 @@ public class LeapSRPSession { * * @param username, the user ID * @param password, the user clear text password - * @param params, the SRP parameters for the session */ public LeapSRPSession(String username, String password) { this(username, password, null); @@ -84,7 +83,6 @@ public class LeapSRPSession { * * @param username, the user ID * @param password, the user clear text password - * @param params, the SRP parameters for the session * @param abytes, the random exponent used in the A public key */ public LeapSRPSession(String username, String password, byte[] abytes) { @@ -187,7 +185,6 @@ public class LeapSRPSession { * * @param b1 the positive source to build first BigInteger * @param b2 the positive source to build second BigInteger - * @param length * @return */ public byte[] xor(byte[] b1, byte[] b2) { diff --git a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java index 9171e816..9394e1b1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java +++ b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java @@ -2,7 +2,6 @@ package se.leap.bitmaskclient; import android.content.*; -import se.leap.bitmaskclient.eip.*; public class OnBootReceiver extends BroadcastReceiver { @@ -11,12 +10,12 @@ public class OnBootReceiver extends BroadcastReceiver { // Debug: am broadcast -a android.intent.action.BOOT_COMPLETED @Override public void onReceive(Context context, Intent intent) { - preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Context.MODE_PRIVATE); + preferences = context.getSharedPreferences(Constants.SHARED_PREFERENCES, Context.MODE_PRIVATE); boolean provider_configured = !preferences.getString(Provider.KEY, "").isEmpty(); boolean start_on_boot = preferences.getBoolean(Dashboard.START_ON_BOOT, false); if (provider_configured && start_on_boot) { Intent dashboard_intent = new Intent(context, Dashboard.class); - dashboard_intent.setAction(Constants.ACTION_START_EIP); + dashboard_intent.setAction(Constants.EIP_ACTION_START); dashboard_intent.putExtra(Dashboard.ON_BOOT, true); dashboard_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(dashboard_intent); diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderApiBase.java b/app/src/main/java/se/leap/bitmaskclient/ProviderApiBase.java index acac607c..6e3b8b08 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderApiBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderApiBase.java @@ -67,7 +67,6 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.TlsVersion; -import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.userstatus.SessionDialog; import se.leap.bitmaskclient.userstatus.User; import se.leap.bitmaskclient.userstatus.UserStatus; @@ -151,7 +150,7 @@ public abstract class ProviderApiBase extends IntentService { public void onCreate() { super.onCreate(); - preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); + preferences = getSharedPreferences(Constants.SHARED_PREFERENCES, MODE_PRIVATE); resources = getResources(); } @@ -817,11 +816,11 @@ public abstract class ProviderApiBase extends IntentService { RSAPrivateKey key = ConfigHelper.parseRsaKeyFromString(keyString); keyString = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT); - preferences.edit().putString(Constants.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n" + keyString + "-----END RSA PRIVATE KEY-----").commit(); + preferences.edit().putString(Constants.PROVIDER_PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n" + keyString + "-----END RSA PRIVATE KEY-----").commit(); X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(certificateString); certificateString = Base64.encodeToString(certificate.getEncoded(), Base64.DEFAULT); - preferences.edit().putString(Constants.VPN_CERTIFICATE, "-----BEGIN CERTIFICATE-----\n" + certificateString + "-----END CERTIFICATE-----").commit(); + preferences.edit().putString(Constants.PROVIDER_VPN_CERTIFICATE, "-----BEGIN CERTIFICATE-----\n" + certificateString + "-----END CERTIFICATE-----").commit(); return true; } catch (CertificateException e) { // TODO Auto-generated catch block diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java new file mode 100644 index 00000000..dd2be212 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java @@ -0,0 +1,135 @@ +package se.leap.bitmaskclient; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.support.annotation.IntDef; +import android.support.annotation.Nullable; +import android.util.Log; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.userstatus.User; + +/** + * Activity shown at startup. Evaluates if App is started for the first time or has been upgraded + * and acts and calls another activity accordingly. + * + */ +public class StartActivity extends Activity { + public static final String TAG = Dashboard.class.getSimpleName(); + + @Retention(RetentionPolicy.SOURCE) + @IntDef({FIRST, NORMAL, UPGRADE, DOWNGRADE}) + private @interface StartupMode {} + private static final int FIRST = 0; + private static final int NORMAL = 1; + private static final int UPGRADE = 2; + private static final int DOWNGRADE = 3; + + private int versionCode; + private int previousVersionCode; + + private SharedPreferences preferences; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + preferences = getSharedPreferences(Constants.SHARED_PREFERENCES, MODE_PRIVATE); + + Log.d(TAG, "Started"); + + switch (checkAppStart()) { + case NORMAL: + break; + + case FIRST: + // TODO start ProfileCreation & replace below code + break; + + case UPGRADE: + executeUpgrade(); + // TODO show donation dialog + break; + + case DOWNGRADE: + // TODO think how and why this should happen and what todo + break; + } + + // initialize app necessities + ProviderAPICommand.initialize(this); + VpnStatus.initLogCache(getApplicationContext().getCacheDir()); + User.init(getString(R.string.default_username)); + + // go to Dashboard + Intent intent = new Intent(this, Dashboard.class); + startActivity(intent); + } + + /** + * check if normal start, first run, up or downgrade + * @return @StartupMode + */ + @StartupMode + private int checkAppStart() { + try { + versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; + previousVersionCode = preferences.getInt(Constants.PREFERENCES_APP_VERSION, -1); + + // versions do match -> normal start + if (versionCode == previousVersionCode) { + Log.d(TAG, "App start was: NORMAL START"); + return NORMAL; + } + + // no previous app version -> first start + if (previousVersionCode == -1 ) { + Log.d(TAG, "FIRST START"); + return FIRST; + } + + // version has increased -> upgrade + if (versionCode > previousVersionCode) { + Log.d(TAG, "UPGRADE"); + return UPGRADE; + } + // version has decreased -> downgrade + if (versionCode < previousVersionCode) { + Log.d(TAG, "DOWNGRADE"); + return DOWNGRADE; + } + + } catch (PackageManager.NameNotFoundException e) { + Log.d(TAG, "Splash screen didn't find any " + getPackageName() + " package"); + } + + return NORMAL; + } + + /** + * execute necessary upgrades for version change + */ + private void executeUpgrade() { + if (hasNewFeature(FeatureVersionCode.MULTIPLE_PROFILES)) { + // TODO prepare usage of multiple profiles + } + + // ensure all upgrades have passed before storing new information + preferences.edit().putInt(Constants.PREFERENCES_APP_VERSION, versionCode).apply(); + } + + /** + * check if an upgrade passed or moved to given milestone + * @param featureVersionCode Version code of the Milestone FeatureVersionCode.MILE_STONE + * @return true if milestone is reached - false otherwise + */ + private boolean hasNewFeature(int featureVersionCode) { + return previousVersionCode < featureVersionCode && versionCode >= featureVersionCode; + } + +} diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java index c85b0151..f787a955 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java @@ -32,8 +32,10 @@ import de.blinkt.openvpn.core.IOpenVPNServiceInternal; import de.blinkt.openvpn.core.OpenVPNService; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VpnStatus; -import mbanje.kurt.fabbutton.*; -import se.leap.bitmaskclient.eip.*; +import se.leap.bitmaskclient.eip.EIP; +import se.leap.bitmaskclient.eip.EipStatus; +import se.leap.bitmaskclient.eip.VoidVpnService; +import se.leap.bitmaskclient.userstatus.FabButton; public class VpnFragment extends Fragment implements Observer { @@ -112,7 +114,7 @@ public class VpnFragment extends Fragment implements Observer { public void onResume() { super.onResume(); //FIXME: avoid race conditions while checking certificate an logging in at about the same time - //eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); + //eipCommand(Constants.EIP_ACTION_CHECK_CERT_VALIDITY); handleNewState(eip_status); bindOpenVpnService(); } @@ -161,13 +163,13 @@ public class VpnFragment extends Fragment implements Observer { } private boolean canStartEIP() { - boolean certificateExists = !Dashboard.preferences.getString(Constants.VPN_CERTIFICATE, "").isEmpty(); - boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false); + boolean certificateExists = !Dashboard.preferences.getString(Constants.PROVIDER_VPN_CERTIFICATE, "").isEmpty(); + boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS, false); return (isAllowedAnon || certificateExists) && !eip_status.isConnected() && !eip_status.isConnecting(); } private boolean canLogInToStartEIP() { - boolean isAllowedRegistered = Dashboard.preferences.getBoolean(Constants.ALLOWED_REGISTERED, false); + boolean isAllowedRegistered = Dashboard.preferences.getBoolean(Constants.PROVIDER_ALLOWED_REGISTERED, false); boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); return isAllowedRegistered && !isLoggedIn && !eip_status.isConnecting() && !eip_status.isConnected(); } @@ -204,7 +206,7 @@ public class VpnFragment extends Fragment implements Observer { eip_status.setConnecting(); saveStatus(); - eipCommand(Constants.ACTION_START_EIP); + eipCommand(Constants.EIP_ACTION_START); } private void stop() { @@ -227,7 +229,7 @@ public class VpnFragment extends Fragment implements Observer { } protected void stopEipIfPossible() { - eipCommand(Constants.ACTION_STOP_EIP); + eipCommand(Constants.EIP_ACTION_STOP); } private void downloadEIPServiceConfig() { @@ -255,7 +257,7 @@ public class VpnFragment extends Fragment implements Observer { } protected void updateEipService() { - eipCommand(Constants.ACTION_UPDATE_EIP_SERVICE); + eipCommand(Constants.EIP_ACTION_UPDATE); } /** @@ -268,7 +270,7 @@ public class VpnFragment extends Fragment implements Observer { // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? Intent vpn_intent = new Intent(dashboard.getApplicationContext(), EIP.class); vpn_intent.setAction(action); - vpn_intent.putExtra(Constants.RECEIVER_TAG, eip_receiver); + vpn_intent.putExtra(Constants.EIP_RECEIVER, eip_receiver); dashboard.startService(vpn_intent); } @@ -341,9 +343,9 @@ public class VpnFragment extends Fragment implements Observer { protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(Constants.REQUEST_TAG); + String request = resultData.getString(Constants.EIP_REQUEST); - if (request.equals(Constants.ACTION_START_EIP)) { + if (request.equals(Constants.EIP_ACTION_START)) { switch (resultCode) { case Activity.RESULT_OK: break; @@ -351,7 +353,7 @@ public class VpnFragment extends Fragment implements Observer { break; } - } else if (request.equals(Constants.ACTION_STOP_EIP)) { + } else if (request.equals(Constants.EIP_ACTION_STOP)) { switch (resultCode) { case Activity.RESULT_OK: stop(); @@ -366,7 +368,7 @@ public class VpnFragment extends Fragment implements Observer { case Activity.RESULT_CANCELED: break; } - } else if (request.equals(Constants.ACTION_CHECK_CERT_VALIDITY)) { + } else if (request.equals(Constants.EIP_ACTION_CHECK_CERT_VALIDITY)) { switch (resultCode) { case Activity.RESULT_OK: break; @@ -374,7 +376,7 @@ public class VpnFragment extends Fragment implements Observer { dashboard.downloadVpnCertificate(); break; } - } else if (request.equals(Constants.ACTION_UPDATE_EIP_SERVICE)) { + } else if (request.equals(Constants.EIP_ACTION_UPDATE)) { switch (resultCode) { case Activity.RESULT_OK: if (wants_to_connect) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java deleted file mode 100644 index db1cb4a1..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -package se.leap.bitmaskclient.eip; - -/** - * Constants for intent passing, shared preferences - * - * @author Parménides GV <parmegv@sdf.org> - */ -public interface Constants { - - public final static String TAG = Constants.class.getSimpleName(); - - public final static String ACTION_CHECK_CERT_VALIDITY = TAG + ".CHECK_CERT_VALIDITY"; - public final static String ACTION_START_EIP = TAG + ".START_EIP"; - public final static String ACTION_STOP_EIP = TAG + ".STOP_EIP"; - public final static String ACTION_UPDATE_EIP_SERVICE = TAG + ".UPDATE_EIP_SERVICE"; - public final static String ACTION_IS_EIP_RUNNING = TAG + ".IS_RUNNING"; - public final static String EIP_NOTIFICATION = TAG + ".EIP_NOTIFICATION"; - public final static String ALLOWED_ANON = "allow_anonymous"; - public final static String ALLOWED_REGISTERED = "allow_registration"; - public final static String VPN_CERTIFICATE = "cert"; - public final static String PRIVATE_KEY = TAG + ".PRIVATE_KEY"; - public final static String KEY = TAG + ".KEY"; - public final static String RECEIVER_TAG = TAG + ".RECEIVER_TAG"; - public final static String REQUEST_TAG = TAG + ".REQUEST_TAG"; - public final static String START_BLOCKING_VPN_PROFILE = TAG + ".START_BLOCKING_VPN_PROFILE"; - public final static String PROVIDER_CONFIGURED = TAG + ".PROVIDER_CONFIGURED"; - -} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 28a9bb50..0b35dc3d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -25,8 +25,6 @@ import org.json.*; import de.blinkt.openvpn.*; import se.leap.bitmaskclient.*; -import static se.leap.bitmaskclient.eip.Constants.*; - /** * EIP is the abstract base class for interacting with and managing the Encrypted * Internet Proxy connection. Connections are started, stopped, and queried through @@ -59,7 +57,7 @@ public final class EIP extends IntentService { super.onCreate(); context = getApplicationContext(); - preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); + preferences = getSharedPreferences(Constants.SHARED_PREFERENCES, MODE_PRIVATE); eip_definition = eipDefinitionFromPreferences(); if (gateways_manager.isEmpty()) gatewaysFromPreferences(); @@ -68,17 +66,17 @@ public final class EIP extends IntentService { @Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); - mReceiver = intent.getParcelableExtra(RECEIVER_TAG); + mReceiver = intent.getParcelableExtra(Constants.EIP_RECEIVER); - if (action.equals(ACTION_START_EIP)) + if (action.equals(Constants.EIP_ACTION_START)) startEIP(); - else if (action.equals(ACTION_STOP_EIP)) + else if (action.equals(Constants.EIP_ACTION_STOP)) stopEIP(); - else if (action.equals(ACTION_IS_EIP_RUNNING)) + else if (action.equals(Constants.EIP_ACTION_IS_RUNNING)) isRunning(); - else if (action.equals(ACTION_UPDATE_EIP_SERVICE)) + else if (action.equals(Constants.EIP_ACTION_UPDATE)) updateEIPService(); - else if (action.equals(ACTION_CHECK_CERT_VALIDITY)) + else if (action.equals(Constants.EIP_ACTION_CHECK_CERT_VALIDITY)) checkCertValidity(); } @@ -96,9 +94,9 @@ public final class EIP extends IntentService { if (gateway != null && gateway.getProfile() != null) { mReceiver = VpnFragment.getReceiver(); launchActiveGateway(); - tellToReceiver(ACTION_START_EIP, Activity.RESULT_OK); + tellToReceiver(Constants.EIP_ACTION_START, Activity.RESULT_OK); } else - tellToReceiver(ACTION_START_EIP, Activity.RESULT_CANCELED); + tellToReceiver(Constants.EIP_ACTION_START, Activity.RESULT_CANCELED); } /** @@ -126,7 +124,7 @@ public final class EIP extends IntentService { if (eip_status.isConnected() || eip_status.isConnecting()) result_code = Activity.RESULT_OK; - tellToReceiver(ACTION_STOP_EIP, result_code); + tellToReceiver(Constants.EIP_ACTION_STOP, result_code); } /** @@ -139,7 +137,7 @@ public final class EIP extends IntentService { int resultCode = (eip_status.isConnected()) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - tellToReceiver(ACTION_IS_EIP_RUNNING, resultCode); + tellToReceiver(Constants.EIP_ACTION_IS_RUNNING, resultCode); } /** @@ -150,13 +148,13 @@ public final class EIP extends IntentService { eip_definition = eipDefinitionFromPreferences(); if (eip_definition.length() > 0) updateGateways(); - tellToReceiver(ACTION_UPDATE_EIP_SERVICE, Activity.RESULT_OK); + tellToReceiver(Constants.EIP_ACTION_UPDATE, Activity.RESULT_OK); } private JSONObject eipDefinitionFromPreferences() { JSONObject result = new JSONObject(); try { - String eip_definition_string = preferences.getString(KEY, ""); + String eip_definition_string = preferences.getString(Constants.PROVIDER_KEY, ""); if (!eip_definition_string.isEmpty()) { result = new JSONObject(eip_definition_string); } @@ -186,17 +184,17 @@ public final class EIP extends IntentService { } private void checkCertValidity() { - VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(VPN_CERTIFICATE, "")); + VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(Constants.PROVIDER_VPN_CERTIFICATE, "")); int resultCode = validator.isValid() ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - tellToReceiver(ACTION_CHECK_CERT_VALIDITY, resultCode); + tellToReceiver(Constants.EIP_ACTION_CHECK_CERT_VALIDITY, resultCode); } private void tellToReceiver(String action, int resultCode) { if (mReceiver != null) { Bundle resultData = new Bundle(); - resultData.putString(REQUEST_TAG, action); + resultData.putString(Constants.EIP_REQUEST, action); mReceiver.send(resultCode, resultData); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java index 177f553e..43c16d00 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -36,6 +36,7 @@ import java.util.List; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.Connection; import de.blinkt.openvpn.core.ProfileManager; +import se.leap.bitmaskclient.Constants; import se.leap.bitmaskclient.Provider; /** @@ -123,8 +124,8 @@ public class GatewaysManager { JSONObject result = new JSONObject(); try { result.put(Provider.CA_CERT, preferences.getString(Provider.CA_CERT, "")); - result.put(Constants.PRIVATE_KEY, preferences.getString(Constants.PRIVATE_KEY, "")); - result.put(Constants.VPN_CERTIFICATE, preferences.getString(Constants.VPN_CERTIFICATE, "")); + result.put(Constants.PROVIDER_PRIVATE_KEY, preferences.getString(Constants.PROVIDER_PRIVATE_KEY, "")); + result.put(Constants.PROVIDER_VPN_CERTIFICATE, preferences.getString(Constants.PROVIDER_VPN_CERTIFICATE, "")); } catch (JSONException e) { e.printStackTrace(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java index 5c9263b3..b1aab79c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java @@ -5,6 +5,8 @@ import android.content.*; import android.net.*; import android.os.*; +import se.leap.bitmaskclient.Constants; + public class VoidVpnLauncher extends Activity { private static final int VPN_USER_PERMISSION = 71; @@ -28,7 +30,7 @@ public class VoidVpnLauncher extends Activity { if (requestCode == VPN_USER_PERMISSION) { if (resultCode == RESULT_OK) { Intent void_vpn_service = new Intent(getApplicationContext(), VoidVpnService.class); - void_vpn_service.setAction(Constants.START_BLOCKING_VPN_PROFILE); + void_vpn_service.setAction(Constants.EIP_ACTION_BLOCK_VPN_PROFILE); startService(void_vpn_service); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java index cbf0fed2..ff375553 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -6,6 +6,8 @@ import android.os.*; import java.io.*; +import se.leap.bitmaskclient.Constants; + public class VoidVpnService extends VpnService { static final String TAG = VoidVpnService.class.getSimpleName(); @@ -16,7 +18,7 @@ public class VoidVpnService extends VpnService { @Override public int onStartCommand(Intent intent, int flags, int startId) { String action = intent != null ? intent.getAction() : ""; - if (action == Constants.START_BLOCKING_VPN_PROFILE) { + if (action == Constants.EIP_ACTION_BLOCK_VPN_PROFILE) { thread = new Thread(new Runnable() { public void run() { Builder builder = new Builder(); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java index f428099e..54563ec4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -118,14 +118,14 @@ public class VpnConfigGenerator { String key = "<key>" + new_line - + secrets.getString(Constants.PRIVATE_KEY) + + secrets.getString(Constants.PROVIDER_PRIVATE_KEY) + new_line + "</key>"; String openvpn_cert = "<cert>" + new_line - + secrets.getString(Constants.VPN_CERTIFICATE) + + secrets.getString(Constants.PROVIDER_VPN_CERTIFICATE) + new_line + "</cert>"; diff --git a/app/src/main/res/drawable-ldpi/mask.png b/app/src/main/res/drawable-ldpi/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4e22d99feddea11a47455f3959c1036dc0038715 GIT binary patch literal 8743 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/mask.png b/app/src/main/res/drawable-mdpi/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..e53cb15c03e13684da02895f31892f6ce4f2934a GIT binary patch literal 6324 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/mask.png b/app/src/main/res/drawable-xxxhdpi/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4297d90c5fa111e0fbb005fb0613568194f05b56 GIT binary patch literal 43251 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/ic_colorsquare.xml b/app/src/main/res/drawable/ic_colorsquare.xml new file mode 100644 index 00000000..4b60e9dc --- /dev/null +++ b/app/src/main/res/drawable/ic_colorsquare.xml @@ -0,0 +1,52 @@ +<vector android:height="24dp" android:viewportHeight="100.0" + android:viewportWidth="100.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:pathData="M50,50m-82000,0a82000,82000 0,1 1,164000 0a82000,82000 0,1 1,-164000 0"/> + <path android:fillAlpha="1" android:fillColor="#e6ee9c" + android:pathData="M50,50 L30664.67,-73860.37A80000,80000 0,0 0,50 -79950Z" + android:strokeColor="#e6ee9c" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#fff59d" + android:pathData="m50,50 l56568.54,-56568.54a80000,80000 0,0 0,-25953.87 -17341.82z" + android:strokeColor="#fff59d" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#ffe082" + android:pathData="m50,50 l73910.37,-30614.67a80000,80000 0,0 0,-17341.82 -25953.87z" + android:strokeColor="#ffe082" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#ffcc80" + android:pathData="M50,50L80050,50A80000,80000 0,0 0,73960.37 -30564.67Z" + android:strokeColor="#ffcc80" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#ffab91" + android:pathData="M50,50 L73960.37,30664.67A80000,80000 0,0 0,80050 50Z" + android:strokeColor="#ffab91" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#ef9a9a" + android:pathData="m50,50 l56568.54,56568.54a80000,80000 0,0 0,17341.82 -25953.87z" + android:strokeColor="#ef9a9a" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#f48fb1" + android:pathData="m50,50 l30614.67,73910.37a80000,80000 0,0 0,25953.87 -17341.82z" + android:strokeColor="#f48fb1" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#ce93d8" + android:pathData="M50,50L50,80050A80000,80000 0,0 0,30664.67 73960.37Z" + android:strokeColor="#ce93d8" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#b39ddb" + android:pathData="M50,50 L-30564.67,73960.37A80000,80000 0,0 0,50 80050Z" + android:strokeColor="#b39ddb" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#9fa8da" + android:pathData="m50,50 l-56568.54,56568.54a80000,80000 0,0 0,25953.87 17341.82z" + android:strokeColor="#9fa8da" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#90caf9" + android:pathData="m50,50 l-73910.37,30614.67a80000,80000 0,0 0,17341.82 25953.87z" + android:strokeColor="#90caf9" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#81d4fa" + android:pathData="m50,50l-80000,0a80000,80000 0,0 0,6089.64 30614.67z" + android:strokeColor="#81d4fa" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#80deea" + android:pathData="M50,50 L-73860.37,-30564.67A80000,80000 0,0 0,-79950 50Z" + android:strokeColor="#80deea" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#80cbc4" + android:pathData="m50,50 l-56568.54,-56568.54a80000,80000 0,0 0,-17341.82 25953.87z" + android:strokeColor="#80cbc4" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#a5d6a7" + android:pathData="m50,50 l-30614.67,-73910.37a80000,80000 0,0 0,-25953.87 17341.82z" + android:strokeColor="#a5d6a7" android:strokeWidth="0"/> + <path android:fillAlpha="1" android:fillColor="#c5e1a5" + android:pathData="m50,50l0,-80000a80000,80000 0,0 0,-30614.67 6089.64z" + android:strokeColor="#c5e1a5" android:strokeWidth="0"/> +</vector> diff --git a/app/src/main/res/drawable/splash_page.xml b/app/src/main/res/drawable/splash_page.xml new file mode 100644 index 00000000..0a083c7e --- /dev/null +++ b/app/src/main/res/drawable/splash_page.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> + <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:drawable="@drawable/ic_colorsquare" + android:gravity="fill_horizontal|fill_vertical"/> + + <item android:drawable="@drawable/mask" + android:gravity="center" > + </item> + +</layer-list> \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml deleted file mode 100644 index cb503b86..00000000 --- a/app/src/main/res/values/attrs.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<resources> - <declare-styleable name="FileSelectLayout"> - <attr name="title" format="string|reference" /> -<!-- <attr name="taskid" format="integer" /> --> - </declare-styleable> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..1818312e --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="colorPrimary">#b39ddb</color> + <color name="colorPrimaryDark">#ac97d2</color> + + <color name="red200">#ef9a9a</color> + <color name="pink200">#f48fb1</color> + <color name="purple200">#ce93d8</color> + <color name="deepPurple200">#b39ddb</color> + <color name="indigo200">#9fa8da</color> + <color name="blue200">#90caf9</color> + <color name="lightBlue200">#81d4fa</color> + <color name="cyan200">#80deea</color> + <color name="teal200">#80cbc4</color> + <color name="green200">#a5d6a7</color> + <color name="lightGreen200">#c5e1a5</color> + <color name="lime200">#e6ee9c</color> + <color name="yellow200">#fff59d</color> + <color name="amber200">#ffe082</color> + <color name="orange200">#ffcc80</color> + <color name="deepOrange200">#ffab91</color> + +</resources> diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 00000000..80607409 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimary</item> + </style> + <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar"> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimary</item> + <item name="android:windowBackground">@drawable/splash_page</item> + </style> +</resources> diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java index 70a2c27c..fadb03c3 100644 --- a/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java @@ -33,7 +33,6 @@ import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLHandshakeException; import okhttp3.OkHttpClient; -import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.eip.EIP; import static se.leap.bitmaskclient.R.string.error_io_exception_user_message; @@ -120,8 +119,8 @@ public class ProviderAPI extends ProviderApiBase { //TODO setProviderName(name); preferences.edit().putString(Provider.KEY, provider_json.toString()).commit(); - preferences.edit().putBoolean(Constants.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.ALLOWED_ANON)).commit(); - preferences.edit().putBoolean(Constants.ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.ALLOWED_REGISTERED)).commit(); + preferences.edit().putBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS)).commit(); + preferences.edit().putBoolean(Constants.PROVIDER_ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(Constants.PROVIDER_ALLOWED_REGISTERED)).commit(); result.putBoolean(RESULT_KEY, true); } catch (JSONException e) { @@ -150,7 +149,7 @@ public class ProviderAPI extends ProviderApiBase { JSONObject eip_service_json = new JSONObject(eip_service_json_string); eip_service_json.getInt(Provider.API_RETURN_SERIAL); - preferences.edit().putString(Constants.KEY, eip_service_json.toString()).commit(); + preferences.edit().putString(Constants.PROVIDER_KEY, eip_service_json.toString()).commit(); result.putBoolean(RESULT_KEY, true); } catch (NullPointerException | JSONException e) { @@ -173,7 +172,7 @@ public class ProviderAPI extends ProviderApiBase { JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); String provider_main_url = provider_json.getString(Provider.API_URL); - URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + Constants.VPN_CERTIFICATE); + URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + Constants.PROVIDER_VPN_CERTIFICATE); String cert_string = downloadWithProviderCA(new_cert_string_url.toString()); diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderDetailFragment.java b/app/src/production/java/se/leap/bitmaskclient/ProviderDetailFragment.java index da7f8763..c7224ede 100644 --- a/app/src/production/java/se/leap/bitmaskclient/ProviderDetailFragment.java +++ b/app/src/production/java/se/leap/bitmaskclient/ProviderDetailFragment.java @@ -2,8 +2,6 @@ package se.leap.bitmaskclient; import org.json.*; -import se.leap.bitmaskclient.eip.*; - import android.app.*; import android.content.*; import android.os.*; @@ -22,7 +20,7 @@ public class ProviderDetailFragment extends DialogFragment { LayoutInflater inflater = getActivity().getLayoutInflater(); View provider_detail_view = inflater.inflate(R.layout.provider_detail_fragment, null); - JSONObject provider_json = new JSONObject(getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, getActivity().MODE_PRIVATE).getString(Provider.KEY, "")); + JSONObject provider_json = new JSONObject(getActivity().getSharedPreferences(Constants.SHARED_PREFERENCES, getActivity().MODE_PRIVATE).getString(Provider.KEY, "")); final TextView domain = (TextView) provider_detail_view.findViewById(R.id.provider_detail_domain); domain.setText(provider_json.getString(Provider.DOMAIN)); @@ -59,7 +57,7 @@ public class ProviderDetailFragment extends DialogFragment { private boolean anon_allowed(JSONObject provider_json) { try { JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); - return service_description.has(Constants.ALLOWED_ANON) && service_description.getBoolean(Constants.ALLOWED_ANON); + return service_description.has(Constants.PROVIDER_ALLOW_ANONYMOUS) && service_description.getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS); } catch (JSONException e) { return false; } @@ -77,8 +75,8 @@ public class ProviderDetailFragment extends DialogFragment { @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); - SharedPreferences.Editor editor = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit(); - editor.remove(Provider.KEY).remove(Constants.ALLOWED_ANON).remove(Constants.KEY).commit(); + SharedPreferences.Editor editor = getActivity().getSharedPreferences(Constants.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit(); + editor.remove(Provider.KEY).remove(Constants.PROVIDER_ALLOW_ANONYMOUS).remove(Constants.PROVIDER_KEY).commit(); interface_with_configuration_wizard.cancelAndShowAllProviders(); } diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java index 833346fa..ea212480 100644 --- a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java +++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java @@ -14,6 +14,7 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.IOException; +import se.leap.bitmaskclient.Constants; import se.leap.bitmaskclient.Provider; import se.leap.bitmaskclient.TestUtils; @@ -42,9 +43,9 @@ public class GatewaysManagerTest { JSONObject secrets = new JSONObject(getJsonStringFor("secrets.json")); - when(sharedPreferences.getString(eq(Constants.PRIVATE_KEY), anyString())).thenReturn(secrets.getString(Constants.PRIVATE_KEY)); + when(sharedPreferences.getString(eq(Constants.PROVIDER_PRIVATE_KEY), anyString())).thenReturn(secrets.getString(Constants.PROVIDER_PRIVATE_KEY)); when(sharedPreferences.getString(eq(Provider.CA_CERT), anyString())).thenReturn(secrets.getString(Provider.CA_CERT)); - when(sharedPreferences.getString(eq(Constants.VPN_CERTIFICATE), anyString())).thenReturn(secrets.getString(Constants.VPN_CERTIFICATE)); + when(sharedPreferences.getString(eq(Constants.PROVIDER_VPN_CERTIFICATE), anyString())).thenReturn(secrets.getString(Constants.PROVIDER_VPN_CERTIFICATE)); when(mockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPreferences); diff --git a/build.gradle b/build.gradle index dc2396d7..3970daf0 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,10 @@ buildscript { repositories { mavenCentral() jcenter() + maven { + url 'https://maven.google.com/' + name 'Google' + } } dependencies { classpath 'com.android.tools.build:gradle:2.3.1' @@ -16,5 +20,9 @@ allprojects { repositories { mavenCentral() jcenter() + maven { + url 'https://maven.google.com/' + name 'Google' + } } } -- GitLab