From 3eb5405141d14a0c75c669c168b272878346cc38 Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Sat, 27 Jan 2018 16:09:38 +0100 Subject: fix comments for mergerequest --- .../test/BaseTestDashboardFragment.java | 4 +- .../test/TestConfigurationWizard.java | 114 ----- .../test/TestProviderListActivity.java | 114 +++++ .../se/leap/bitmaskclient/ConfigurationWizard.java | 133 ------ .../leap/bitmaskclient/ProviderListActivity.java | 133 ++++++ .../se/leap/bitmaskclient/ProviderListContent.java | 2 +- app/src/main/AndroidManifest.xml | 2 +- .../bitmaskclient/BaseConfigurationWizard.java | 475 -------------------- .../java/se/leap/bitmaskclient/ConfigHelper.java | 10 +- .../main/java/se/leap/bitmaskclient/Dashboard.java | 10 +- .../bitmaskclient/ProviderListBaseActivity.java | 478 +++++++++++++++++++++ .../java/se/leap/bitmaskclient/StartActivity.java | 5 +- .../drawer/NavigationDrawerFragment.java | 4 +- .../configuration_wizard_activity.xml | 2 +- .../res/layout/configuration_wizard_activity.xml | 2 +- .../se/leap/bitmaskclient/ConfigurationWizard.java | 104 ----- .../leap/bitmaskclient/ProviderListActivity.java | 104 +++++ .../se/leap/bitmaskclient/ProviderListContent.java | 2 +- 18 files changed, 850 insertions(+), 848 deletions(-) delete mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/test/TestConfigurationWizard.java create mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/test/TestProviderListActivity.java delete mode 100644 app/src/insecure/java/se/leap/bitmaskclient/ConfigurationWizard.java create mode 100644 app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java delete mode 100644 app/src/production/java/se/leap/bitmaskclient/ConfigurationWizard.java create mode 100644 app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java (limited to 'app/src') diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java index 956049dc..e187d424 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java @@ -7,7 +7,7 @@ import android.view.View; import com.robotium.solo.Solo; -import se.leap.bitmaskclient.ConfigurationWizard; +import se.leap.bitmaskclient.ProviderListActivity; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.R; @@ -43,7 +43,7 @@ public abstract class BaseTestDashboardFragment extends ActivityInstrumentationT void tapSwitchProvider() { solo.clickOnMenuItem(solo.getString(R.string.switch_provider_menu_option)); - solo.waitForActivity(ConfigurationWizard.class); + solo.waitForActivity(ProviderListActivity.class); } private void useRegistered() { diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestConfigurationWizard.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestConfigurationWizard.java deleted file mode 100644 index c0d3aab1..00000000 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestConfigurationWizard.java +++ /dev/null @@ -1,114 +0,0 @@ -package se.leap.bitmaskclient.test; - -import android.test.ActivityInstrumentationTestCase2; -import android.widget.ListView; - -import com.robotium.solo.Solo; - -import java.io.IOException; - -import se.leap.bitmaskclient.ConfigurationWizard; -import se.leap.bitmaskclient.R; - -public class TestConfigurationWizard extends ActivityInstrumentationTestCase2 { - - private Solo solo; - - public TestConfigurationWizard() { - super(ConfigurationWizard.class); - } - - - @Override - protected void setUp() throws Exception { - super.setUp(); - solo = new Solo(getInstrumentation(), getActivity()); - Screenshot.initialize(solo); - } - - @Override - protected void tearDown() throws Exception { - solo.finishOpenedActivities(); - super.tearDown(); - } - - /** - * Tests should run independently from each other. We need a better approach to test the amount of providers added - */ - /*public void testListProviders() { - assertEquals(solo.getCurrentViews(ListView.class).size(), 1); - - assertEquals("Number of available providers differ", predefinedProviders() + added_providers, shownProviders()); - }*/ - - private int shownProviders() { - return solo.getCurrentViews(ListView.class).get(0).getCount(); - } - - private int predefinedProviders() { - int predefined_providers = 0; - try { - predefined_providers = solo.getCurrentActivity().getAssets().list("urls").length; - } catch (IOException e) { - e.printStackTrace(); - return predefined_providers; - } - - return predefined_providers; - } - - public void testSelectProvider() { - Screenshot.take("Initial CW"); - selectProvider("demo.bitmask.net"); - } - - private void selectProvider(String provider) { - solo.clickOnText(provider); - Screenshot.setTimeToSleep(1); - Screenshot.take("Configuring provider"); - waitForProviderDetails(); - } - - private void waitForProviderDetails() { - String text = solo.getString(R.string.provider_details_title); - assertTrue("Provider details dialog did not appear", solo.waitForText(text, 1, 60*1000)); - Screenshot.take("Provider details"); - } - - public void testAddNewProvider() { - //addProvider("calyx.net"); - addProvider("riseup.net", true); - } - - public void testAddFalseProviderReturning404() { - //addProvider("calyx.net"); - addProvider("startpage.com", false); - } - - public void testAddFalseProviderReturning200() { - //addProvider("calyx.net"); - addProvider("test.com", false); - } - - private void addProvider(String url, boolean expectSuccess) { - - solo.clickOnActionBarItem(R.id.new_provider); - solo.enterText(0, url); - if ( BuildConfig.FLAVOR.equals("insecure")) { - solo.clickOnCheckBox(0); - } - solo.clickOnText(solo.getString(R.string.save)); - if (expectSuccess) { - waitForProviderDetails(); - } else { - waitForNoValidProviderError(); - } - solo.goBack(); - } - - private void waitForNoValidProviderError() { - String text = solo.getString(R.string.malformed_url); - assertTrue("Provider details dialog did not appear", solo.waitForText(text, 1, 60*1000)); - } - -} diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestProviderListActivity.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestProviderListActivity.java new file mode 100644 index 00000000..4ab705e7 --- /dev/null +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestProviderListActivity.java @@ -0,0 +1,114 @@ +package se.leap.bitmaskclient.test; + +import android.test.ActivityInstrumentationTestCase2; +import android.widget.ListView; + +import com.robotium.solo.Solo; + +import java.io.IOException; + +import se.leap.bitmaskclient.ProviderListActivity; +import se.leap.bitmaskclient.R; + +public class TestProviderListActivity extends ActivityInstrumentationTestCase2 { + + private Solo solo; + + public TestProviderListActivity() { + super(ProviderListActivity.class); + } + + + @Override + protected void setUp() throws Exception { + super.setUp(); + solo = new Solo(getInstrumentation(), getActivity()); + Screenshot.initialize(solo); + } + + @Override + protected void tearDown() throws Exception { + solo.finishOpenedActivities(); + super.tearDown(); + } + + /** + * Tests should run independently from each other. We need a better approach to test the amount of providers added + */ + /*public void testListProviders() { + assertEquals(solo.getCurrentViews(ListView.class).size(), 1); + + assertEquals("Number of available providers differ", predefinedProviders() + added_providers, shownProviders()); + }*/ + + private int shownProviders() { + return solo.getCurrentViews(ListView.class).get(0).getCount(); + } + + private int predefinedProviders() { + int predefined_providers = 0; + try { + predefined_providers = solo.getCurrentActivity().getAssets().list("urls").length; + } catch (IOException e) { + e.printStackTrace(); + return predefined_providers; + } + + return predefined_providers; + } + + public void testSelectProvider() { + Screenshot.take("Initial CW"); + selectProvider("demo.bitmask.net"); + } + + private void selectProvider(String provider) { + solo.clickOnText(provider); + Screenshot.setTimeToSleep(1); + Screenshot.take("Configuring provider"); + waitForProviderDetails(); + } + + private void waitForProviderDetails() { + String text = solo.getString(R.string.provider_details_title); + assertTrue("Provider details dialog did not appear", solo.waitForText(text, 1, 60*1000)); + Screenshot.take("Provider details"); + } + + public void testAddNewProvider() { + //addProvider("calyx.net"); + addProvider("riseup.net", true); + } + + public void testAddFalseProviderReturning404() { + //addProvider("calyx.net"); + addProvider("startpage.com", false); + } + + public void testAddFalseProviderReturning200() { + //addProvider("calyx.net"); + addProvider("test.com", false); + } + + private void addProvider(String url, boolean expectSuccess) { + + solo.clickOnActionBarItem(R.id.new_provider); + solo.enterText(0, url); + if ( BuildConfig.FLAVOR.equals("insecure")) { + solo.clickOnCheckBox(0); + } + solo.clickOnText(solo.getString(R.string.save)); + if (expectSuccess) { + waitForProviderDetails(); + } else { + waitForNoValidProviderError(); + } + solo.goBack(); + } + + private void waitForNoValidProviderError() { + String text = solo.getString(R.string.malformed_url); + assertTrue("Provider details dialog did not appear", solo.waitForText(text, 1, 60*1000)); + } + +} diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/insecure/java/se/leap/bitmaskclient/ConfigurationWizard.java deleted file mode 100644 index b5ce824f..00000000 --- a/app/src/insecure/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributors - * - * 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 . - */ -package se.leap.bitmaskclient; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.FragmentTransaction; - -import java.net.MalformedURLException; -import java.net.URL; - -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; - -/** - * Activity that builds and shows the list of known available providers. - *

- * It also allows the user to enter custom providers with a button. - * - * @author parmegv - * @author cyberta - */ -public class ConfigurationWizard extends BaseConfigurationWizard { - - @Override - protected void onItemSelectedLogic() { - boolean danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, true); - setUpProvider(danger_on); - } - - @Override - public void cancelSettingUpProvider() { - super.cancelSettingUpProvider(); - preferences.edit().remove(ProviderItem.DANGER_ON).apply(); - } - - /** - * Open the new provider dialog with data - */ - public void addAndSelectNewProvider(String main_url, boolean danger_on) { - FragmentTransaction fragment_transaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); - - DialogFragment newFragment = new NewProviderDialog(); - Bundle data = new Bundle(); - data.putString(Provider.MAIN_URL, main_url); - data.putBoolean(ProviderItem.DANGER_ON, danger_on); - newFragment.setArguments(data); - newFragment.show(fragment_transaction, NewProviderDialog.TAG); - } - - public void showAndSelectProvider(String provider_main_url, boolean danger_on) { - try { - provider = new Provider(new URL((provider_main_url))); - adapter.add(provider); - adapter.saveProviders(); - autoSelectProvider(provider, danger_on); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } - - private void autoSelectProvider(Provider provider, boolean danger_on) { - preferences.edit().putBoolean(ProviderItem.DANGER_ON, danger_on).apply(); - this.provider = provider; - onItemSelectedLogic(); - showProgressBar(); - } - - /** - * Asks ProviderAPI to download a new provider.json file - * - * @param danger_on tells if HTTPS client should bypass certificate errors - */ - public void setUpProvider(boolean danger_on) { - mConfigState.setAction(SETTING_UP_PROVIDER); - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); - parameters.putBoolean(ProviderItem.DANGER_ON, danger_on); - if (provider.hasCertificatePin()){ - parameters.putString(Provider.CA_CERT_FINGERPRINT, provider.certificatePin()); - } - if (provider.hasCaCert()) { - parameters.putString(Provider.CA_CERT, provider.getCaCert()); - } - if (provider.hasDefinition()) { - parameters.putString(Provider.KEY, provider.getDefinition().toString()); - } - - providerAPICommand.setAction(ProviderAPI.SET_UP_PROVIDER); - providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); - - startService(providerAPICommand); - } - - /** - * Retrys setup of last used provider, allows bypassing ca certificate validation. - */ - @Override - public void retrySetUpProvider() { - cancelSettingUpProvider(); - if (!ProviderAPI.caCertDownloaded()) { - addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl(), ProviderAPI.lastDangerOn()); - } else { - showProgressBar(); - adapter.hideAllBut(adapter.indexOf(provider)); - - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - - providerAPICommand.setAction(ProviderAPI.SET_UP_PROVIDER); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); - providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); - - startService(providerAPICommand); - } - } - -} diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java new file mode 100644 index 00000000..034c9752 --- /dev/null +++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributors + * + * 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 . + */ +package se.leap.bitmaskclient; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentTransaction; + +import java.net.MalformedURLException; +import java.net.URL; + +import se.leap.bitmaskclient.ProviderListContent.ProviderItem; + +/** + * Activity that builds and shows the list of known available providers. + *

+ * It also allows the user to enter custom providers with a button. + * + * @author parmegv + * @author cyberta + */ +public class ProviderListActivity extends ProviderListBaseActivity { + + @Override + protected void onItemSelectedLogic() { + boolean danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, true); + setUpProvider(danger_on); + } + + @Override + public void cancelSettingUpProvider() { + super.cancelSettingUpProvider(); + preferences.edit().remove(ProviderItem.DANGER_ON).apply(); + } + + /** + * Open the new provider dialog with data + */ + public void addAndSelectNewProvider(String main_url, boolean danger_on) { + FragmentTransaction fragment_transaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); + + DialogFragment newFragment = new NewProviderDialog(); + Bundle data = new Bundle(); + data.putString(Provider.MAIN_URL, main_url); + data.putBoolean(ProviderItem.DANGER_ON, danger_on); + newFragment.setArguments(data); + newFragment.show(fragment_transaction, NewProviderDialog.TAG); + } + + public void showAndSelectProvider(String provider_main_url, boolean danger_on) { + try { + provider = new Provider(new URL((provider_main_url))); + adapter.add(provider); + adapter.saveProviders(); + autoSelectProvider(provider, danger_on); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + private void autoSelectProvider(Provider provider, boolean danger_on) { + preferences.edit().putBoolean(ProviderItem.DANGER_ON, danger_on).apply(); + this.provider = provider; + onItemSelectedLogic(); + showProgressBar(); + } + + /** + * Asks ProviderAPI to download a new provider.json file + * + * @param danger_on tells if HTTPS client should bypass certificate errors + */ + public void setUpProvider(boolean danger_on) { + mConfigState.setAction(SETTING_UP_PROVIDER); + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); + parameters.putBoolean(ProviderItem.DANGER_ON, danger_on); + if (provider.hasCertificatePin()){ + parameters.putString(Provider.CA_CERT_FINGERPRINT, provider.certificatePin()); + } + if (provider.hasCaCert()) { + parameters.putString(Provider.CA_CERT, provider.getCaCert()); + } + if (provider.hasDefinition()) { + parameters.putString(Provider.KEY, provider.getDefinition().toString()); + } + + providerAPICommand.setAction(ProviderAPI.SET_UP_PROVIDER); + providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); + + startService(providerAPICommand); + } + + /** + * Retrys setup of last used provider, allows bypassing ca certificate validation. + */ + @Override + public void retrySetUpProvider() { + cancelSettingUpProvider(); + if (!ProviderAPI.caCertDownloaded()) { + addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl(), ProviderAPI.lastDangerOn()); + } else { + showProgressBar(); + adapter.hideAllBut(adapter.indexOf(provider)); + + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + + providerAPICommand.setAction(ProviderAPI.SET_UP_PROVIDER); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); + providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); + + startService(providerAPICommand); + } + } + +} diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java index c8dfc092..88e31c9a 100644 --- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java +++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java @@ -20,7 +20,7 @@ import java.util.*; import java.net.*; /** - * Models the provider list shown in the ConfigurationWizard. + * Models the provider list shown in the ProviderListActivity. * * @author parmegv */ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c0ab2c75..2ffb54f4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -93,7 +93,7 @@ android:label="@string/title_activity_main" /> . - */ - -package se.leap.bitmaskclient; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.os.Handler; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.ListView; - -import com.pedrogomez.renderers.Renderer; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; - -import butterknife.InjectView; -import butterknife.OnItemClick; -import se.leap.bitmaskclient.fragments.AboutFragment; - -import static android.view.View.GONE; -import static se.leap.bitmaskclient.Constants.APP_ACTION_QUIT; -import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; -import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; -import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; -import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE; -import static se.leap.bitmaskclient.ProviderAPI.ERRORS; -import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_API_EVENT; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_OK; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_SET_UP; -import static se.leap.bitmaskclient.ProviderAPI.RESULT_CODE; -import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY; - -/** - * abstract base Activity that builds and shows the list of known available providers. - * The implementation of BaseConfigurationWizard differ in that they may or may not allow to bypass - * secure download mechanisms including certificate validation. - *

- * It also allows the user to enter custom providers with a button. - * - * @author parmegv - * @author cyberta - */ - -public abstract class BaseConfigurationWizard extends ConfigWizardBaseActivity - implements NewProviderDialog.NewProviderDialogInterface, DownloadFailedDialog.DownloadFailedDialogInterface, ProviderAPIResultReceiver.Receiver { - - @InjectView(R.id.provider_list) - protected ListView providerListView; - @Inject - protected ProviderListAdapter adapter; - - private ProviderManager providerManager; - protected Intent mConfigState = new Intent(PROVIDER_NOT_SET); - - final public static String TAG = ConfigurationWizard.class.getSimpleName(); - - final private static String ACTIVITY_STATE = "ACTIVITY STATE"; - - final protected static String PROVIDER_NOT_SET = "PROVIDER NOT SET"; - final protected static String SETTING_UP_PROVIDER = "PROVIDER GETS SET"; - final private static String SHOWING_PROVIDER_DETAILS = "SHOWING PROVIDER DETAILS"; - final private static String PENDING_SHOW_FAILED_DIALOG = "SHOW FAILED DIALOG"; - final private static String REASON_TO_FAIL = "REASON TO FAIL"; - final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; - - public ProviderAPIResultReceiver providerAPIResultReceiver; - private ProviderAPIBroadcastReceiver providerAPIBroadcastReceiver; - - FragmentManagerEnhanced fragmentManager; - - private boolean isActivityShowing; - private String reasonToFail; - - public abstract void retrySetUpProvider(); - - protected abstract void onItemSelectedLogic(); - - - private void initProviderList() { - List> prototypes = new ArrayList<>(); - prototypes.add(new ProviderRenderer(this)); - ProviderRendererBuilder providerRendererBuilder = new ProviderRendererBuilder(prototypes); - adapter = new ProviderListAdapter(getLayoutInflater(), providerRendererBuilder, providerManager); - providerListView.setAdapter(adapter); - } - - @Override - protected void onSaveInstanceState(@NotNull Bundle outState) { - outState.putString(ACTIVITY_STATE, mConfigState.getAction()); - outState.putParcelable(Provider.KEY, provider); - - DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag(DownloadFailedDialog.TAG); - if (dialogFragment != null) { - outState.putString(REASON_TO_FAIL, reasonToFail); - dialogFragment.dismiss(); - } - - super.onSaveInstanceState(outState); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - fragmentManager = new FragmentManagerEnhanced(getSupportFragmentManager()); - providerManager = ProviderManager.getInstance(getAssets(), getExternalFilesDir(null)); - - setUpInitialUI(); - - initProviderList(); - - if (savedInstanceState != null) - restoreState(savedInstanceState); - setUpProviderAPIResultReceiver(); - } - - private void restoreState(Bundle savedInstanceState) { - - provider = savedInstanceState.getParcelable(Provider.KEY); - mConfigState.setAction(savedInstanceState.getString(ACTIVITY_STATE, PROVIDER_NOT_SET)); - - reasonToFail = savedInstanceState.getString(REASON_TO_FAIL); - if(reasonToFail != null) { - showDownloadFailedDialog(); - } - - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction()) - ) { - showProgressBar(); - } - } - - @Override - protected void onResume() { - Log.d(TAG, "resuming with ConfigState: " + mConfigState.getAction()); - super.onResume(); - hideProgressBar(); - isActivityShowing = true; - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction())) { - showProgressBar(); - adapter.hideAllBut(adapter.indexOf(provider)); - checkProviderSetUp(); - } else if (PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { - showDownloadFailedDialog(); - } else if (SHOWING_PROVIDER_DETAILS.equals(mConfigState.getAction())) { - cancelAndShowAllProviders(); - } - } - - private void setUpInitialUI() { - setContentView(R.layout.configuration_wizard_activity); - setProviderHeaderText(R.string.setup_provider); - hideProgressBar(); - } - - @Override - protected void onPause() { - super.onPause(); - isActivityShowing = false; - } - - @Override - protected void onDestroy() { - super.onDestroy(); - if (providerAPIBroadcastReceiver != null) - unregisterReceiver(providerAPIBroadcastReceiver); - providerAPIResultReceiver = null; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) { - if (resultCode == RESULT_OK) { - setResult(resultCode, data); - finish(); - } - } - } - - private void setUpProviderAPIResultReceiver() { - providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), this); - providerAPIBroadcastReceiver = new ProviderAPIBroadcastReceiver(); - - IntentFilter updateIntentFilter = new IntentFilter(PROVIDER_API_EVENT); - updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); - registerReceiver(providerAPIBroadcastReceiver, updateIntentFilter); - } - - void handleProviderSetUp() { - try { - String providerJsonString = preferences.getString(Provider.KEY, ""); - if (!providerJsonString.isEmpty()) - provider.define(new JSONObject(providerJsonString)); - String caCert = preferences.getString(Provider.CA_CERT, ""); - provider.setCACert(caCert); - } catch (JSONException e) { - e.printStackTrace(); - } - - if (preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false)) { - mConfigState.putExtra(SERVICES_RETRIEVED, true); - - downloadVpnCertificate(); - } else { - showProviderDetails(); - } - } - - void handleProviderSetupFailed(Bundle resultData) { - mConfigState.setAction(PROVIDER_NOT_SET); - preferences.edit().remove(Provider.KEY).apply(); - - setResult(RESULT_CANCELED, mConfigState); - - reasonToFail = resultData.getString(ERRORS); - showDownloadFailedDialog(); - } - - void handleCorrectlyDownloadedCertificate() { - showProviderDetails(); - } - - void handleIncorrectlyDownloadedCertificate() { - mConfigState.setAction(PROVIDER_NOT_SET); - hideProgressBar(); - setResult(RESULT_CANCELED, mConfigState); - } - - @Override - public void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == ProviderAPI.PROVIDER_OK) { - handleProviderSetUp(); - } else if (resultCode == AboutFragment.VIEWED) { - // Do nothing, right now - // I need this for CW to wait for the About activity to end before going back to Dashboard. - } - } - - @OnItemClick(R.id.provider_list) - void onItemSelected(int position) { - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { - return; - } - - //TODO Code 2 pane view - mConfigState.setAction(SETTING_UP_PROVIDER); - provider = adapter.getItem(position); - showProgressBar(); - onItemSelectedLogic(); - } - - @Override - public void onBackPressed() { - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { - stopSettingUpProvider(); - } else { - askDashboardToQuitApp(); - super.onBackPressed(); - } - } - - private void stopSettingUpProvider() { - ProviderAPI.stop(); - loadingScreen.setVisibility(GONE); - - cancelSettingUpProvider(); - } - - @Override - public void cancelSettingUpProvider() { - hideProgressBar(); - mConfigState.setAction(PROVIDER_NOT_SET); - adapter.showAllProviders(); - preferences.edit().remove(Provider.KEY).remove(PROVIDER_ALLOW_ANONYMOUS).remove(PROVIDER_KEY).apply(); - } - - @Override - public void updateProviderDetails() { - mConfigState.setAction(SETTING_UP_PROVIDER); - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - - providerAPICommand.setAction(ProviderAPI.UPDATE_PROVIDER_DETAILS); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); - providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); - - startService(providerAPICommand); - } - - public void checkProviderSetUp() { - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - providerAPICommand.setAction(PROVIDER_SET_UP); - providerAPICommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver); - startService(providerAPICommand); - } - - private void askDashboardToQuitApp() { - Intent askQuit = new Intent(); - askQuit.putExtra(APP_ACTION_QUIT, APP_ACTION_QUIT); - setResult(RESULT_CANCELED, askQuit); - } - - /** - * Asks ProviderApiService to download an anonymous (anon) VPN certificate. - */ - private void downloadVpnCertificate() { - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - providerAPICommand.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); - startService(providerAPICommand); - } - - /** - * Open the new provider dialog - */ - public void addAndSelectNewProvider() { - FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); - new NewProviderDialog().show(fragmentTransaction, NewProviderDialog.TAG); - } - - /** - * Open the new provider dialog with data - */ - public void addAndSelectNewProvider(String main_url) { - FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); - - DialogFragment newFragment = new NewProviderDialog(); - Bundle data = new Bundle(); - data.putString(Provider.MAIN_URL, main_url); - newFragment.setArguments(data); - newFragment.show(fragmentTransaction, NewProviderDialog.TAG); - } - - /** - * Shows an error dialog, if configuring of a provider failed. - */ - public void showDownloadFailedDialog() { - try { - FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(DownloadFailedDialog.TAG); - DialogFragment newFragment; - try { - JSONObject errorJson = new JSONObject(reasonToFail); - newFragment = DownloadFailedDialog.newInstance(errorJson); - } catch (JSONException e) { - e.printStackTrace(); - newFragment = DownloadFailedDialog.newInstance(reasonToFail); - } - newFragment.show(fragmentTransaction, DownloadFailedDialog.TAG); - } catch (IllegalStateException e) { - e.printStackTrace(); - mConfigState.setAction(PENDING_SHOW_FAILED_DIALOG); - mConfigState.putExtra(REASON_TO_FAIL, reasonToFail); - } - - } - - /** - * Once selected a provider, this fragment offers the user to log in, - * use it anonymously (if possible) - * or cancel his/her election pressing the back button. - * - * - */ - public void showProviderDetails() { - // show only if current activity is shown - if (isActivityShowing && mConfigState.getAction() != null && - !mConfigState.getAction().equalsIgnoreCase(SHOWING_PROVIDER_DETAILS)) { - mConfigState.setAction(SHOWING_PROVIDER_DETAILS); - Intent intent = new Intent(this, ProviderDetailActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - intent.putExtra(PROVIDER_KEY, provider); - startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.about_leap: - startActivityForResult(new Intent(this, AboutFragment.class), 0); - return true; - case R.id.new_provider: - addAndSelectNewProvider(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - public void cancelAndShowAllProviders() { - mConfigState.setAction(PROVIDER_NOT_SET); - provider = null; - adapter.showAllProviders(); - } - - public class ProviderAPIBroadcastReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Log.d(TAG, "received Broadcast"); - - String action = intent.getAction(); - if (action == null || !action.equalsIgnoreCase(PROVIDER_API_EVENT)) { - return; - } - - if (mConfigState.getAction() != null && - mConfigState.getAction().equalsIgnoreCase(SETTING_UP_PROVIDER)) { - int resultCode = intent.getIntExtra(RESULT_CODE, -1); - Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); - - Bundle resultData = intent.getParcelableExtra(RESULT_KEY); - String handledProvider = resultData.getString(Provider.KEY); - - String providerName = ConfigHelper.getProviderName(handledProvider); - String providerDomain = ConfigHelper.getProviderDomain(handledProvider); - - if (providerName != null && providerName.equalsIgnoreCase(provider.getName()) && - providerDomain != null && - providerDomain.equalsIgnoreCase(provider.getDomain())) { - switch (resultCode) { - case PROVIDER_OK: - handleProviderSetUp(); - break; - case PROVIDER_NOK: - handleProviderSetupFailed(resultData); - break; - case CORRECTLY_DOWNLOADED_CERTIFICATE: - handleCorrectlyDownloadedCertificate(); - break; - case INCORRECTLY_DOWNLOADED_CERTIFICATE: - handleIncorrectlyDownloadedCertificate(); - break; - } - } - } - } - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java index f93fb36c..3713e198 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java @@ -285,12 +285,12 @@ public class ConfigHelper { return getProviderName(null, provider); } - public static String getProviderName(SharedPreferences preferences) { + public static String getProviderName(@Nullable SharedPreferences preferences) { return getProviderName(preferences,null); } - public static String getProviderName(SharedPreferences preferences, @Nullable String provider) { - if (provider == null) { + public static String getProviderName(@Nullable SharedPreferences preferences, @Nullable String provider) { + if (provider == null && preferences != null) { provider = preferences.getString(Provider.KEY, ""); } try { @@ -315,8 +315,8 @@ public class ConfigHelper { return getProviderDomain(null, provider); } - public static String getProviderDomain(SharedPreferences preferences, @Nullable String provider) { - if (provider == null) { + public static String getProviderDomain(@Nullable SharedPreferences preferences, @Nullable String provider) { + if (provider == null && preferences != null) { provider = preferences.getString(Provider.KEY, ""); } try { diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 5ccb48b5..cb781009 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -232,7 +232,7 @@ public class Dashboard extends ButterKnifeActivity { private void handleConfigureAlwaysOn(Intent intent) { intent.removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); Log.d(TAG, "start Configuration wizard!"); - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } private void prepareEIP(Bundle savedInstanceState) { @@ -255,7 +255,7 @@ public class Dashboard extends ButterKnifeActivity { if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) { getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); } - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } @SuppressLint("CommitPrefEdits") private void providerToPreferences(Provider provider) { @@ -273,7 +273,7 @@ public class Dashboard extends ButterKnifeActivity { .setPositiveButton(getResources().getString(R.string.setup_error_configure_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - startActivityForResult(new Intent(Dashboard.this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(Dashboard.this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } }) .setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { @@ -416,7 +416,7 @@ public class Dashboard extends ButterKnifeActivity { clearDataOfLastProvider(); switching_provider = false; - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); } private void clearDataOfLastProvider() { @@ -441,7 +441,7 @@ public class Dashboard extends ButterKnifeActivity { preferenceEditor.apply(); switching_provider = false; - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); } private static class DashboardReceiver implements ProviderAPIResultReceiver.Receiver{ diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java new file mode 100644 index 00000000..f60b5cc7 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java @@ -0,0 +1,478 @@ +/** + * Copyright (c) 2017 LEAP Encryption Access Project and contributors + * + * 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 . + */ + +package se.leap.bitmaskclient; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentTransaction; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ListView; + +import com.pedrogomez.renderers.Renderer; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import butterknife.InjectView; +import butterknife.OnItemClick; +import se.leap.bitmaskclient.fragments.AboutFragment; + +import static android.view.View.GONE; +import static se.leap.bitmaskclient.Constants.APP_ACTION_QUIT; +import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; +import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; +import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; +import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE; +import static se.leap.bitmaskclient.ProviderAPI.ERRORS; +import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_API_EVENT; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_OK; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_SET_UP; +import static se.leap.bitmaskclient.ProviderAPI.RESULT_CODE; +import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY; + +/** + * abstract base Activity that builds and shows the list of known available providers. + * The implementation of ProviderListBaseActivity differ in that they may or may not allow to bypass + * secure download mechanisms including certificate validation. + *

+ * It also allows the user to enter custom providers with a button. + * + * @author parmegv + * @author cyberta + */ + +public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity + implements NewProviderDialog.NewProviderDialogInterface, DownloadFailedDialog.DownloadFailedDialogInterface, ProviderAPIResultReceiver.Receiver { + + @InjectView(R.id.provider_list) + protected ListView providerListView; + @Inject + protected ProviderListAdapter adapter; + + private ProviderManager providerManager; + protected Intent mConfigState = new Intent(PROVIDER_NOT_SET); + + final public static String TAG = ProviderListActivity.class.getSimpleName(); + + final private static String ACTIVITY_STATE = "ACTIVITY STATE"; + + final protected static String PROVIDER_NOT_SET = "PROVIDER NOT SET"; + final protected static String SETTING_UP_PROVIDER = "PROVIDER GETS SET"; + final private static String SHOWING_PROVIDER_DETAILS = "SHOWING PROVIDER DETAILS"; + final private static String PENDING_SHOW_FAILED_DIALOG = "SHOW FAILED DIALOG"; + final private static String REASON_TO_FAIL = "REASON TO FAIL"; + final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; + + public ProviderAPIResultReceiver providerAPIResultReceiver; + private ProviderAPIBroadcastReceiver providerAPIBroadcastReceiver; + + FragmentManagerEnhanced fragmentManager; + + private boolean isActivityShowing; + private String reasonToFail; + + public abstract void retrySetUpProvider(); + + protected abstract void onItemSelectedLogic(); + + + private void initProviderList() { + List> prototypes = new ArrayList<>(); + prototypes.add(new ProviderRenderer(this)); + ProviderRendererBuilder providerRendererBuilder = new ProviderRendererBuilder(prototypes); + adapter = new ProviderListAdapter(getLayoutInflater(), providerRendererBuilder, providerManager); + providerListView.setAdapter(adapter); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + outState.putString(ACTIVITY_STATE, mConfigState.getAction()); + outState.putParcelable(Provider.KEY, provider); + + DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag(DownloadFailedDialog.TAG); + if (dialogFragment != null) { + outState.putString(REASON_TO_FAIL, reasonToFail); + dialogFragment.dismiss(); + } + + super.onSaveInstanceState(outState); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + fragmentManager = new FragmentManagerEnhanced(getSupportFragmentManager()); + providerManager = ProviderManager.getInstance(getAssets(), getExternalFilesDir(null)); + + setUpInitialUI(); + + initProviderList(); + + if (savedInstanceState != null) + restoreState(savedInstanceState); + setUpProviderAPIResultReceiver(); + } + + private void restoreState(Bundle savedInstanceState) { + + provider = savedInstanceState.getParcelable(Provider.KEY); + mConfigState.setAction(savedInstanceState.getString(ACTIVITY_STATE, PROVIDER_NOT_SET)); + + reasonToFail = savedInstanceState.getString(REASON_TO_FAIL); + if(reasonToFail != null) { + showDownloadFailedDialog(); + } + + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || + PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction()) + ) { + showProgressBar(); + } + } + + @Override + protected void onResume() { + Log.d(TAG, "resuming with ConfigState: " + mConfigState.getAction()); + super.onResume(); + hideProgressBar(); + isActivityShowing = true; + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction())) { + showProgressBar(); + adapter.hideAllBut(adapter.indexOf(provider)); + checkProviderSetUp(); + } else if (PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + showDownloadFailedDialog(); + } else if (SHOWING_PROVIDER_DETAILS.equals(mConfigState.getAction())) { + cancelAndShowAllProviders(); + } + } + + private void setUpInitialUI() { + setContentView(R.layout.configuration_wizard_activity); + setProviderHeaderText(R.string.setup_provider); + hideProgressBar(); + } + + @Override + protected void onPause() { + super.onPause(); + isActivityShowing = false; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (providerAPIBroadcastReceiver != null) + unregisterReceiver(providerAPIBroadcastReceiver); + providerAPIResultReceiver = null; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) { + if (resultCode == RESULT_OK) { + setResult(resultCode, data); + finish(); + } + } + } + + private void setUpProviderAPIResultReceiver() { + providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), this); + providerAPIBroadcastReceiver = new ProviderAPIBroadcastReceiver(); + + IntentFilter updateIntentFilter = new IntentFilter(PROVIDER_API_EVENT); + updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); + registerReceiver(providerAPIBroadcastReceiver, updateIntentFilter); + } + + void handleProviderSetUp() { + try { + String providerJsonString = preferences.getString(Provider.KEY, ""); + if (!providerJsonString.isEmpty()) + provider.define(new JSONObject(providerJsonString)); + String caCert = preferences.getString(Provider.CA_CERT, ""); + provider.setCACert(caCert); + } catch (JSONException e) { + e.printStackTrace(); + } + + if (preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false)) { + mConfigState.putExtra(SERVICES_RETRIEVED, true); + + downloadVpnCertificate(); + } else { + showProviderDetails(); + } + } + + void handleProviderSetupFailed(Bundle resultData) { + mConfigState.setAction(PROVIDER_NOT_SET); + preferences.edit().remove(Provider.KEY).apply(); + + setResult(RESULT_CANCELED, mConfigState); + + reasonToFail = resultData.getString(ERRORS); + showDownloadFailedDialog(); + } + + void handleCorrectlyDownloadedCertificate() { + showProviderDetails(); + } + + void handleIncorrectlyDownloadedCertificate() { + mConfigState.setAction(PROVIDER_NOT_SET); + hideProgressBar(); + setResult(RESULT_CANCELED, mConfigState); + } + + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + if (resultCode == ProviderAPI.PROVIDER_OK) { + handleProviderSetUp(); + } else if (resultCode == AboutFragment.VIEWED) { + // Do nothing, right now + // I need this for CW to wait for the About activity to end before going back to Dashboard. + } + } + + @OnItemClick(R.id.provider_list) + void onItemSelected(int position) { + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || + PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + return; + } + + //TODO Code 2 pane view + mConfigState.setAction(SETTING_UP_PROVIDER); + provider = adapter.getItem(position); + showProgressBar(); + onItemSelectedLogic(); + } + + @Override + public void onBackPressed() { + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || + PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + stopSettingUpProvider(); + } else { + askDashboardToQuitApp(); + super.onBackPressed(); + } + } + + private void stopSettingUpProvider() { + ProviderAPI.stop(); + loadingScreen.setVisibility(GONE); + + cancelSettingUpProvider(); + } + + @Override + public void cancelSettingUpProvider() { + hideProgressBar(); + mConfigState.setAction(PROVIDER_NOT_SET); + adapter.showAllProviders(); + preferences.edit().remove(Provider.KEY).remove(PROVIDER_ALLOW_ANONYMOUS).remove(PROVIDER_KEY).apply(); + } + + @Override + public void updateProviderDetails() { + mConfigState.setAction(SETTING_UP_PROVIDER); + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + + providerAPICommand.setAction(ProviderAPI.UPDATE_PROVIDER_DETAILS); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); + providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); + + startService(providerAPICommand); + } + + public void checkProviderSetUp() { + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + providerAPICommand.setAction(PROVIDER_SET_UP); + providerAPICommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver); + startService(providerAPICommand); + } + + private void askDashboardToQuitApp() { + Intent askQuit = new Intent(); + askQuit.putExtra(APP_ACTION_QUIT, APP_ACTION_QUIT); + setResult(RESULT_CANCELED, askQuit); + } + + /** + * Asks ProviderApiService to download an anonymous (anon) VPN certificate. + */ + private void downloadVpnCertificate() { + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + providerAPICommand.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); + startService(providerAPICommand); + } + + /** + * Open the new provider dialog + */ + public void addAndSelectNewProvider() { + FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); + new NewProviderDialog().show(fragmentTransaction, NewProviderDialog.TAG); + } + + /** + * Open the new provider dialog with data + */ + public void addAndSelectNewProvider(String main_url) { + FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); + + DialogFragment newFragment = new NewProviderDialog(); + Bundle data = new Bundle(); + data.putString(Provider.MAIN_URL, main_url); + newFragment.setArguments(data); + newFragment.show(fragmentTransaction, NewProviderDialog.TAG); + } + + /** + * Shows an error dialog, if configuring of a provider failed. + */ + public void showDownloadFailedDialog() { + try { + FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(DownloadFailedDialog.TAG); + DialogFragment newFragment; + try { + JSONObject errorJson = new JSONObject(reasonToFail); + newFragment = DownloadFailedDialog.newInstance(errorJson); + } catch (JSONException e) { + e.printStackTrace(); + newFragment = DownloadFailedDialog.newInstance(reasonToFail); + } + newFragment.show(fragmentTransaction, DownloadFailedDialog.TAG); + } catch (IllegalStateException e) { + e.printStackTrace(); + mConfigState.setAction(PENDING_SHOW_FAILED_DIALOG); + mConfigState.putExtra(REASON_TO_FAIL, reasonToFail); + } + + } + + /** + * Once selected a provider, this fragment offers the user to log in, + * use it anonymously (if possible) + * or cancel his/her election pressing the back button. + * + * + */ + public void showProviderDetails() { + // show only if current activity is shown + if (isActivityShowing && mConfigState.getAction() != null && + !mConfigState.getAction().equalsIgnoreCase(SHOWING_PROVIDER_DETAILS)) { + mConfigState.setAction(SHOWING_PROVIDER_DETAILS); + Intent intent = new Intent(this, ProviderDetailActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent.putExtra(PROVIDER_KEY, provider); + startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.about_leap: + startActivityForResult(new Intent(this, AboutFragment.class), 0); + return true; + case R.id.new_provider: + addAndSelectNewProvider(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public void cancelAndShowAllProviders() { + mConfigState.setAction(PROVIDER_NOT_SET); + provider = null; + adapter.showAllProviders(); + } + + public class ProviderAPIBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "received Broadcast"); + + String action = intent.getAction(); + if (action == null || !action.equalsIgnoreCase(PROVIDER_API_EVENT)) { + return; + } + + if (mConfigState.getAction() != null && + mConfigState.getAction().equalsIgnoreCase(SETTING_UP_PROVIDER)) { + int resultCode = intent.getIntExtra(RESULT_CODE, -1); + Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); + + Bundle resultData = intent.getParcelableExtra(RESULT_KEY); + String handledProvider = resultData.getString(Provider.KEY); + + String providerName = ConfigHelper.getProviderName(handledProvider); + String providerDomain = ConfigHelper.getProviderDomain(handledProvider); + + if (providerName != null && providerName.equalsIgnoreCase(provider.getName()) && + providerDomain != null && + providerDomain.equalsIgnoreCase(provider.getDomain())) { + switch (resultCode) { + case PROVIDER_OK: + handleProviderSetUp(); + break; + case PROVIDER_NOK: + handleProviderSetupFailed(resultData); + break; + } + } else { + switch (resultCode) { + case CORRECTLY_DOWNLOADED_CERTIFICATE: + handleCorrectlyDownloadedCertificate(); + break; + case INCORRECTLY_DOWNLOADED_CERTIFICATE: + handleIncorrectlyDownloadedCertificate(); + break; + } + } + } + } + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java index 61e65f2d..f5991538 100644 --- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java @@ -17,7 +17,6 @@ import se.leap.bitmaskclient.userstatus.User; import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE; import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION; -import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; @@ -56,7 +55,7 @@ public class StartActivity extends Activity { case FIRST: storeAppVersion(); // TODO start ProfileCreation & replace below code - // (new Intent(getActivity(), ConfigurationWizard.class), Constants.REQUEST_CODE_SWITCH_PROVIDER); + // (new Intent(getActivity(), ProviderListActivity.class), Constants.REQUEST_CODE_SWITCH_PROVIDER); break; case UPGRADE: @@ -165,7 +164,7 @@ public class StartActivity extends Activity { if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) { getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); } - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } @Override 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 aae1e1ea..ebfb3ba7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -27,7 +27,7 @@ import android.widget.ListView; import android.widget.Toast; import se.leap.bitmaskclient.ConfigHelper; -import se.leap.bitmaskclient.ConfigurationWizard; +import se.leap.bitmaskclient.ProviderListActivity; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.VpnFragment; import se.leap.bitmaskclient.fragments.AboutFragment; @@ -304,7 +304,7 @@ public class NavigationDrawerFragment extends Fragment { // TODO STOP VPN // if (provider.hasEIP()) eip_fragment.stopEipIfPossible(); preferences.edit().clear().apply(); - startActivityForResult(new Intent(getActivity(), ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER); + startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); break; case 1: mTitle = getString(R.string.log_fragment_title); diff --git a/app/src/main/res/layout-xlarge/configuration_wizard_activity.xml b/app/src/main/res/layout-xlarge/configuration_wizard_activity.xml index f82377cb..581b0c9a 100644 --- a/app/src/main/res/layout-xlarge/configuration_wizard_activity.xml +++ b/app/src/main/res/layout-xlarge/configuration_wizard_activity.xml @@ -3,7 +3,7 @@ android:id="@+id/configuration_wizard_layout" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ConfigurationWizard" + tools:context=".ProviderListActivity" style="@style/BitmaskActivity" > diff --git a/app/src/production/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/production/java/se/leap/bitmaskclient/ConfigurationWizard.java deleted file mode 100644 index 53bc8f0b..00000000 --- a/app/src/production/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ /dev/null @@ -1,104 +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 . - */ -package se.leap.bitmaskclient; - -import android.content.Intent; -import android.os.Bundle; - -import java.net.MalformedURLException; -import java.net.URL; - -/** - * Activity that builds and shows the list of known available providers. - *

- * It also allows the user to enter custom providers with a button. - * - * @author parmegv - * @author cyberta - */ -public class ConfigurationWizard extends BaseConfigurationWizard { - - - @Override - protected void onItemSelectedLogic() { - setUpProvider(); - } - - public void showAndSelectProvider(String provider_main_url) { - try { - provider = new Provider(new URL((provider_main_url))); - adapter.add(provider); - adapter.saveProviders(); - autoSelectProvider(provider); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } - - private void autoSelectProvider(Provider provider) { - this.provider = provider; - onItemSelectedLogic(); - showProgressBar(); - } - - /** - * Asks ProviderAPI to download a new provider.json file - * - */ - public void setUpProvider() { - mConfigState.setAction(SETTING_UP_PROVIDER); - Intent providerApiCommand = new Intent(this, ProviderAPI.class); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); - if (provider.hasCertificatePin()){ - parameters.putString(Provider.CA_CERT_FINGERPRINT, provider.certificatePin()); - } - if (provider.hasCaCert()) { - parameters.putString(Provider.CA_CERT, provider.getCaCert()); - } - if (provider.hasDefinition()) { - parameters.putString(Provider.KEY, provider.getDefinition().toString()); - } - - providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER); - providerApiCommand.putExtra(ProviderAPI.PARAMETERS, parameters); - - startService(providerApiCommand); - } - - @Override - public void retrySetUpProvider() { - cancelSettingUpProvider(); - if (!ProviderAPI.caCertDownloaded()) { - addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl()); - } else { - showProgressBar(); - adapter.hideAllBut(adapter.indexOf(provider)); - - - Intent providerApiCommand = new Intent(this, ProviderAPI.class); - providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER); - providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); - providerApiCommand.putExtra(ProviderAPI.PARAMETERS, parameters); - - startService(providerApiCommand); - } - } - -} diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java b/app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java new file mode 100644 index 00000000..8c008024 --- /dev/null +++ b/app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java @@ -0,0 +1,104 @@ +/** + * 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 . + */ +package se.leap.bitmaskclient; + +import android.content.Intent; +import android.os.Bundle; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Activity that builds and shows the list of known available providers. + *

+ * It also allows the user to enter custom providers with a button. + * + * @author parmegv + * @author cyberta + */ +public class ProviderListActivity extends ProviderListBaseActivity { + + + @Override + protected void onItemSelectedLogic() { + setUpProvider(); + } + + public void showAndSelectProvider(String provider_main_url) { + try { + provider = new Provider(new URL((provider_main_url))); + adapter.add(provider); + adapter.saveProviders(); + autoSelectProvider(provider); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + private void autoSelectProvider(Provider provider) { + this.provider = provider; + onItemSelectedLogic(); + showProgressBar(); + } + + /** + * Asks ProviderAPI to download a new provider.json file + * + */ + public void setUpProvider() { + mConfigState.setAction(SETTING_UP_PROVIDER); + Intent providerApiCommand = new Intent(this, ProviderAPI.class); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); + if (provider.hasCertificatePin()){ + parameters.putString(Provider.CA_CERT_FINGERPRINT, provider.certificatePin()); + } + if (provider.hasCaCert()) { + parameters.putString(Provider.CA_CERT, provider.getCaCert()); + } + if (provider.hasDefinition()) { + parameters.putString(Provider.KEY, provider.getDefinition().toString()); + } + + providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER); + providerApiCommand.putExtra(ProviderAPI.PARAMETERS, parameters); + + startService(providerApiCommand); + } + + @Override + public void retrySetUpProvider() { + cancelSettingUpProvider(); + if (!ProviderAPI.caCertDownloaded()) { + addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl()); + } else { + showProgressBar(); + adapter.hideAllBut(adapter.indexOf(provider)); + + + Intent providerApiCommand = new Intent(this, ProviderAPI.class); + providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER); + providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); + providerApiCommand.putExtra(ProviderAPI.PARAMETERS, parameters); + + startService(providerApiCommand); + } + } + +} diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java b/app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java index 6466e769..d9e1d1a9 100644 --- a/app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java +++ b/app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java @@ -20,7 +20,7 @@ import java.util.*; import java.net.*; /** - * Models the provider list shown in the ConfigurationWizard. + * Models the provider list shown in the ProviderListActivity. * * @author parmegv */ -- cgit v1.2.3