diff options
Diffstat (limited to 'app/src/main')
-rw-r--r-- | app/src/main/AndroidManifest.xml | 4 | ||||
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/Constants.java | 1 | ||||
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java | 117 | ||||
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/ProviderSetupFailedDialog.java | 16 | ||||
-rw-r--r-- | app/src/main/res/layout/a_add_provider.xml | 74 | ||||
-rw-r--r-- | app/src/main/res/layout/v_add_provider.xml | 41 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 1 |
7 files changed, 203 insertions, 51 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8b87d095..b1131850 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -94,6 +94,10 @@ android:label="@string/configuration_wizard_title" /> <activity + android:name=".AddProviderActivity" + android:label="@string/add_provider" /> + + <activity android:name=".ProviderDetailActivity" android:label="@string/provider_details_title" android:launchMode="singleTop" /> diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java index 8ec3fcc7..2efc2c1f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java @@ -21,6 +21,7 @@ public interface Constants { int REQUEST_CODE_CONFIGURE_LEAP = 0; int REQUEST_CODE_SWITCH_PROVIDER = 1; int REQUEST_CODE_LOG_IN = 2; + int REQUEST_CODE_ADD_PROVIDER = 3; ////////////////////////////////////////////// diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java index 6a0a1864..0e1ecae9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java @@ -1,16 +1,16 @@ /** * Copyright (c) 2017 LEAP Encryption Access Project and contributors - * + * <p> * 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. - * + * <p> * 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. - * + * <p> * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -33,10 +33,11 @@ import android.widget.ListView; import com.pedrogomez.renderers.Renderer; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.json.JSONException; import org.json.JSONObject; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -50,6 +51,7 @@ import static se.leap.bitmaskclient.Constants.BROADCAST_PROVIDER_API_EVENT; import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE; import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; +import static se.leap.bitmaskclient.Constants.REQUEST_CODE_ADD_PROVIDER; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_VPN_CERTIFICATE; import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_VPN_CERTIFICATE; @@ -72,7 +74,7 @@ import static se.leap.bitmaskclient.ProviderAPI.UPDATE_PROVIDER_DETAILS; */ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity - implements NewProviderDialog.NewProviderDialogInterface, ProviderSetupFailedDialog.DownloadFailedDialogInterface, ProviderAPIResultReceiver.Receiver { + implements ProviderSetupFailedDialog.DownloadFailedDialogInterface, ProviderAPIResultReceiver.Receiver { @InjectView(R.id.provider_list) protected ListView providerListView; @@ -80,7 +82,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity protected ProviderListAdapter adapter; private ProviderManager providerManager; - protected Intent mConfigState = new Intent(PROVIDER_NOT_SET); + protected Intent configState = new Intent(PROVIDER_NOT_SET); final public static String TAG = ProviderListActivity.class.getSimpleName(); @@ -88,25 +90,26 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity 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 SHOWING_PROVIDER_DETAILS = "SHOWING PROVIDER DETAILS"; final private static String PENDING_SHOW_FAILED_DIALOG = "SHOW FAILED DIALOG PENDING"; final private static String SHOW_FAILED_DIALOG = "SHOW FAILED DIALOG"; final private static String REASON_TO_FAIL = "REASON TO FAIL"; final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; + final protected static String EXTRAS_KEY_INVALID_URL = "INVALID_URL"; public ProviderAPIResultReceiver providerAPIResultReceiver; private ProviderAPIBroadcastReceiver providerAPIBroadcastReceiver; - FragmentManagerEnhanced fragmentManager; + private FragmentManagerEnhanced fragmentManager; private boolean isActivityShowing; private String reasonToFail; + private boolean testNewURL; public abstract void retrySetUpProvider(@NonNull Provider provider); protected abstract void onItemSelectedLogic(); - private void initProviderList() { List<Renderer<Provider>> prototypes = new ArrayList<>(); prototypes.add(new ProviderRenderer(this)); @@ -117,7 +120,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity @Override public void onSaveInstanceState(@NotNull Bundle outState) { - outState.putString(ACTIVITY_STATE, mConfigState.getAction()); + outState.putString(ACTIVITY_STATE, configState.getAction()); outState.putString(REASON_TO_FAIL, reasonToFail); super.onSaveInstanceState(outState); @@ -128,7 +131,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity if (savedInstanceState == null) { return; } - mConfigState.setAction(savedInstanceState.getString(ACTIVITY_STATE, PROVIDER_NOT_SET)); + configState.setAction(savedInstanceState.getString(ACTIVITY_STATE, PROVIDER_NOT_SET)); if (savedInstanceState.containsKey(REASON_TO_FAIL)) { reasonToFail = savedInstanceState.getString(REASON_TO_FAIL); } @@ -147,19 +150,19 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity @Override protected void onResume() { - Log.d(TAG, "resuming with ConfigState: " + mConfigState.getAction()); + Log.d(TAG, "resuming with ConfigState: " + configState.getAction()); super.onResume(); setUpProviderAPIResultReceiver(); isActivityShowing = true; - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction())) { + if (SETTING_UP_PROVIDER.equals(configState.getAction())) { showProgressBar(); checkProviderSetUp(); - } else if (PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + } else if (PENDING_SHOW_FAILED_DIALOG.equals(configState.getAction())) { showProgressBar(); showDownloadFailedDialog(); - } else if (SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + } else if (SHOW_FAILED_DIALOG.equals(configState.getAction())) { showProgressBar(); - } else if (SHOWING_PROVIDER_DETAILS.equals(mConfigState.getAction())) { + } else if (SHOWING_PROVIDER_DETAILS.equals(configState.getAction())) { cancelSettingUpProvider(); } } @@ -191,9 +194,31 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity setResult(resultCode, data); finish(); } + } else if (requestCode == REQUEST_CODE_ADD_PROVIDER) { + if (resultCode == RESULT_OK) { + testNewURL = true; + String newUrl = data.getStringExtra(AddProviderActivity.EXTRAS_KEY_NEW_URL); + this.provider.setMainUrl(newUrl); + showAndSelectProvider(newUrl); + } + } + } + + public void showAndSelectProvider(String newURL) { + try { + provider = new Provider(new URL((newURL))); + autoSelectProvider(); + } catch (MalformedURLException e) { + e.printStackTrace(); } } + private void autoSelectProvider() { + onItemSelectedLogic(); + showProgressBar(); + } + + private void setUpProviderAPIResultReceiver() { providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), this); providerAPIBroadcastReceiver = new ProviderAPIBroadcastReceiver(); @@ -208,7 +233,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity adapter.add(provider); adapter.saveProviders(); if (provider.allowsAnonymous()) { - mConfigState.putExtra(SERVICES_RETRIEVED, true); + configState.putExtra(SERVICES_RETRIEVED, true); downloadVpnCertificate(); } else { showProviderDetails(); @@ -216,6 +241,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity } void handleProviderSetupFailed(Bundle resultData) { + reasonToFail = resultData.getString(ERRORS); showDownloadFailedDialog(); } @@ -227,7 +253,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity void handleIncorrectlyDownloadedCertificate() { cancelSettingUpProvider(); - setResult(RESULT_CANCELED, mConfigState); + setResult(RESULT_CANCELED, configState); } @Override @@ -243,8 +269,8 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity @OnItemClick(R.id.provider_list) void onItemSelected(int position) { - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + if (SETTING_UP_PROVIDER.equals(configState.getAction()) || + SHOW_FAILED_DIALOG.equals(configState.getAction())) { return; } @@ -252,7 +278,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity provider = adapter.getItem(position); if (provider != null && !provider.isDefault()) { //TODO Code 2 pane view - mConfigState.setAction(SETTING_UP_PROVIDER); + configState.setAction(SETTING_UP_PROVIDER); showProgressBar(); onItemSelectedLogic(); } else { @@ -262,8 +288,8 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity @Override public void onBackPressed() { - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + if (SETTING_UP_PROVIDER.equals(configState.getAction()) || + SHOW_FAILED_DIALOG.equals(configState.getAction())) { stopSettingUpProvider(); } else { super.onBackPressed(); @@ -276,14 +302,14 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity @Override public void cancelSettingUpProvider() { - mConfigState.setAction(PROVIDER_NOT_SET); + configState.setAction(PROVIDER_NOT_SET); provider = null; hideProgressBar(); } @Override public void updateProviderDetails() { - mConfigState.setAction(SETTING_UP_PROVIDER); + configState.setAction(SETTING_UP_PROVIDER); ProviderAPICommand.execute(this, UPDATE_PROVIDER_DETAILS, provider); } @@ -298,28 +324,24 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity ProviderAPICommand.execute(this, DOWNLOAD_VPN_CERTIFICATE, provider); } + /** * Open the new provider dialog */ public void addAndSelectNewProvider() { - addAndSelectNewProvider(null); + Intent intent = new Intent(this, AddProviderActivity.class); + startActivityForResult(intent, REQUEST_CODE_ADD_PROVIDER); } /** * Open the new provider dialog - * @param mainUrl - the main url of the provider to add - if null add a new provider */ - public void addAndSelectNewProvider(@Nullable String mainUrl) { - FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); - - DialogFragment newFragment = new NewProviderDialog(); - - if (mainUrl != null) { - Bundle data = new Bundle(); - data.putString(Provider.MAIN_URL, mainUrl); - newFragment.setArguments(data); - } - newFragment.show(fragmentTransaction, NewProviderDialog.TAG); + @Override + public void addAndSelectNewProvider(String url) { + testNewURL = false; + Intent intent = new Intent(this, AddProviderActivity.class); + intent.putExtra(EXTRAS_KEY_INVALID_URL, url); + startActivityForResult(intent, REQUEST_CODE_ADD_PROVIDER); } /** @@ -327,12 +349,12 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity */ public void showDownloadFailedDialog() { try { - mConfigState.setAction(SHOW_FAILED_DIALOG); + configState.setAction(SHOW_FAILED_DIALOG); FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(ProviderSetupFailedDialog.TAG); DialogFragment newFragment; try { JSONObject errorJson = new JSONObject(reasonToFail); - newFragment = ProviderSetupFailedDialog.newInstance(provider, errorJson); + newFragment = ProviderSetupFailedDialog.newInstance(provider, errorJson, testNewURL); } catch (JSONException e) { e.printStackTrace(); newFragment = ProviderSetupFailedDialog.newInstance(provider, reasonToFail); @@ -343,23 +365,20 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity newFragment.show(fragmentTransaction, ProviderSetupFailedDialog.TAG); } catch (IllegalStateException e) { e.printStackTrace(); - mConfigState.setAction(PENDING_SHOW_FAILED_DIALOG); + configState.setAction(PENDING_SHOW_FAILED_DIALOG); } - } /** * 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); + if (isActivityShowing && configState.getAction() != null && + !configState.getAction().equalsIgnoreCase(SHOWING_PROVIDER_DETAILS)) { + configState.setAction(SHOWING_PROVIDER_DETAILS); Intent intent = new Intent(this, ProviderDetailActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); intent.putExtra(PROVIDER_KEY, provider); @@ -377,8 +396,8 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity return; } - if (mConfigState.getAction() != null && - mConfigState.getAction().equalsIgnoreCase(SETTING_UP_PROVIDER)) { + if (configState.getAction() != null && + configState.getAction().equalsIgnoreCase(SETTING_UP_PROVIDER)) { int resultCode = intent.getIntExtra(BROADCAST_RESULT_CODE, RESULT_CANCELED); Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderSetupFailedDialog.java b/app/src/main/java/se/leap/bitmaskclient/ProviderSetupFailedDialog.java index 5bd9575e..3cfae776 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderSetupFailedDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderSetupFailedDialog.java @@ -52,7 +52,8 @@ public class ProviderSetupFailedDialog extends DialogFragment { DEFAULT, ERROR_CORRUPTED_PROVIDER_JSON, ERROR_INVALID_CERTIFICATE, - ERROR_CERTIFICATE_PINNING + ERROR_CERTIFICATE_PINNING, + ERROR_NEW_URL_NO_VPN_PROVIDER } /** @@ -68,7 +69,7 @@ public class ProviderSetupFailedDialog extends DialogFragment { /** * @return a new instance of this DialogFragment. */ - public static DialogFragment newInstance(Provider provider, JSONObject errorJson) { + public static DialogFragment newInstance(Provider provider, JSONObject errorJson, boolean testNewURL) { ProviderSetupFailedDialog dialogFragment = new ProviderSetupFailedDialog(); dialogFragment.provider = provider; try { @@ -81,6 +82,8 @@ public class ProviderSetupFailedDialog extends DialogFragment { if (errorJson.has(ERRORID)) { dialogFragment.downloadError = valueOf(errorJson.getString(ERRORID)); + } else if (testNewURL) { + dialogFragment.downloadError = DOWNLOAD_ERRORS.ERROR_NEW_URL_NO_VPN_PROVIDER; } } catch (Exception e) { e.printStackTrace(); @@ -123,6 +126,13 @@ public class ProviderSetupFailedDialog extends DialogFragment { } }); break; + case ERROR_NEW_URL_NO_VPN_PROVIDER: + builder.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + interfaceWithConfigurationWizard.addAndSelectNewProvider(provider.getMainUrlString()); + } + }); + break; default: builder.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { @@ -142,6 +152,8 @@ public class ProviderSetupFailedDialog extends DialogFragment { void cancelSettingUpProvider(); void updateProviderDetails(); + + void addAndSelectNewProvider(String url); } DownloadFailedDialogInterface interfaceWithConfigurationWizard; diff --git a/app/src/main/res/layout/a_add_provider.xml b/app/src/main/res/layout/a_add_provider.xml new file mode 100644 index 00000000..fd515bf3 --- /dev/null +++ b/app/src/main/res/layout/a_add_provider.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + style="@style/BitmaskActivity" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="@dimen/stdpadding" + tools:context=".AddProviderActivity"> + + <!--Contains header information!??? --> + <include layout="@layout/v_add_provider" /> + + <LinearLayout + android:id="@+id/content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentEnd="true" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:orientation="vertical"> + + <!-- the header contains the mask--> + <include layout="@layout/v_provider_header" /> + + <android.support.design.widget.TextInputLayout + android:id="@+id/text_uri_error" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/activity_vertical_margin" + android:hint="@string/new_provider_uri" + app:errorEnabled="true"> + + <android.support.design.widget.TextInputEditText + android:id="@+id/text_uri" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ems="10" + android:inputType="text" /> + + </android.support.design.widget.TextInputLayout> + + + <CheckBox + android:id="@+id/danger_checkbox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" + android:layout_marginBottom="@dimen/add_button_margin"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="right" + android:orientation="horizontal"> + + <Button + android:id="@+id/button_cancel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/cancel" /> + + <Button + android:id="@+id/button_save" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/activity_horizontal_margin" + android:layout_marginStart="@dimen/activity_horizontal_margin" + android:text="@string/save" /> + + </LinearLayout> + </LinearLayout> + +</RelativeLayout> diff --git a/app/src/main/res/layout/v_add_provider.xml b/app/src/main/res/layout/v_add_provider.xml new file mode 100644 index 00000000..44146fb5 --- /dev/null +++ b/app/src/main/res/layout/v_add_provider.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/loading_screen" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:visibility="gone"> + + <android.support.v7.widget.AppCompatImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:adjustViewBounds="true" + app:tint="@color/colorPrimary" + app:srcCompat="@drawable/action_history" + android:layout_marginTop="@dimen/loading_screen_icon_vertical_margin" + android:layout_marginBottom="@dimen/loading_screen_icon_vertical_margin" + /> + + <android.support.v7.widget.AppCompatTextView + android:id="@+id/progressbar_description" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:fadingEdge="horizontal" + android:singleLine="true" + android:text="@string/introduce_new_provider" + android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" + android:layout_marginTop="@dimen/standard_margin" + android:layout_marginBottom="@dimen/standard_margin" + /> + + <ProgressBar + android:id="@+id/progressbar" + style="@style/Widget.AppCompat.ProgressBar.Horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:indeterminate="true" + android:layout_marginTop="@dimen/standard_margin" + /> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3aa00124..968ac2e0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -113,6 +113,7 @@ <string name="always_on_vpn">Always-on VPN</string> <string name="do_not_show_again">Do not show again.</string> <string name="always_on_vpn_user_message">To enable always-on VPN in Android VPN Settings click on the configure icon [img src] and turn the switch on."</string> + <string name="title_activity_provider_add">ProviderAddActivity</string> <string name="donate_title">Donate</string> <string name="donate_default_message">Please donate today if you value secure communication that is easy for both the end-user and the service provider.</string> <string name="donate_message">LEAP depends on donations and grants. Please donate today if you value secure communication that is easy for both the end-user and the service provider.</string> |