summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java10
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java33
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java44
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipFragment.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivity.java19
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java10
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/StartActivity.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java46
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/userstatus/User.java46
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatus.java127
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java8
-rw-r--r--app/src/main/res/drawable-hdpi/ic_about_36.pngbin0 -> 1230 bytes
-rw-r--r--app/src/main/res/drawable-hdpi/ic_always_on_36.pngbin0 -> 1329 bytes
-rw-r--r--app/src/main/res/drawable-hdpi/ic_battery_36.pngbin0 -> 573 bytes
-rw-r--r--app/src/main/res/drawable-hdpi/ic_donate_36.pngbin0 -> 1322 bytes
-rw-r--r--app/src/main/res/drawable-hdpi/ic_log_36.pngbin0 -> 835 bytes
-rw-r--r--app/src/main/res/drawable-hdpi/ic_switch_provider_36.pngbin0 -> 627 bytes
-rw-r--r--app/src/main/res/drawable-mdpi/ic_about_36.pngbin0 -> 1009 bytes
-rw-r--r--app/src/main/res/drawable-mdpi/ic_always_on_36.pngbin0 -> 1104 bytes
-rw-r--r--app/src/main/res/drawable-mdpi/ic_battery_36.pngbin0 -> 609 bytes
-rw-r--r--app/src/main/res/drawable-mdpi/ic_donate_36.pngbin0 -> 944 bytes
-rw-r--r--app/src/main/res/drawable-mdpi/ic_log_36.pngbin0 -> 780 bytes
-rw-r--r--app/src/main/res/drawable-mdpi/ic_switch_provider_36.pngbin0 -> 609 bytes
-rw-r--r--app/src/main/res/drawable-xhdpi/ic_about_36.pngbin0 -> 1638 bytes
-rw-r--r--app/src/main/res/drawable-xhdpi/ic_always_on_36.pngbin0 -> 1740 bytes
-rw-r--r--app/src/main/res/drawable-xhdpi/ic_battery_36.pngbin0 -> 798 bytes
-rw-r--r--app/src/main/res/drawable-xhdpi/ic_donate_36.pngbin0 -> 1607 bytes
-rw-r--r--app/src/main/res/drawable-xhdpi/ic_log_36.pngbin0 -> 1124 bytes
-rw-r--r--app/src/main/res/drawable-xhdpi/ic_switch_provider_36.pngbin0 -> 763 bytes
-rw-r--r--app/src/main/res/drawable-xxhdpi/ic_about_36.pngbin0 -> 2213 bytes
-rw-r--r--app/src/main/res/drawable-xxhdpi/ic_always_on_36.pngbin0 -> 2446 bytes
-rw-r--r--app/src/main/res/drawable-xxhdpi/ic_battery_36.pngbin0 -> 845 bytes
-rw-r--r--app/src/main/res/drawable-xxhdpi/ic_donate_36.pngbin0 -> 2341 bytes
-rw-r--r--app/src/main/res/drawable-xxhdpi/ic_log_36.pngbin0 -> 1384 bytes
-rw-r--r--app/src/main/res/drawable-xxhdpi/ic_switch_provider_36.pngbin0 -> 878 bytes
-rw-r--r--app/src/main/res/drawable-xxxhdpi/ic_about_36.pngbin0 -> 3043 bytes
-rw-r--r--app/src/main/res/drawable-xxxhdpi/ic_always_on_36.pngbin0 -> 3353 bytes
-rw-r--r--app/src/main/res/drawable-xxxhdpi/ic_battery_36.pngbin0 -> 1159 bytes
-rw-r--r--app/src/main/res/drawable-xxxhdpi/ic_donate_36.pngbin0 -> 3063 bytes
-rw-r--r--app/src/main/res/drawable-xxxhdpi/ic_log_36.pngbin0 -> 1945 bytes
-rw-r--r--app/src/main/res/drawable-xxxhdpi/ic_switch_provider_36.pngbin0 -> 1070 bytes
-rw-r--r--app/src/main/res/drawable/black_circle.xml8
-rw-r--r--app/src/main/res/drawable/black_circle_pressed.xml10
-rw-r--r--app/src/main/res/drawable/black_circle_released.xml18
-rw-r--r--app/src/main/res/drawable/cust_button_primary.xml26
-rw-r--r--app/src/main/res/drawable/cust_button_primary_black.xml4
-rw-r--r--app/src/main/res/drawable/cust_button_primary_black_pressed.xml8
-rw-r--r--app/src/main/res/drawable/cust_button_primary_black_released.xml17
-rw-r--r--app/src/main/res/drawable/cust_button_primary_disabled.xml19
-rw-r--r--app/src/main/res/drawable/cust_button_primary_pressed.xml10
-rw-r--r--app/src/main/res/drawable/cust_button_primary_rect.xml24
-rw-r--r--app/src/main/res/drawable/cust_button_primary_released.xml19
-rw-r--r--app/src/main/res/drawable/progressbar_circle.xml89
-rw-r--r--app/src/main/res/layout-xlarge-port/a_add_provider.xml (renamed from app/src/main/res/layout-sw600dp-port/a_add_provider.xml)2
-rw-r--r--app/src/main/res/layout-xlarge-port/a_custom_provider_setup.xml (renamed from app/src/main/res/layout-sw600dp-port/a_custom_provider_setup.xml)0
-rw-r--r--app/src/main/res/layout-xlarge-port/a_provider_credentials.xml (renamed from app/src/main/res/layout-sw600dp-port/a_provider_credentials.xml)0
-rw-r--r--app/src/main/res/layout-xlarge-port/a_provider_detail.xml (renamed from app/src/main/res/layout-sw600dp-port/a_provider_detail.xml)0
-rw-r--r--app/src/main/res/layout-xlarge-port/a_provider_list.xml (renamed from app/src/main/res/layout-sw600dp-port/a_provider_list.xml)0
-rw-r--r--app/src/main/res/layout-xlarge-port/f_log.xml (renamed from app/src/main/res/layout-sw600dp-port/f_log.xml)0
-rw-r--r--app/src/main/res/layout-xlarge/a_add_provider.xml2
-rw-r--r--app/src/main/res/layout-xlarge/f_eip.xml6
-rw-r--r--app/src/main/res/layout-xlarge/f_log.xml (renamed from app/src/main/res/layout-sw600dp/f_log.xml)0
-rw-r--r--app/src/main/res/layout-xlarge/v_icon_text_list_item.xml32
-rw-r--r--app/src/main/res/layout-xlarge/v_switch_list_item.xml48
-rw-r--r--app/src/main/res/layout/a_add_provider_tablet_scrollview.xml1
-rw-r--r--app/src/main/res/layout/a_custom_provider_setup_tablet_linear_layout.xml3
-rw-r--r--app/src/main/res/layout/a_provider_credentials_tablet_linear_layout.xml3
-rw-r--r--app/src/main/res/layout/a_provider_detail_tablet_linear_layout.xml1
-rw-r--r--app/src/main/res/layout/a_provider_list_tablet_linear_layout.xml1
-rw-r--r--app/src/main/res/layout/f_eip.xml7
-rw-r--r--app/src/main/res/layout/v_icon_text_list_item.xml31
-rw-r--r--app/src/main/res/layout/v_main_button.xml4
-rw-r--r--app/src/main/res/layout/v_provider_credentials.xml8
-rw-r--r--app/src/main/res/layout/v_switch_list_item.xml59
-rw-r--r--app/src/main/res/values-sw600dp/dimens.xml1
-rw-r--r--app/src/main/res/values-v21/styles.xml10
-rw-r--r--app/src/main/res/values-v21/themes.xml2
-rw-r--r--app/src/main/res/values-w820dp/dimens.xml2
-rw-r--r--app/src/main/res/values/colors.xml5
-rw-r--r--app/src/main/res/values/dimens.xml2
-rw-r--r--app/src/main/res/values/strings.xml23
-rw-r--r--app/src/main/res/values/styles.xml11
-rw-r--r--app/src/main/res/values/themes.xml11
-rw-r--r--app/src/main/res/values/untranslatable.xml23
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java3
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java33
-rw-r--r--app/src/test/resources/error_messages.json12
91 files changed, 529 insertions, 444 deletions
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
index 3325d82b..1190d382 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
@@ -62,6 +62,7 @@ import static se.leap.bitmaskclient.R.string.malformed_url;
import static se.leap.bitmaskclient.R.string.setup_error_text;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details;
+import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString;
/**
* Created by cyberta on 04.01.18.
@@ -281,7 +282,8 @@ public class ProviderApiManager extends ProviderApiManagerBase {
try {
// try to download with provider CA on certificate error
JSONObject responseErrorJson = new JSONObject(responseString);
- if (dangerOn && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) {
+ if (dangerOn && responseErrorJson.getString(ERRORS).equals(
+ getProviderFormattedString(resources, R.string.certificate_error))) {
responseString = downloadWithoutCA(stringUrl);
}
} catch (JSONException e) {
@@ -309,7 +311,8 @@ public class ProviderApiManager extends ProviderApiManagerBase {
try {
// try to download with provider CA on certificate error
JSONObject responseErrorJson = new JSONObject(responseString);
- if (dangerOn && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) {
+ if (dangerOn && responseErrorJson.getString(ERRORS).equals(
+ getProviderFormattedString(resources, R.string.certificate_error))) {
responseString = downloadWithCommercialCA(urlString, dangerOn);
}
} catch (JSONException e) {
@@ -344,7 +347,8 @@ public class ProviderApiManager extends ProviderApiManagerBase {
try {
// danger danger: try to download without CA on certificate error
JSONObject responseErrorJson = new JSONObject(responseString);
- if (dangerOn && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) {
+ if (dangerOn && responseErrorJson.getString(ERRORS).equals(
+ getProviderFormattedString(resources, R.string.certificate_error))) {
responseString = downloadWithoutCA(urlString);
}
} catch (JSONException e) {
diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
index d52ebac1..fa28a875 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
@@ -20,6 +20,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
import se.leap.bitmaskclient.R;
+import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString;
+
public class VpnStatus {
@@ -103,6 +105,8 @@ public class VpnStatus {
if (mLastStateresid == R.string.state_waitconnectretry) {
return c.getString(R.string.state_waitconnectretry, mLaststatemsg);
+ } else if (mLastStateresid == R.string.void_vpn_establish) {
+ return getProviderFormattedString(c.getResources(), R.string.void_vpn_establish);
}
String prefix = c.getString(mLastStateresid);
diff --git a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
index 36dd5868..28e5f5af 100644
--- a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
@@ -62,25 +62,22 @@ public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseAct
android.R.id.text1,
optionsList.toArray(new String[optionsList.size()])
));
- options.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- String text = ((TextView) view).getText().toString();
- Intent intent;
- if (text.equals(getString(R.string.login_to_profile))) {
- Log.d(TAG, "login selected");
- intent = new Intent(getApplicationContext(), LoginActivity.class);
- } else if (text.equals(getString(R.string.create_profile))) {
- Log.d(TAG, "signup selected");
- intent = new Intent(getApplicationContext(), SignupActivity.class);
- } else {
- onAnonymouslySelected();
- return;
- }
- intent.putExtra(PROVIDER_KEY, provider);
- intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
- startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP);
+ options.setOnItemClickListener((parent, view, position, id) -> {
+ String text = ((TextView) view).getText().toString();
+ Intent intent;
+ if (text.equals(getString(R.string.login_to_profile))) {
+ Log.d(TAG, "login selected");
+ intent = new Intent(getApplicationContext(), LoginActivity.class);
+ } else if (text.equals(getString(R.string.create_profile))) {
+ Log.d(TAG, "signup selected");
+ intent = new Intent(getApplicationContext(), SignupActivity.class);
+ } else {
+ onAnonymouslySelected();
+ return;
}
+ intent.putExtra(PROVIDER_KEY, provider);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP);
});
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java b/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java
index 01b10575..89aeb4be 100644
--- a/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java
+++ b/app/src/main/java/se/leap/bitmaskclient/DrawerSettingsAdapter.java
@@ -16,6 +16,9 @@
*/
package se.leap.bitmaskclient;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.SwitchCompat;
import android.view.LayoutInflater;
@@ -23,6 +26,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
+import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
@@ -52,21 +56,27 @@ public class DrawerSettingsAdapter extends BaseAdapter {
private boolean isChecked = false;
private int itemType = NONE;
private CompoundButton.OnCheckedChangeListener callback;
+ private Drawable iconResource;
- private DrawerSettingsItem(String description, int viewType, boolean isChecked, int itemType, CompoundButton.OnCheckedChangeListener callback) {
+ private DrawerSettingsItem(Context context, String description, @DrawableRes int iconResource, int viewType, boolean isChecked, int itemType, CompoundButton.OnCheckedChangeListener callback) {
this.description = description;
this.viewType = viewType;
this.isChecked = isChecked;
this.itemType = itemType;
this.callback = callback;
+ try {
+ this.iconResource = context.getResources().getDrawable(iconResource);
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ }
}
- public static DrawerSettingsItem getSimpleTextInstance(String description, int itemType) {
- return new DrawerSettingsItem(description, VIEW_SIMPLE_TEXT, false, itemType, null);
+ public static DrawerSettingsItem getSimpleTextInstance(Context context, String description, @DrawableRes int iconResource, int itemType) {
+ return new DrawerSettingsItem(context, description, iconResource, VIEW_SIMPLE_TEXT, false, itemType, null);
}
- public static DrawerSettingsItem getSwitchInstance(String description, boolean isChecked, int itemType, CompoundButton.OnCheckedChangeListener callback) {
- return new DrawerSettingsItem(description, VIEW_SWITCH, isChecked, itemType, callback);
+ public static DrawerSettingsItem getSwitchInstance(Context context, String description, @DrawableRes int iconResource, boolean isChecked, int itemType, CompoundButton.OnCheckedChangeListener callback) {
+ return new DrawerSettingsItem(context, description, iconResource, VIEW_SWITCH, isChecked, itemType, callback);
}
public int getItemType() {
@@ -138,7 +148,7 @@ public class DrawerSettingsAdapter extends BaseAdapter {
switch(type) {
case VIEW_SIMPLE_TEXT:
convertView = initTextViewBinding(holder);
- holder.textView.setText(drawerSettingsItem.description);
+ bindSimpleText(drawerSettingsItem, holder);
break;
case VIEW_SWITCH:
convertView = initSwitchBinding(holder);
@@ -154,7 +164,7 @@ public class DrawerSettingsAdapter extends BaseAdapter {
holder.resetSwitchView();
convertView = initTextViewBinding(holder);
}
- holder.textView.setText(drawerSettingsItem.description);
+ bindSimpleText(drawerSettingsItem, holder);
break;
case VIEW_SWITCH:
if (!holder.isSwitchViewHolder()) {
@@ -169,23 +179,36 @@ public class DrawerSettingsAdapter extends BaseAdapter {
return convertView;
}
+ private void bindSimpleText(DrawerSettingsItem drawerSettingsItem, ViewHolder holder) {
+ holder.textView.setText(drawerSettingsItem.description);
+ if (drawerSettingsItem.iconResource != null) {
+ holder.iconView.setImageDrawable(drawerSettingsItem.iconResource);
+ }
+ }
+
private void bindSwitch(DrawerSettingsItem drawerSettingsItem, ViewHolder holder) {
holder.switchView.setChecked(drawerSettingsItem.isChecked);
- holder.switchView.setText(drawerSettingsItem.description);
+ holder.textView.setText(drawerSettingsItem.description);
holder.switchView.setOnCheckedChangeListener(drawerSettingsItem.callback);
+ if (drawerSettingsItem.iconResource != null) {
+ holder.iconView.setImageDrawable(drawerSettingsItem.iconResource);
+ }
}
@NonNull
private View initSwitchBinding(ViewHolder holder) {
View convertView = mInflater.inflate(R.layout.v_switch_list_item, null);
- holder.switchView = convertView.findViewById(android.R.id.text1);
+ holder.switchView = convertView.findViewById(R.id.option_switch);
+ holder.textView = convertView.findViewById(android.R.id.text1);
+ holder.iconView = convertView.findViewById(R.id.material_icon);
return convertView;
}
@NonNull
private View initTextViewBinding(ViewHolder holder) {
- View convertView = mInflater.inflate(R.layout.v_single_list_item, null);
+ View convertView = mInflater.inflate(R.layout.v_icon_text_list_item, null);
holder.textView = convertView.findViewById(android.R.id.text1);
+ holder.iconView = convertView.findViewById(R.id.material_icon);
return convertView;
}
@@ -200,6 +223,7 @@ public class DrawerSettingsAdapter extends BaseAdapter {
static class ViewHolder {
TextView textView;
+ ImageView iconView;
SwitchCompat switchView;
boolean isSwitchViewHolder() {
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
index 69d81ccf..11ad8da3 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
@@ -32,14 +32,15 @@ import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.AppCompatTextView;
+import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
@@ -61,12 +62,12 @@ import se.leap.bitmaskclient.views.VpnStateImage;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK;
+import static se.leap.bitmaskclient.Constants.ASK_TO_CANCEL_VPN;
import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_LOG_IN;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;
-import static se.leap.bitmaskclient.Constants.ASK_TO_CANCEL_VPN;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.EipSetupObserver.connectionRetry;
import static se.leap.bitmaskclient.EipSetupObserver.gatewayOrder;
@@ -92,7 +93,7 @@ public class EipFragment extends Fragment implements Observer {
VpnStateImage vpnStateImage;
@InjectView(R.id.vpn_main_button)
- Button mainButton;
+ AppCompatButton mainButton;
@InjectView(R.id.routed_text)
AppCompatTextView routedText;
@@ -537,7 +538,7 @@ public class EipFragment extends Fragment implements Observer {
private void setVpnRouteText() {
String vpnRouteString = provider.getName();
VpnProfile vpnProfile = ProfileManager.getLastConnectedVpn();
- if (vpnProfile != null && vpnProfile.mName != null) {
+ if (vpnProfile != null && !TextUtils.isEmpty(vpnProfile.mName)) {
vpnRouteString += " (" + vpnProfile.mName + ")";
}
vpnRoute.setText(vpnRouteString);
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
index 32b4562a..f2e333ab 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
@@ -20,10 +20,12 @@ package se.leap.bitmaskclient;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
+import android.support.annotation.StringRes;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
@@ -108,6 +110,7 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
bundle.putParcelable(PROVIDER_KEY, provider);
eipFragment.setArguments(bundle);
fragmentManagerEnhanced.replace(R.id.main_container, eipFragment, MainActivity.TAG);
+ hideActionBarSubTitle();
} else {
super.onBackPressed();
}
@@ -135,9 +138,11 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
}
bundle.putParcelable(PROVIDER_KEY, provider);
fragment.setArguments(bundle);
+ hideActionBarSubTitle();
break;
case ACTION_SHOW_LOG_FRAGMENT:
fragment = new LogFragment();
+ setActionBarTitle(R.string.log_fragment_title);
break;
default:
break;
@@ -152,6 +157,19 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
}
}
+ private void hideActionBarSubTitle() {
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setSubtitle(null);
+ }
+ }
+ private void setActionBarTitle(@StringRes int stringId) {
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setSubtitle(stringId);
+ }
+ }
+
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
@@ -190,6 +208,7 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
fragment.setArguments(arguments);
new FragmentManagerEnhanced(getSupportFragmentManager())
.replace(R.id.main_container, fragment, EipFragment.TAG);
+ hideActionBarSubTitle();
}
@Override
diff --git a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
index 7d1054f1..69270140 100644
--- a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
@@ -52,7 +52,7 @@ import static se.leap.bitmaskclient.R.string.error_io_exception_user_message;
import static se.leap.bitmaskclient.R.string.error_no_such_algorithm_exception_user_message;
import static se.leap.bitmaskclient.R.string.keyChainAccessError;
import static se.leap.bitmaskclient.R.string.server_unreachable_message;
-import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
+import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString;
/**
* Created by cyberta on 08.01.18.
@@ -92,7 +92,7 @@ public class OkHttpClientGenerator {
} catch (IllegalArgumentException e) {
e.printStackTrace();
// TODO ca cert is invalid - show better error ?!
- addErrorMessageToJson(initError, resources.getString(certificate_error));
+ addErrorMessageToJson(initError, getProviderFormattedString(resources, certificate_error));
} catch (IllegalStateException | KeyManagementException | KeyStoreException e) {
e.printStackTrace();
addErrorMessageToJson(initError, String.format(resources.getString(keyChainAccessError), e.getLocalizedMessage()));
@@ -102,7 +102,7 @@ public class OkHttpClientGenerator {
} catch (CertificateException e) {
e.printStackTrace();
// TODO ca cert is invalid - show better error ?!
- addErrorMessageToJson(initError, resources.getString(certificate_error));
+ addErrorMessageToJson(initError, getProviderFormattedString(resources, certificate_error));
} catch (UnknownHostException e) {
e.printStackTrace();
addErrorMessageToJson(initError, resources.getString(server_unreachable_message));
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
index 15c7457e..37adbe93 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
@@ -107,6 +107,7 @@ import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details;
import static se.leap.bitmaskclient.R.string.warning_expired_provider_cert;
import static se.leap.bitmaskclient.utils.ConfigHelper.getFingerprintFromCertificate;
+import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString;
import static se.leap.bitmaskclient.utils.ConfigHelper.parseRsaKeyFromString;
import static se.leap.bitmaskclient.utils.PreferenceHelper.deleteProviderDetailsFromPreferences;
import static se.leap.bitmaskclient.utils.PreferenceHelper.getFromPersistedProvider;
@@ -237,8 +238,8 @@ public abstract class ProviderApiManagerBase {
deleteProviderDetailsFromPreferences(preferences, provider.getDomain());
}
- String formatErrorMessage(final int toastStringId) {
- return formatErrorMessage(resources.getString(toastStringId));
+ String formatErrorMessage(final int errorStringId) {
+ return formatErrorMessage(getProviderFormattedString(resources, errorStringId));
}
private String formatErrorMessage(String errorMessage) {
@@ -751,10 +752,11 @@ public abstract class ProviderApiManagerBase {
Bundle setErrorResult(Bundle result, int errorMessageId, String errorId) {
JSONObject errorJson = new JSONObject();
+ String errorMessage = getProviderFormattedString(resources, errorMessageId);
if (errorId != null) {
- addErrorMessageToJson(errorJson, resources.getString(errorMessageId), errorId);
+ addErrorMessageToJson(errorJson, errorMessage, errorId);
} else {
- addErrorMessageToJson(errorJson, resources.getString(errorMessageId));
+ addErrorMessageToJson(errorJson, errorMessage);
}
result.putString(ERRORS, errorJson.toString());
result.putBoolean(BROADCAST_RESULT_KEY, false);
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
index 961957d2..55a1da93 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
@@ -46,7 +46,6 @@ import org.json.JSONException;
import butterknife.InjectView;
import butterknife.OnClick;
import se.leap.bitmaskclient.Constants.CREDENTIAL_ERRORS;
-import se.leap.bitmaskclient.userstatus.User;
import static android.text.TextUtils.isEmpty;
import static android.view.View.GONE;
@@ -250,14 +249,12 @@ public abstract class ProviderCredentialsBaseActivity extends ConfigWizardBaseAc
}
void login(String username, String password) {
- User.setUserName(username);
Bundle parameters = bundleUsernameAndPassword(username, password);
ProviderAPICommand.execute(this, LOG_IN, parameters, provider);
}
public void signUp(String username, String password) {
- User.setUserName(username);
Bundle parameters = bundleUsernameAndPassword(username, password);
ProviderAPICommand.execute(this, SIGN_UP, parameters, provider);
diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
index d30b98a0..d8aca351 100644
--- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
@@ -30,7 +30,6 @@ import java.lang.annotation.RetentionPolicy;
import de.blinkt.openvpn.core.VpnStatus;
import se.leap.bitmaskclient.eip.EipCommand;
-import se.leap.bitmaskclient.userstatus.User;
import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE;
import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
@@ -90,7 +89,6 @@ public class StartActivity extends Activity{
// initialize app necessities
VpnStatus.initLogCache(getApplicationContext().getCacheDir());
- User.init(getString(R.string.default_username));
prepareEIP();
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 21d061d1..640c143a 100644
--- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
@@ -27,6 +27,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
@@ -118,8 +119,6 @@ public class NavigationDrawerFragment extends Fragment {
private volatile boolean wasPaused;
private volatile boolean shouldCloseOnResume;
- private String title;
-
private SharedPreferences preferences;
private final static String KEY_SHOW_ENABLE_EXPERIMENTAL_FEATURE = "KEY_SHOW_ENABLE_EXPERIMENTAL_FEATURE";
@@ -188,7 +187,7 @@ public class NavigationDrawerFragment extends Fragment {
setupSettingsListAdapter();
setupSettingsListView();
accountListAdapter = new ArrayAdapter<>(actionBar.getThemedContext(),
- R.layout.v_single_list_item,
+ R.layout.v_icon_text_list_item,
android.R.id.text1);
refreshAccountListAdapter();
setupAccountsListView();
@@ -244,12 +243,7 @@ public class NavigationDrawerFragment extends Fragment {
private void setupAccountsListView() {
drawerAccountsListView = drawerView.findViewById(R.id.accountList);
drawerAccountsListView.setAdapter(accountListAdapter);
- drawerAccountsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- selectItem(parent, position);
- }
- });
+ drawerAccountsListView.setOnItemClickListener((parent, view, position, id) -> selectItem(parent, position));
}
private void setupSettingsListView() {
@@ -261,22 +255,24 @@ public class NavigationDrawerFragment extends Fragment {
private void setupSettingsListAdapter() {
settingsListAdapter = new DrawerSettingsAdapter(getLayoutInflater());
if (getContext() != null) {
- settingsListAdapter.addItem(getSwitchInstance(getString(R.string.save_battery),
+ settingsListAdapter.addItem(getSwitchInstance(getContext(),
+ getString(R.string.save_battery),
+ R.drawable.ic_battery_36,
getSaveBattery(getContext()),
BATTERY_SAVER,
(buttonView, newStateIsChecked) -> onSwitchItemSelected(BATTERY_SAVER, newStateIsChecked)));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- settingsListAdapter.addItem(getSimpleTextInstance(getString(R.string.always_on_vpn), ALWAYS_ON));
+ settingsListAdapter.addItem(getSimpleTextInstance(getContext(), getString(R.string.always_on_vpn), R.drawable.ic_always_on_36, ALWAYS_ON));
}
if (isDefaultBitmask()) {
- settingsListAdapter.addItem(getSimpleTextInstance(getString(switch_provider_menu_option), SWITCH_PROVIDER));
+ settingsListAdapter.addItem(getSimpleTextInstance(getContext(), getString(switch_provider_menu_option), R.drawable.ic_switch_provider_36, SWITCH_PROVIDER));
}
- settingsListAdapter.addItem(getSimpleTextInstance(getString(log_fragment_title), LOG));
+ settingsListAdapter.addItem(getSimpleTextInstance(getContext(), getString(log_fragment_title), R.drawable.ic_log_36, LOG));
if (ENABLE_DONATION) {
- settingsListAdapter.addItem(getSimpleTextInstance(getString(donate_title), DONATE));
+ settingsListAdapter.addItem(getSimpleTextInstance(getContext(), getString(donate_title), R.drawable.ic_donate_36, DONATE));
}
- settingsListAdapter.addItem(getSimpleTextInstance(getString(about_fragment_title), ABOUT));
+ settingsListAdapter.addItem(getSimpleTextInstance(getContext(), getString(about_fragment_title), R.drawable.ic_about_36, ABOUT));
}
private ActionBar setupActionBar() {
@@ -285,6 +281,7 @@ public class NavigationDrawerFragment extends Fragment {
final ActionBar actionBar = activity.getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
+ actionBar.setDisplayShowTitleEnabled(true);
return actionBar;
}
@@ -464,12 +461,12 @@ public class NavigationDrawerFragment extends Fragment {
Fragment fragment = null;
if (parent == drawerAccountsListView) {
- title = getString(R.string.vpn_fragment_title);
fragment = new EipFragment();
Bundle arguments = new Bundle();
Provider currentProvider = getSavedProviderFromSharedPreferences(preferences);
arguments.putParcelable(PROVIDER_KEY, currentProvider);
fragment.setArguments(arguments);
+ hideActionBarSubTitle();
} else {
DrawerSettingsItem settingsItem = settingsListAdapter.getItem(position);
switch (settingsItem.getItemType()) {
@@ -477,12 +474,12 @@ public class NavigationDrawerFragment extends Fragment {
getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
break;
case LOG:
- title = getString(log_fragment_title);
fragment = new LogFragment();
+ setActionBarTitle(log_fragment_title);
break;
case ABOUT:
- title = getString(about_fragment_title);
fragment = new AboutFragment();
+ setActionBarTitle(about_fragment_title);
break;
case ALWAYS_ON:
if (getShowAlwaysOnDialog(getContext())) {
@@ -506,14 +503,19 @@ public class NavigationDrawerFragment extends Fragment {
fragmentManager.replace(R.id.main_container, fragment, MainActivity.TAG);
}
- restoreActionBar();
}
- public void restoreActionBar() {
+ private void setActionBarTitle(@StringRes int resId) {
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setSubtitle(resId);
+ }
+ }
+
+ private void hideActionBarSubTitle() {
ActionBar actionBar = getActionBar();
if (actionBar != null) {
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setSubtitle(title);
+ actionBar.setSubtitle(null);
}
}
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 a896197c..f6e3df7c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
@@ -40,6 +40,7 @@ import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_BLOCKING_VPN;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
import static se.leap.bitmaskclient.Constants.EIP_IS_ALWAYS_ON;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
+import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString;
public class VoidVpnService extends VpnService implements Observer, VpnNotificationManager.VpnServiceCallback {
@@ -147,7 +148,7 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat
private void establishBlockingVpn() {
try {
- VpnStatus.logInfo(getString(R.string.void_vpn_establish));
+ VpnStatus.logInfo(getProviderFormattedString(getResources(), R.string.void_vpn_establish));
VpnStatus.updateStateString(STATE_ESTABLISH, "",
R.string.void_vpn_establish, ConnectionStatus.LEVEL_BLOCKING);
Builder builder = prepareBlockingVpnProfile();
@@ -180,9 +181,10 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat
}
if (eipStatus.isBlockingVpnEstablished()) {
+ String blockingMessage = getProviderFormattedString(getResources(), eipStatus.getLocalizedResId());
notificationManager.buildVoidVpnNotification(
- getString(eipStatus.getLocalizedResId()),
- getString(eipStatus.getLocalizedResId()),
+ blockingMessage,
+ blockingMessage,
eipStatus.getLevel());
} else {
notificationManager.stopNotifications(NOTIFICATION_CHANNEL_NEWSTATUS_ID);
diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/User.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/User.java
deleted file mode 100644
index 64ce0629..00000000
--- a/app/src/main/java/se/leap/bitmaskclient/userstatus/User.java
+++ /dev/null
@@ -1,46 +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.userstatus;
-
-import se.leap.bitmaskclient.LeapSRPSession;
-
-public class User {
- private static String user_name;
- private static User user;
-
- public static User init(String default_username) {
- if (user == null) {
- user = new User();
- user.setUserName(default_username);
- }
- return user;
- }
-
- public static void setUserName(String user_name) {
- User.user_name = user_name;
- }
-
- private User() { }
-
- public static String userName() {
- return user_name;
- }
-
- public static boolean loggedIn() {
- return LeapSRPSession.loggedIn();
- }
-}
diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatus.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatus.java
deleted file mode 100644
index 90ad0ffd..00000000
--- a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatus.java
+++ /dev/null
@@ -1,127 +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.userstatus;
-
-import android.content.res.*;
-
-import java.util.*;
-
-import se.leap.bitmaskclient.R;
-
-public class UserStatus extends Observable {
- public static String TAG = UserStatus.class.getSimpleName();
- private static UserStatus current_status;
- private static Resources resources;
-
- public enum SessionStatus {
- LOGGED_IN,
- LOGGED_OUT,
- NOT_LOGGED_IN,
- DIDNT_LOG_OUT,
- LOGGING_IN,
- LOGGING_OUT,
- SIGNING_UP;
-
- @Override
- public String toString() {
- int id = 0;
- if(this == SessionStatus.LOGGED_IN)
- id = R.string.logged_in_user_status;
- else if(this == SessionStatus.LOGGED_OUT)
- id = R.string.logged_out_user_status;
- else if(this == SessionStatus.NOT_LOGGED_IN)
- id = R.string.not_logged_in_user_status;
- else if(this == SessionStatus.DIDNT_LOG_OUT)
- id = R.string.didnt_log_out_user_status;
- else if(this == SessionStatus.LOGGING_IN)
- id = R.string.logging_in_user_status;
- else if(this == SessionStatus.LOGGING_OUT)
- id = R.string.logging_out_user_status;
- else if(this == SessionStatus.SIGNING_UP)
- id = R.string.signingup_message;
-
- return resources.getString(id);
- }
- }
-
- private static SessionStatus session_status = SessionStatus.LOGGED_OUT;
-
- public static UserStatus getInstance(Resources resources) {
- if (current_status == null) {
- current_status = new UserStatus(resources);
- }
- return current_status;
- }
-
- private UserStatus(Resources resources) {
- UserStatus.resources = resources;
- }
-
- private void sessionStatus(SessionStatus session_status) {
- this.session_status = session_status;
- }
-
- public SessionStatus sessionStatus() {
- return session_status;
- }
-
- public boolean inProgress() {
- return session_status == SessionStatus.LOGGING_IN
- || session_status == SessionStatus.LOGGING_OUT;
- }
-
- public boolean isLoggedIn() {
- return session_status == SessionStatus.LOGGED_IN;
- }
-
- public boolean isLoggedOut() {
- return session_status == SessionStatus.LOGGED_OUT;
- }
-
- public boolean notLoggedIn() {
- return session_status == SessionStatus.NOT_LOGGED_IN;
- }
-
- public boolean didntLogOut() {
- return session_status == SessionStatus.DIDNT_LOG_OUT;
- }
-
- public static void updateStatus(SessionStatus session_status, Resources resources) {
- current_status = getInstance(resources);
- current_status.sessionStatus(session_status);
- current_status.setChanged();
- current_status.notifyObservers();
- }
-
- @Override
- public String toString() {
- String user_session_status = User.userName();
-
- String default_username = resources.getString(R.string.default_username, "");
- if(user_session_status.isEmpty() && !default_username.equalsIgnoreCase("null")) user_session_status = default_username;
- user_session_status += " " + session_status.toString();
-
- user_session_status = user_session_status.trim();
- if(User.userName().isEmpty())
- user_session_status = capitalize(user_session_status);
- return user_session_status;
- }
-
- private String capitalize(String to_be_capitalized) {
- return to_be_capitalized.substring(0,1).toUpperCase() + to_be_capitalized.substring(1);
- }
-}
diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java
index d1ac0eb3..da74c7c4 100644
--- a/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java
@@ -17,8 +17,10 @@
package se.leap.bitmaskclient.utils;
import android.content.Context;
+import android.content.res.Resources;
import android.os.Looper;
import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
import org.json.JSONException;
import org.json.JSONObject;
@@ -43,6 +45,7 @@ import java.util.Calendar;
import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.ProviderAPI;
+import se.leap.bitmaskclient.R;
import static se.leap.bitmaskclient.Constants.DEFAULT_BITMASK;
@@ -182,4 +185,9 @@ public class ConfigHelper {
public static int getCurrentTimezone() {
return Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000;
}
+
+ public static String getProviderFormattedString(Resources resources, @StringRes int resourceId) {
+ String appName = resources.getString(R.string.app_name);
+ return resources.getString(resourceId, appName);
+ }
}
diff --git a/app/src/main/res/drawable-hdpi/ic_about_36.png b/app/src/main/res/drawable-hdpi/ic_about_36.png
new file mode 100644
index 00000000..52f4e395
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/ic_about_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/ic_always_on_36.png b/app/src/main/res/drawable-hdpi/ic_always_on_36.png
new file mode 100644
index 00000000..8547b61d
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/ic_always_on_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/ic_battery_36.png b/app/src/main/res/drawable-hdpi/ic_battery_36.png
new file mode 100644
index 00000000..7d4cd60b
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/ic_battery_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/ic_donate_36.png b/app/src/main/res/drawable-hdpi/ic_donate_36.png
new file mode 100644
index 00000000..f269af8c
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/ic_donate_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/ic_log_36.png b/app/src/main/res/drawable-hdpi/ic_log_36.png
new file mode 100644
index 00000000..3ed90a08
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/ic_log_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/ic_switch_provider_36.png b/app/src/main/res/drawable-hdpi/ic_switch_provider_36.png
new file mode 100644
index 00000000..0bace0ce
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/ic_switch_provider_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/ic_about_36.png b/app/src/main/res/drawable-mdpi/ic_about_36.png
new file mode 100644
index 00000000..110e8f2e
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/ic_about_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/ic_always_on_36.png b/app/src/main/res/drawable-mdpi/ic_always_on_36.png
new file mode 100644
index 00000000..ea15a067
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/ic_always_on_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/ic_battery_36.png b/app/src/main/res/drawable-mdpi/ic_battery_36.png
new file mode 100644
index 00000000..0490996a
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/ic_battery_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/ic_donate_36.png b/app/src/main/res/drawable-mdpi/ic_donate_36.png
new file mode 100644
index 00000000..b47fecaf
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/ic_donate_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/ic_log_36.png b/app/src/main/res/drawable-mdpi/ic_log_36.png
new file mode 100644
index 00000000..85a5210c
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/ic_log_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/ic_switch_provider_36.png b/app/src/main/res/drawable-mdpi/ic_switch_provider_36.png
new file mode 100644
index 00000000..a830e782
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/ic_switch_provider_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_about_36.png b/app/src/main/res/drawable-xhdpi/ic_about_36.png
new file mode 100644
index 00000000..7a15dacc
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/ic_about_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_always_on_36.png b/app/src/main/res/drawable-xhdpi/ic_always_on_36.png
new file mode 100644
index 00000000..811d64d7
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/ic_always_on_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_battery_36.png b/app/src/main/res/drawable-xhdpi/ic_battery_36.png
new file mode 100644
index 00000000..4bed162d
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/ic_battery_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_donate_36.png b/app/src/main/res/drawable-xhdpi/ic_donate_36.png
new file mode 100644
index 00000000..fe680f0e
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/ic_donate_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_log_36.png b/app/src/main/res/drawable-xhdpi/ic_log_36.png
new file mode 100644
index 00000000..571e09ae
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/ic_log_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_switch_provider_36.png b/app/src/main/res/drawable-xhdpi/ic_switch_provider_36.png
new file mode 100644
index 00000000..be31da48
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/ic_switch_provider_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_about_36.png b/app/src/main/res/drawable-xxhdpi/ic_about_36.png
new file mode 100644
index 00000000..b2c8cfcc
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/ic_about_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_always_on_36.png b/app/src/main/res/drawable-xxhdpi/ic_always_on_36.png
new file mode 100644
index 00000000..bfb87c49
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/ic_always_on_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_battery_36.png b/app/src/main/res/drawable-xxhdpi/ic_battery_36.png
new file mode 100644
index 00000000..7a311741
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/ic_battery_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_donate_36.png b/app/src/main/res/drawable-xxhdpi/ic_donate_36.png
new file mode 100644
index 00000000..08bff222
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/ic_donate_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_log_36.png b/app/src/main/res/drawable-xxhdpi/ic_log_36.png
new file mode 100644
index 00000000..b0396a89
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/ic_log_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_switch_provider_36.png b/app/src/main/res/drawable-xxhdpi/ic_switch_provider_36.png
new file mode 100644
index 00000000..229e3147
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/ic_switch_provider_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_about_36.png b/app/src/main/res/drawable-xxxhdpi/ic_about_36.png
new file mode 100644
index 00000000..bbbd987f
--- /dev/null
+++ b/app/src/main/res/drawable-xxxhdpi/ic_about_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_always_on_36.png b/app/src/main/res/drawable-xxxhdpi/ic_always_on_36.png
new file mode 100644
index 00000000..f8e2a790
--- /dev/null
+++ b/app/src/main/res/drawable-xxxhdpi/ic_always_on_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_battery_36.png b/app/src/main/res/drawable-xxxhdpi/ic_battery_36.png
new file mode 100644
index 00000000..70087a20
--- /dev/null
+++ b/app/src/main/res/drawable-xxxhdpi/ic_battery_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_donate_36.png b/app/src/main/res/drawable-xxxhdpi/ic_donate_36.png
new file mode 100644
index 00000000..cf04212d
--- /dev/null
+++ b/app/src/main/res/drawable-xxxhdpi/ic_donate_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_log_36.png b/app/src/main/res/drawable-xxxhdpi/ic_log_36.png
new file mode 100644
index 00000000..30f5e866
--- /dev/null
+++ b/app/src/main/res/drawable-xxxhdpi/ic_log_36.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_switch_provider_36.png b/app/src/main/res/drawable-xxxhdpi/ic_switch_provider_36.png
new file mode 100644
index 00000000..56a9bd29
--- /dev/null
+++ b/app/src/main/res/drawable-xxxhdpi/ic_switch_provider_36.png
Binary files differ
diff --git a/app/src/main/res/drawable/black_circle.xml b/app/src/main/res/drawable/black_circle.xml
index 533652d6..f64c034d 100644
--- a/app/src/main/res/drawable/black_circle.xml
+++ b/app/src/main/res/drawable/black_circle.xml
@@ -1,9 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
-<item>
- <shape android:shape="oval">
- <solid android:color="@color/black800"/>
- <size android:width="250dp" android:height="250dp"/>
- </shape>
-</item>
+ <item android:drawable="@drawable/black_circle_pressed" android:state_pressed="true"/>
+ <item android:drawable="@drawable/black_circle_released"/>
</selector> \ No newline at end of file
diff --git a/app/src/main/res/drawable/black_circle_pressed.xml b/app/src/main/res/drawable/black_circle_pressed.xml
new file mode 100644
index 00000000..d7d646a0
--- /dev/null
+++ b/app/src/main/res/drawable/black_circle_pressed.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="oval">
+ <solid android:color="@color/black800_secondary"/>
+ <size android:width="250dp" android:height="250dp"/>
+ </shape>
+ </item>
+
+</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/drawable/black_circle_released.xml b/app/src/main/res/drawable/black_circle_released.xml
new file mode 100644
index 00000000..b1ef3827
--- /dev/null
+++ b/app/src/main/res/drawable/black_circle_released.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="oval">
+ <solid android:color="@color/black800_transparent"/>
+ <size android:width="250dp" android:height="250dp"/>
+ </shape>
+ </item>
+ <item
+ android:bottom="7dp"
+ android:right="5dp"
+ >
+ <shape android:shape="oval">
+ <solid android:color="@color/black800"/>
+ <size android:width="250dp" android:height="250dp"/>
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary.xml b/app/src/main/res/drawable/cust_button_primary.xml
index 3b0f7e26..31f9fbdd 100644
--- a/app/src/main/res/drawable/cust_button_primary.xml
+++ b/app/src/main/res/drawable/cust_button_primary.xml
@@ -1,24 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item android:state_pressed="true" >
- <shape android:shape="rectangle" >
- <corners android:radius="50dp" />
- <padding android:left="8dp" android:right="8dp"/>
- <solid android:color="@color/colorPrimaryDark"/>
- </shape>
- </item>
- <item android:state_focused="true">
- <shape android:shape="rectangle" >
- <corners android:radius="50dp" />
- <padding android:left="8dp" android:right="8dp"/>
- <solid android:color="@color/colorPrimaryDark"/>
- </shape>
- </item>
- <item >
- <shape android:shape="rectangle" >
- <corners android:radius="50dp" />
- <padding android:left="8dp" android:right="8dp"/>
- <solid android:color="@color/colorPrimary"/>
- </shape>
- </item>
+
+ <item android:state_enabled="false" android:drawable="@drawable/cust_button_primary_disabled"/>
+ <item android:state_pressed="true" android:drawable="@drawable/cust_button_primary_pressed"/>
+ <item android:state_focused="true" android:drawable="@drawable/cust_button_primary_pressed"/>
+ <item android:drawable="@drawable/cust_button_primary_released"/>
</selector> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary_black.xml b/app/src/main/res/drawable/cust_button_primary_black.xml
new file mode 100644
index 00000000..d43237a1
--- /dev/null
+++ b/app/src/main/res/drawable/cust_button_primary_black.xml
@@ -0,0 +1,4 @@
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/cust_button_primary_black_pressed"/>
+ <item android:drawable="@drawable/cust_button_primary_black_released"/>
+</selector> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary_black_pressed.xml b/app/src/main/res/drawable/cust_button_primary_black_pressed.xml
new file mode 100644
index 00000000..b8040ec0
--- /dev/null
+++ b/app/src/main/res/drawable/cust_button_primary_black_pressed.xml
@@ -0,0 +1,8 @@
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/button_radius"/>
+ <solid android:color="@color/black800_secondary"/>
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary_black_released.xml b/app/src/main/res/drawable/cust_button_primary_black_released.xml
new file mode 100644
index 00000000..8195c0c1
--- /dev/null
+++ b/app/src/main/res/drawable/cust_button_primary_black_released.xml
@@ -0,0 +1,17 @@
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/button_radius"/>
+ <solid android:color="@color/black800_transparent"/>
+ </shape>
+ </item>
+
+ <item
+ android:bottom="@dimen/button_bevel"
+ >
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/button_radius"/>
+ <solid android:color="@color/black800"/>
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary_disabled.xml b/app/src/main/res/drawable/cust_button_primary_disabled.xml
new file mode 100644
index 00000000..f62ecce3
--- /dev/null
+++ b/app/src/main/res/drawable/cust_button_primary_disabled.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item>
+ <shape android:shape="rectangle" >
+ <corners android:radius="50dp" />
+ <solid android:color="@color/colorPrimary_transparent"/>
+ </shape>
+ </item>
+ <item
+ android:bottom="@dimen/button_bevel"
+ >
+ <shape android:shape="rectangle">
+ <corners android:radius="50dp" />
+ <padding android:right="2dp"/>
+ <padding android:left="8dp" android:right="8dp"/>
+ <solid android:color="@color/colorDisabled"/>
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary_pressed.xml b/app/src/main/res/drawable/cust_button_primary_pressed.xml
new file mode 100644
index 00000000..012631e7
--- /dev/null
+++ b/app/src/main/res/drawable/cust_button_primary_pressed.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item>
+ <shape android:shape="rectangle" >
+ <corners android:radius="50dp" />
+ <padding android:left="8dp" android:right="8dp"/>
+ <solid android:color="@color/colorPrimaryDark"/>
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary_rect.xml b/app/src/main/res/drawable/cust_button_primary_rect.xml
new file mode 100644
index 00000000..c83d4e62
--- /dev/null
+++ b/app/src/main/res/drawable/cust_button_primary_rect.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:state_pressed="true" >
+ <shape android:shape="rectangle" >
+ <corners android:radius="8dp" />
+ <padding android:left="8dp" android:right="8dp"/>
+ <solid android:color="@color/colorPrimaryDark"/>
+ </shape>
+ </item>
+ <item android:state_focused="true">
+ <shape android:shape="rectangle" >
+ <corners android:radius="8dp" />
+ <padding android:left="8dp" android:right="8dp"/>
+ <solid android:color="@color/colorPrimaryDark"/>
+ </shape>
+ </item>
+ <item >
+ <shape android:shape="rectangle" >
+ <corners android:radius="8dp" />
+ <padding android:left="8dp" android:right="8dp"/>
+ <solid android:color="@color/colorPrimary"/>
+ </shape>
+ </item>
+</selector> \ No newline at end of file
diff --git a/app/src/main/res/drawable/cust_button_primary_released.xml b/app/src/main/res/drawable/cust_button_primary_released.xml
new file mode 100644
index 00000000..b9c2020f
--- /dev/null
+++ b/app/src/main/res/drawable/cust_button_primary_released.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item>
+ <shape android:shape="rectangle" >
+ <corners android:radius="50dp" />
+ <solid android:color="@color/colorPrimary_transparent"/>
+ </shape>
+ </item>
+ <item
+ android:bottom="@dimen/button_bevel"
+ >
+ <shape android:shape="rectangle" >
+ <corners android:radius="50dp" />
+ <padding android:right="2dp"/>
+ <padding android:left="8dp" android:right="8dp"/>
+ <solid android:color="@color/colorPrimary"/>
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/drawable/progressbar_circle.xml b/app/src/main/res/drawable/progressbar_circle.xml
index 6257e3af..3d5f6026 100644
--- a/app/src/main/res/drawable/progressbar_circle.xml
+++ b/app/src/main/res/drawable/progressbar_circle.xml
@@ -1,83 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:id="@+id/progress1">
- <rotate
- android:fromDegrees="-90"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toDegrees="90">
-
- <shape
- android:shape="ring"
- android:useLevel="true">
- <gradient
- android:endColor="#00c5e1a5"
- android:centerColor="#c5e1a5"
- android:startColor="#00ffe082"
- android:type="sweep"
- />
- </shape>
- </rotate>
- </item>
-
- <item android:id="@+id/progress2">
- <rotate
- android:fromDegrees="0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toDegrees="180">
-
- <shape
- android:shape="ring"
- android:useLevel="true">
- <gradient
- android:endColor="#00ffcc80"
- android:centerColor="#ffcc80"
- android:startColor="#00ffcc80"
- android:type="sweep"
- />
- </shape>
- </rotate>
- </item>
-
- <item android:id="@+id/progress3">
- <rotate
- android:fromDegrees="90"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toDegrees="270">
+ <item>
+ <scale
+ android:scaleHeight="125%"
+ android:scaleWidth="125%"
+ android:scaleGravity="center"
+ >
<shape
- android:shape="ring"
- android:useLevel="true">
+ android:shape="oval"
+ android:useLevel="true"
+ >
<gradient
- android:endColor="#00ce93d8"
- android:centerColor="#ce93d8"
- android:startColor="#00ce93d8"
- android:type="sweep"
+ android:startColor="@color/colorPrimaryDark"
+ android:centerColor="@color/colorPrimary"
+ android:endColor="@color/black800_high_transparent"
+ android:gradientRadius="100dp"
+ android:type="radial"
/>
</shape>
- </rotate>
+ </scale>
</item>
-
- <item android:id="@+id/progress4">
- <rotate
- android:fromDegrees="180"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toDegrees="0">
- <shape
- android:shape="ring"
- android:useLevel="true">
- <gradient
- android:endColor="#0081d4fa"
- android:centerColor="#81d4fa"
- android:startColor="#0081d4fa"
- android:type="sweep"
- />
- </shape>
- </rotate>
- </item>
-
</layer-list> \ No newline at end of file
diff --git a/app/src/main/res/layout-sw600dp-port/a_add_provider.xml b/app/src/main/res/layout-xlarge-port/a_add_provider.xml
index 0249a3fe..67aef3d6 100644
--- a/app/src/main/res/layout-sw600dp-port/a_add_provider.xml
+++ b/app/src/main/res/layout-xlarge-port/a_add_provider.xml
@@ -10,7 +10,7 @@
<android.support.v7.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:srcCompat="@drawable/background_onboarding_tablet"
+ app:srcCompat="@drawable/background_main"
android:scaleType="centerCrop"
/>
diff --git a/app/src/main/res/layout-sw600dp-port/a_custom_provider_setup.xml b/app/src/main/res/layout-xlarge-port/a_custom_provider_setup.xml
index f32cdd65..f32cdd65 100644
--- a/app/src/main/res/layout-sw600dp-port/a_custom_provider_setup.xml
+++ b/app/src/main/res/layout-xlarge-port/a_custom_provider_setup.xml
diff --git a/app/src/main/res/layout-sw600dp-port/a_provider_credentials.xml b/app/src/main/res/layout-xlarge-port/a_provider_credentials.xml
index ab140a2e..ab140a2e 100644
--- a/app/src/main/res/layout-sw600dp-port/a_provider_credentials.xml
+++ b/app/src/main/res/layout-xlarge-port/a_provider_credentials.xml
diff --git a/app/src/main/res/layout-sw600dp-port/a_provider_detail.xml b/app/src/main/res/layout-xlarge-port/a_provider_detail.xml
index dac21eaf..dac21eaf 100644
--- a/app/src/main/res/layout-sw600dp-port/a_provider_detail.xml
+++ b/app/src/main/res/layout-xlarge-port/a_provider_detail.xml
diff --git a/app/src/main/res/layout-sw600dp-port/a_provider_list.xml b/app/src/main/res/layout-xlarge-port/a_provider_list.xml
index 61ea6882..61ea6882 100644
--- a/app/src/main/res/layout-sw600dp-port/a_provider_list.xml
+++ b/app/src/main/res/layout-xlarge-port/a_provider_list.xml
diff --git a/app/src/main/res/layout-sw600dp-port/f_log.xml b/app/src/main/res/layout-xlarge-port/f_log.xml
index ebadeb74..ebadeb74 100644
--- a/app/src/main/res/layout-sw600dp-port/f_log.xml
+++ b/app/src/main/res/layout-xlarge-port/f_log.xml
diff --git a/app/src/main/res/layout-xlarge/a_add_provider.xml b/app/src/main/res/layout-xlarge/a_add_provider.xml
index 10bae173..4e6abd3d 100644
--- a/app/src/main/res/layout-xlarge/a_add_provider.xml
+++ b/app/src/main/res/layout-xlarge/a_add_provider.xml
@@ -10,7 +10,7 @@
<android.support.v7.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:srcCompat="@drawable/background_onboarding_tablet"
+ app:srcCompat="@drawable/background_main"
android:scaleType="centerCrop"
/>
diff --git a/app/src/main/res/layout-xlarge/f_eip.xml b/app/src/main/res/layout-xlarge/f_eip.xml
index 4db7cc56..1c355d58 100644
--- a/app/src/main/res/layout-xlarge/f_eip.xml
+++ b/app/src/main/res/layout-xlarge/f_eip.xml
@@ -83,17 +83,21 @@
<android.support.v7.widget.AppCompatButton
android:id="@+id/vpn_main_button"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="40dp"
+ android:minWidth="200dp"
android:layout_marginBottom="@dimen/stdpadding"
android:layout_marginEnd="@dimen/stdpadding"
android:layout_marginStart="@dimen/stdpadding"
android:layout_marginTop="@dimen/stdpadding"
android:layout_marginLeft="@dimen/stdpadding"
android:layout_marginRight="@dimen/stdpadding"
+ android:paddingLeft="@dimen/stdpadding"
+ android:paddingRight="@dimen/stdpadding"
app:layout_constraintBottom_toBottomOf="@+id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="@string/vpn.button.turn.on"
+ tools:text="Turn on in another language"
style="@style/BitmaskButtonBlack"
/>
diff --git a/app/src/main/res/layout-sw600dp/f_log.xml b/app/src/main/res/layout-xlarge/f_log.xml
index b014ee9d..b014ee9d 100644
--- a/app/src/main/res/layout-sw600dp/f_log.xml
+++ b/app/src/main/res/layout-xlarge/f_log.xml
diff --git a/app/src/main/res/layout-xlarge/v_icon_text_list_item.xml b/app/src/main/res/layout-xlarge/v_icon_text_list_item.xml
new file mode 100644
index 00000000..0192e080
--- /dev/null
+++ b/app/src/main/res/layout-xlarge/v_icon_text_list_item.xml
@@ -0,0 +1,32 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/item_container"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <ImageView
+ android:id="@+id/material_icon"
+ android:layout_width="?android:attr/listPreferredItemHeight"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_gravity="center"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ tools:src="@drawable/ic_add_circle_outline_grey600_24dp"
+ />
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ tools:text="TEST"
+ />
+
+</LinearLayout>
diff --git a/app/src/main/res/layout-xlarge/v_switch_list_item.xml b/app/src/main/res/layout-xlarge/v_switch_list_item.xml
new file mode 100644
index 00000000..d692070e
--- /dev/null
+++ b/app/src/main/res/layout-xlarge/v_switch_list_item.xml
@@ -0,0 +1,48 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/item_container"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:layout_width="match_parent"
+ >
+
+ <ImageView
+ android:id="@+id/material_icon"
+ android:layout_width="?android:attr/listPreferredItemHeight"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_gravity="center"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ tools:src="@drawable/ic_add_circle_outline_grey600_24dp"
+ />
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ tools:text="TEST"
+ android:layout_toEndOf="@id/material_icon"
+ android:layout_toRightOf="@+id/material_icon"
+ />
+
+ <android.support.v7.widget.SwitchCompat
+ android:id="@+id/option_switch"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:checked="false"
+ tools:text="" />
+</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/a_add_provider_tablet_scrollview.xml b/app/src/main/res/layout/a_add_provider_tablet_scrollview.xml
index 132deba0..4510af7d 100644
--- a/app/src/main/res/layout/a_add_provider_tablet_scrollview.xml
+++ b/app/src/main/res/layout/a_add_provider_tablet_scrollview.xml
@@ -9,7 +9,6 @@
app:layout_constraintHeight_min="411dp"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toTopOf="@+id/guideline_top"
- app:layout_constraintWidth_min="731dp"
android:layout_margin="@dimen/stdpadding"
android:padding="@dimen/stdpadding"
android:background="@color/colorBackground"
diff --git a/app/src/main/res/layout/a_custom_provider_setup_tablet_linear_layout.xml b/app/src/main/res/layout/a_custom_provider_setup_tablet_linear_layout.xml
index b3df1950..9fb67092 100644
--- a/app/src/main/res/layout/a_custom_provider_setup_tablet_linear_layout.xml
+++ b/app/src/main/res/layout/a_custom_provider_setup_tablet_linear_layout.xml
@@ -10,8 +10,7 @@
app:layout_constraintEnd_toStartOf="@+id/guideline_right"
app:layout_constraintHeight_min="411dp"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
- app:layout_constraintTop_toTopOf="@+id/guideline_top"
- app:layout_constraintWidth_min="731dp">
+ app:layout_constraintTop_toTopOf="@+id/guideline_top">
<!-- a "content" view that is required for
ConfigWizardBaseActivities -->
<LinearLayout
diff --git a/app/src/main/res/layout/a_provider_credentials_tablet_linear_layout.xml b/app/src/main/res/layout/a_provider_credentials_tablet_linear_layout.xml
index b92a4bef..486d0419 100644
--- a/app/src/main/res/layout/a_provider_credentials_tablet_linear_layout.xml
+++ b/app/src/main/res/layout/a_provider_credentials_tablet_linear_layout.xml
@@ -13,8 +13,7 @@
app:layout_constraintEnd_toStartOf="@+id/guideline_right"
app:layout_constraintHeight_min="411dp"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
- app:layout_constraintTop_toTopOf="@+id/guideline_top"
- app:layout_constraintWidth_min="731dp">
+ app:layout_constraintTop_toTopOf="@+id/guideline_top">
<include layout="@layout/v_loading_screen" />
diff --git a/app/src/main/res/layout/a_provider_detail_tablet_linear_layout.xml b/app/src/main/res/layout/a_provider_detail_tablet_linear_layout.xml
index 17006d9c..14400672 100644
--- a/app/src/main/res/layout/a_provider_detail_tablet_linear_layout.xml
+++ b/app/src/main/res/layout/a_provider_detail_tablet_linear_layout.xml
@@ -12,7 +12,6 @@
app:layout_constraintHeight_min="411dp"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toTopOf="@+id/guideline_top"
- app:layout_constraintWidth_min="731dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
diff --git a/app/src/main/res/layout/a_provider_list_tablet_linear_layout.xml b/app/src/main/res/layout/a_provider_list_tablet_linear_layout.xml
index 3c2b150d..107f25fb 100644
--- a/app/src/main/res/layout/a_provider_list_tablet_linear_layout.xml
+++ b/app/src/main/res/layout/a_provider_list_tablet_linear_layout.xml
@@ -11,7 +11,6 @@
app:layout_constraintHeight_min="411dp"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toTopOf="@+id/guideline_top"
- app:layout_constraintWidth_min="731dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
diff --git a/app/src/main/res/layout/f_eip.xml b/app/src/main/res/layout/f_eip.xml
index ed4ec9c4..960c6fca 100644
--- a/app/src/main/res/layout/f_eip.xml
+++ b/app/src/main/res/layout/f_eip.xml
@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/eipServiceFragment">
<android.support.constraint.Guideline
@@ -84,17 +85,21 @@
<android.support.v7.widget.AppCompatButton
android:id="@+id/vpn_main_button"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="32dp"
+ android:minWidth="150dp"
android:layout_marginBottom="@dimen/stdpadding"
android:layout_marginEnd="@dimen/stdpadding"
android:layout_marginStart="@dimen/stdpadding"
android:layout_marginTop="@dimen/stdpadding"
android:layout_marginLeft="@dimen/stdpadding"
android:layout_marginRight="@dimen/stdpadding"
+ android:paddingLeft="@dimen/stdpadding"
+ android:paddingRight="@dimen/stdpadding"
app:layout_constraintBottom_toBottomOf="@+id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="@string/vpn.button.turn.on"
+ tools:text="Turn on in another language"
style="@style/BitmaskButtonBlack"
/>
diff --git a/app/src/main/res/layout/v_icon_text_list_item.xml b/app/src/main/res/layout/v_icon_text_list_item.xml
new file mode 100644
index 00000000..0631b2fc
--- /dev/null
+++ b/app/src/main/res/layout/v_icon_text_list_item.xml
@@ -0,0 +1,31 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/item_container"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <ImageView
+ android:id="@+id/material_icon"
+ android:layout_width="?android:attr/listPreferredItemHeightSmall"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:layout_gravity="center"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ tools:src="@drawable/ic_add_circle_outline_grey600_24dp"
+ />
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ tools:text="TEST"
+ />
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/v_main_button.xml b/app/src/main/res/layout/v_main_button.xml
index ad1ac4ba..06504f3c 100644
--- a/app/src/main/res/layout/v_main_button.xml
+++ b/app/src/main/res/layout/v_main_button.xml
@@ -103,9 +103,9 @@
app:layout_constraintStart_toStartOf="@id/border_guideline_left"
app:layout_constraintTop_toTopOf="@id/border_guideline_top"
android:indeterminate="true"
- android:indeterminateDuration="2000"
+ android:indeterminateDuration="800"
android:indeterminateDrawable="@drawable/progressbar_circle"
- android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:interpolator="@android:anim/decelerate_interpolator"
android:indeterminateBehavior="cycle"
/>
diff --git a/app/src/main/res/layout/v_provider_credentials.xml b/app/src/main/res/layout/v_provider_credentials.xml
index 0bfdcc47..65f554aa 100644
--- a/app/src/main/res/layout/v_provider_credentials.xml
+++ b/app/src/main/res/layout/v_provider_credentials.xml
@@ -18,7 +18,7 @@
android:hint="@string/auth_username"
app:errorEnabled="true"
android:layout_marginTop="@dimen/standard_margin"
- >
+ app:errorTextAppearance="@style/error_appearance">
<android.support.design.widget.TextInputEditText
android:id="@+id/provider_credentials_username"
@@ -35,7 +35,8 @@
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:hint="@string/password"
- app:errorEnabled="true">
+ app:errorEnabled="true"
+ app:errorTextAppearance="@style/error_appearance">
<android.support.design.widget.TextInputEditText
android:id="@+id/provider_credentials_password"
@@ -53,7 +54,8 @@
app:passwordToggleEnabled="true"
android:hint="@string/password"
app:errorEnabled="true"
- android:visibility="gone">
+ android:visibility="gone"
+ app:errorTextAppearance="@style/error_appearance">
<android.support.design.widget.TextInputEditText
android:id="@+id/provider_credentials_password_verification"
diff --git a/app/src/main/res/layout/v_switch_list_item.xml b/app/src/main/res/layout/v_switch_list_item.xml
index bdb9a74c..26060a73 100644
--- a/app/src/main/res/layout/v_switch_list_item.xml
+++ b/app/src/main/res/layout/v_switch_list_item.xml
@@ -1,15 +1,48 @@
-<android.support.v7.widget.SwitchCompat xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- android:id="@android:id/text1"
+ android:id="@+id/item_container"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceListItemSmall"
- android:gravity="center_vertical"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingRight="?android:attr/listPreferredItemPaddingRight"
- android:background="?android:attr/activatedBackgroundIndicator"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:checked="false"
- tools:text="someOption" /> \ No newline at end of file
+ >
+
+ <ImageView
+ android:id="@+id/material_icon"
+ android:layout_width="?android:attr/listPreferredItemHeightSmall"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:layout_gravity="center"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ tools:src="@drawable/ic_add_circle_outline_grey600_24dp"
+ />
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ tools:text="TEST"
+ android:layout_toEndOf="@id/material_icon"
+ android:layout_toRightOf="@+id/material_icon"
+ />
+
+ <android.support.v7.widget.SwitchCompat
+ android:id="@+id/option_switch"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:checked="false"
+ tools:text="" />
+</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml
index ec877dc8..6dd93e3a 100644
--- a/app/src/main/res/values-sw600dp/dimens.xml
+++ b/app/src/main/res/values-sw600dp/dimens.xml
@@ -10,5 +10,6 @@
<dimen name="bitmask_logo_compact">56dp</dimen>
<dimen name="stdpadding">16dp</dimen>
<dimen name="compact_padding">6dp</dimen>
+ <dimen name="button_radius">20dp</dimen>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
index 9f36e474..50070e6d 100644
--- a/app/src/main/res/values-v21/styles.xml
+++ b/app/src/main/res/values-v21/styles.xml
@@ -26,15 +26,5 @@
<item name="android:colorAccent">@color/accent</item>
</style>
- <style name="BitmaskButton" parent="android:Widget.Button">
- <item name="android:textAllCaps">true</item>
- <item name="android:backgroundTint">@color/colorPrimary</item>
- </style>
-
- <style name="BitmaskButtonBlack" parent="android:Widget.Button">
- <item name="android:textAllCaps">true</item>
- <item name="android:backgroundTint">@color/black800</item>
- <item name="android:textColor">@color/white</item>
- </style>
</resources>
diff --git a/app/src/main/res/values-v21/themes.xml b/app/src/main/res/values-v21/themes.xml
index d6145217..0a426ced 100644
--- a/app/src/main/res/values-v21/themes.xml
+++ b/app/src/main/res/values-v21/themes.xml
@@ -17,7 +17,7 @@
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:colorPrimary">@color/colorPrimary</item>
- <item name="android:colorPrimaryDark">@color/colorPrimary</item>
+ <item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="android:windowBackground">@drawable/splash_page</item>
</style>
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
index 654ea948..94bd0ff2 100644
--- a/app/src/main/res/values-w820dp/dimens.xml
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -7,4 +7,6 @@
<dimen name="bitmask_logo_compact">56dp</dimen>
<dimen name="compact_padding">6dp</dimen>
<dimen name="stdpadding">16dp</dimen>
+ <dimen name="button_radius">20dp</dimen>
+
</resources>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 40ab06c5..d8873017 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,11 +2,16 @@
<resources>
<color name="colorPrimary">#b39ddb</color>
<color name="colorPrimaryDark">#ac97d2</color>
+ <color name="colorPrimary_transparent">#20000000</color>
<color name="colorBackground">#fffafafa</color>
<color name="colorError">#ef9a9a</color>
<color name="colorSuccess">#a5d6a7</color>
+ <color name="colorDisabled">#AAAAAA</color>
<color name="black800">#424242</color>
+ <color name="black800_secondary">#3b3b3b</color>
+ <color name="black800_transparent">#AA424242</color>
+ <color name="black800_high_transparent">#22424242</color>
<color name="red200">#ef9a9a</color>
<color name="pink200">#f48fb1</color>
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 338ad4d5..3adf6cf6 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -41,4 +41,6 @@
<dimen name="constraint_bottom_compact">0.9</dimen>
<dimen name="toast_bottom_padding">20dp</dimen>
+ <dimen name="button_bevel">3dp</dimen>
+ <dimen name="button_radius">16dp</dimen>
</resources> \ 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 ba4ef949..551b7cb1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -49,11 +49,11 @@
<string name="setup_error_title">Configuration Error</string>
<string name="setup_error_configure_button">Configure</string>
<string name="setup_error_close_button">Exit</string>
- <string name="setup_error_text">There was an error configuring Bitmask with your chosen provider.\n\nYou may choose to reconfigure, or exit and configure a provider upon next launch.</string>
+ <string name="setup_error_text">There was an error configuring %s with your chosen provider.\n\nYou may choose to reconfigure, or exit and configure a provider upon next launch.</string>
<string name="server_unreachable_message">The server is unreachable, please try again.</string>
<string name="error.security.pinnedcertificate">Security error, upgrade the app or choose another provider.</string>
- <string name="malformed_url">It doesn\'t seem to be a Bitmask provider.</string>
- <string name="certificate_error">This is not a trusted Bitmask provider.</string>
+ <string name="malformed_url">It doesn\'t seem to be a %s provider.</string>
+ <string name="certificate_error">This is not a trusted %s provider.</string>
<string name="service_is_down_error">The service is down.</string>
<string name="configuring_provider">Configuring provider</string>
<string name="incorrectly_downloaded_certificate_message">Your anonymous certificate was not downloaded</string>
@@ -72,29 +72,20 @@
<string name="provider_problem">It seems there is a problem with the provider.</string>
<string name="try_another_provider">Please try another provider, or contact yours.</string>
<string name="default_username">Anonymous</string>
- <string name="logged_in_user_status">is logged in.</string>
- <string name="logged_out_user_status">logged out.</string>
- <string name="didnt_log_out_user_status">didn\'t log out. Try later, it may be a problem in the network or with the provider. Should it persist, wipe the Bitmask data from the Android settings.</string>
- <string name="not_logged_in_user_status">have not logged in.</string>
- <string name="logging_in_user_status">is logging in.</string>
<string name="logging_in">Logging in</string>
<string name="signing_up">Signing up</string>
- <string name="logging_out_user_status">is logging out.</string>
- <string name="signingup_message">is being registered.</string>
<string name="vpn.button.turn.on">Turn on</string>
<string name="vpn.button.turn.off">Turn off</string>
<string name="vpn_button_turn_off_blocking">Stop blocking</string>
<string name="vpn_securely_routed">Your traffic is securely routed through:</string>
<string name="vpn_securely_routed_no_internet">No internet connection detected, when it comes back we\'ll route your traffic securely through:</string>
- <string name="bitmask_log">Bitmask Log</string>
- <string name="title_activity_main">Bitmask</string>
<string name="log_fragment_title">Log</string>
<string name="vpn_fragment_title">VPN</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
<string name="action_example">Example action</string>
<string name="action_settings">Settings</string>
- <string name="void_vpn_establish">Bitmask blocks all outgoing internet traffic.</string>
+ <string name="void_vpn_establish">%s blocks all outgoing internet traffic.</string>
<string name="void_vpn_error_establish">Failed to establish blocking VPN.</string>
<string name="void_vpn_stopped">Stopped blocking all outgoing internet traffic.</string>
<string name="void_vpn_title">Blocking traffic</string>
@@ -102,9 +93,9 @@
<string name="update_certificate">Update certificate</string>
<string name="warning_eip_json_corrupted">Updating provider configuration failed.</string>
<string name="eip_json_corrupted_user_message">Updating provider configuration failed. Please log in to try again.</string>
- <string name="warning_corrupted_provider_details">Stored provider details are corrupted. You can either update Bitmask (recommended) or update the provider details using a commercial CA certificate.</string>
- <string name="warning_corrupted_provider_cert">Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.</string>
- <string name="warning_expired_provider_cert">Stored provider certificate is expired. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.</string>
+ <string name="warning_corrupted_provider_details">Stored provider details are corrupted. You can either update %s (recommended) or update the provider details using a commercial CA certificate.</string>
+ <string name="warning_corrupted_provider_cert">Stored provider certificate is invalid. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.</string>
+ <string name="warning_expired_provider_cert">Stored provider certificate is expired. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.</string>
<string name="downloading_vpn_certificate_failed">Downloading the VPN certificate failed. Try again or choose another provider.</string>
<string name="vpn_certificate_is_invalid">VPN certificate is invalid. Try to download a new one.</string>
<string name="vpn_certificate_user_message">The VPN certificate is invalid. Please log in to download a new one.</string>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 4e845384..b8c0bc59 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -62,6 +62,9 @@
<style name="BitmaskButton" parent="android:Widget.Button">
<item name="android:textAllCaps">true</item>
+ <item name="android:background">@drawable/cust_button_primary</item>
+ <item name="android:height">36dp</item>
+ <item name="android:minWidth">75dp</item>
</style>
<style name="BitmaskActivity">
@@ -69,8 +72,14 @@
<style name="BitmaskButtonBlack" parent="android:Widget.Button">
<item name="android:textAllCaps">true</item>
- <item name="android:background">@color/black800</item>
+ <item name="android:background">@drawable/cust_button_primary_black</item>
<item name="android:textColor">@color/white</item>
+ <item name="android:textStyle">bold</item>
+ </style>
+
+ <style name="error_appearance" parent="@android:style/TextAppearance">
+ <item name="android:textColor">@color/colorError</item>
+ <item name="android:textSize">11sp</item>
</style>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index f3c55f41..51a8ea0e 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -2,7 +2,7 @@
<resources>
<style name="BitmaskTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
- <item name="colorPrimaryDark">@color/colorPrimary</item>
+ <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="textColorError">@color/colorError</item>
@@ -11,18 +11,13 @@
<!-- button and controls -->
<item name="android:buttonStyle">@style/BitmaskButton</item>
- <item name="colorButtonNormal">@color/colorPrimaryDark</item>
- <item name="colorControlHighlight">@color/colorPrimaryDark</item>
+ <item name="buttonStyle">@style/BitmaskButton</item>
</style>
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
- <item name="colorPrimaryDark">@color/colorPrimary</item>
+ <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="android:windowBackground">@drawable/splash_page</item>
</style>
- <style name="foo">
- <item name="textColorError">@color/colorPrimary</item>
- </style>
-
</resources>
diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml
index 07cca36e..a92cd176 100644
--- a/app/src/main/res/values/untranslatable.xml
+++ b/app/src/main/res/values/untranslatable.xml
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="notifcation_title_bitmask">%s - %s</string>
- <string name="copyright_leapgui" translatable="false">Copyright 2012-2018\nLEAP Encryption Access Project &lt;info@leap.se></string>
- <string name="opevpn_copyright" translatable="false">Copyright © 2002–2010 OpenVPN Technologies, Inc. &lt;sales@openvpn.net>\n
+ <string name="notifcation_title_bitmask" translatable="false">%s - %s</string>
+ <string name="copyright_leapgui" translatable="false">Copyright 2012-2019\nLEAP Encryption Access Project &lt;info@leap.se></string>
+ <string name="opevpn_copyright" translatable="false">Copyright © 2002–2019 OpenVPN Technologies, Inc. &lt;sales@openvpn.net>\n
"OpenVPN" is a trademark of OpenVPN Technologies, Inc.</string>
<string name="lzo_copyright" translatable="false">Copyright © 1996 – 2011 Markus Franz Xaver Johannes Oberhumer</string>
- <string name="copyright_openssl" translatable="false"> This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit\n
- Copyright © 1998-2008 The OpenSSL Project. All rights reserved.\n\n
+ <string name="copyright_openssl" translatable="false"> Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.\n\n
This product includes cryptographic software written by Eric Young (eay@cryptsoft.com)\n
Copyright © 1995-1998 Eric Young (eay@cryptsoft.com) All rights reserved.</string>
- <string name="copyright_okhttp" translatable="false">Copyright © 2016 Square, Inc.</string>
+ <string name="copyright_okhttp" translatable="false">Copyright © 2019 Square, Inc.</string>
<string name="okhttp" translatable="false">OkHttp</string>
<string name="openvpn" translatable="false">OpenVPN</string>
<string name="lzo" translatable="false">LZO</string>
@@ -18,18 +17,18 @@
<string name="copyright_mbetTLS" translatable="false">Unless specifically indicated otherwise in a file, files are licensed under the Apache 2.0 license, as can be found in: apache-2.0.txt. \n
https://github.com/schwabe/polarssl/blob/icsopenvpn_270/apache-2.0.txt
</string>
- <string name="asio">Asio</string>
- <string name="copyright_asio">Boost Software License - Version 1.0 - August 17th, 2003</string>
- <string name="openvpn3">OpenVPN 3</string>
- <string name="copyright_openvpn3">GNU AFFERO GENERAL PUBLIC LICENSE\n
+ <string name="asio" translatable="false">Asio</string>
+ <string name="copyright_asio" translatable="false">Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com).\n\nDistributed under the Boost Software License, Version 1.0.</string>
+ <string name="openvpn3" translatable="false">OpenVPN 3</string>
+ <string name="copyright_openvpn3" translatable="false">GNU AFFERO GENERAL PUBLIC LICENSE\n
Version 3, 19 November 2007</string>
<string name="unknown_state" translatable="false">Unknown state</string>
- <string name="copyright_blinktgui" translatable="false">Copyright 2012–2017 Arne Schwabe &lt;arne@rfc2549.org></string>
+ <string name="copyright_blinktgui" translatable="false">Copyright 2012–2019 Arne Schwabe &lt;arne@rfc2549.org></string>
<string name="defaultserver" translatable="false">openvpn.uni-paderborn.de</string>
<string name="defaultport" translatable="false">1194</string>
<string name="copyright_file_dialog" translatable="false">File Dialog based on work by Alexander Ponomarev</string>
<string name="file_dialog" translatable="false">File Dialog</string>
- <string name="permission_description">Allows another app to control OpenVPN</string>
+ <string name="permission_description" translatable="false">Allows another app to control OpenVPN</string>
<string name="bouncy_castle" translatable="false">Bouncy Castle Crypto APIs</string>
<string name="copyright_bouncycastle" translatable="false">Copyright © 2000–2012 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)</string>
<string name="state_user_vpn_permission" translatable="false">Waiting for user permission to use VPN API</string>
diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
index 1372fc43..6d9671b1 100644
--- a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
+++ b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
@@ -46,6 +46,7 @@ import static se.leap.bitmaskclient.R.string.malformed_url;
import static se.leap.bitmaskclient.R.string.setup_error_text;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details;
+import static se.leap.bitmaskclient.utils.ConfigHelper.getProviderFormattedString;
/**
* Implements the logic of the provider api http requests. The methods of this class need to be called from
@@ -248,7 +249,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
try {
// try to download with provider CA on certificate error
JSONObject responseErrorJson = new JSONObject(responseString);
- if (responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) {
+ if (responseErrorJson.getString(ERRORS).equals(getProviderFormattedString(resources, R.string.certificate_error))) {
responseString = downloadWithProviderCA(provider.getCaCert(), stringUrl);
}
} catch (JSONException e) {
diff --git a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
index c765ab1b..fa9f9252 100644
--- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
+++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
@@ -46,6 +46,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
@@ -373,6 +374,7 @@ public class MockHelper {
when(ConfigHelper.getFingerprintFromCertificate(any(X509Certificate.class), anyString())).thenReturn(mockedFingerprint);
when(ConfigHelper.checkErroneousDownload(anyString())).thenCallRealMethod();
when(ConfigHelper.parseX509CertificateFromString(anyString())).thenCallRealMethod();
+ when(ConfigHelper.getProviderFormattedString(any(Resources.class), anyInt())).thenCallRealMethod();
}
public static void mockPreferenceHelper(final Provider providerFromPrefs) {
@@ -402,6 +404,7 @@ public class MockHelper {
when(ConfigHelper.getFingerprintFromCertificate(any(X509Certificate.class), anyString())).thenReturn(mockedFingerprint);
when(ConfigHelper.checkErroneousDownload(anyString())).thenCallRealMethod();
when(ConfigHelper.parseX509CertificateFromString(anyString())).thenCallRealMethod();
+ when(ConfigHelper.getProviderFormattedString(any(Resources.class), anyInt())).thenCallRealMethod();
}
public static void mockProviderApiConnector(final BackendMockProvider.TestBackendErrorCase errorCase) throws IOException {
@@ -421,16 +424,16 @@ public class MockHelper {
JSONObject errorMessages = new JSONObject(TestSetupHelper.getInputAsString(inputStream));
- when(mockedResources.getString(R.string.warning_corrupted_provider_details)).
- thenReturn(errorMessages.getString("warning_corrupted_provider_details"));
+ when(mockedResources.getString(eq(R.string.warning_corrupted_provider_details), anyString())).
+ thenReturn(String.format(errorMessages.getString("warning_corrupted_provider_details"), "Bitmask"));
when(mockedResources.getString(R.string.server_unreachable_message)).
thenReturn(errorMessages.getString("server_unreachable_message"));
when(mockedResources.getString(R.string.error_security_pinnedcertificate)).
thenReturn(errorMessages.getString("error.security.pinnedcertificate"));
- when(mockedResources.getString(R.string.malformed_url)).
- thenReturn(errorMessages.getString("malformed_url"));
- when(mockedResources.getString(R.string.certificate_error)).
- thenReturn(errorMessages.getString("certificate_error"));
+ when(mockedResources.getString(eq(R.string.malformed_url), anyString())).
+ thenReturn(String.format(errorMessages.getString("malformed_url"), "Bitmask"));
+ when(mockedResources.getString(eq(R.string.certificate_error), anyString())).
+ thenReturn(String.format(errorMessages.getString("certificate_error"), "Bitmask"));
when(mockedResources.getString(R.string.error_srp_math_error_user_message)).
thenReturn(errorMessages.getString("error_srp_math_error_user_message"));
when(mockedResources.getString(R.string.error_bad_user_password_user_message)).
@@ -445,14 +448,16 @@ public class MockHelper {
thenReturn(errorMessages.getString("error_json_exception_user_message"));
when(mockedResources.getString(R.string.error_no_such_algorithm_exception_user_message)).
thenReturn(errorMessages.getString("error_no_such_algorithm_exception_user_message"));
- when(mockedResources.getString(R.string.warning_corrupted_provider_details)).
- thenReturn(errorMessages.getString("warning_corrupted_provider_details"));
- when(mockedResources.getString(R.string.warning_corrupted_provider_cert)).
- thenReturn(errorMessages.getString("warning_corrupted_provider_cert"));
- when(mockedResources.getString(R.string.warning_expired_provider_cert)).
- thenReturn(errorMessages.getString("warning_expired_provider_cert"));
- when(mockedResources.getString(R.string.setup_error_text)).
- thenReturn(errorMessages.getString("setup_error_text"));
+ when(mockedResources.getString(eq(R.string.warning_corrupted_provider_details), anyString())).
+ thenReturn(String.format(errorMessages.getString("warning_corrupted_provider_details"), "Bitmask"));
+ when(mockedResources.getString(eq(R.string.warning_corrupted_provider_cert), anyString())).
+ thenReturn(String.format(errorMessages.getString("warning_corrupted_provider_cert"), "Bitmask"));
+ when(mockedResources.getString(eq(R.string.warning_expired_provider_cert), anyString())).
+ thenReturn(String.format(errorMessages.getString("warning_expired_provider_cert"), "Bitmask"));
+ when(mockedResources.getString(eq(R.string.setup_error_text), anyString())).
+ thenReturn(String.format(errorMessages.getString("setup_error_text"), "Bitmask"));
+ when(mockedResources.getString(R.string.app_name)).
+ thenReturn("Bitmask");
return mockedResources;
}
}
diff --git a/app/src/test/resources/error_messages.json b/app/src/test/resources/error_messages.json
index 8430d9e0..e3b92d78 100644
--- a/app/src/test/resources/error_messages.json
+++ b/app/src/test/resources/error_messages.json
@@ -1,8 +1,8 @@
{
"server_unreachable_message": "Server is unreachable, please try again.",
"error.security.pinnedcertificate": "Security error, update the app or choose another provider.",
- "malformed_url": "It doesn't seem to be a Bitmask provider.",
- "certificate_error": "This is not a trusted Bitmask provider.",
+ "malformed_url": "It doesn't seem to be a %s provider.",
+ "certificate_error": "This is not a trusted %s provider.",
"error_srp_math_error_user_message": "Try again: server math error.",
"error_bad_user_password_user_message": "Incorrect username or password.",
"error_not_valid_password_user_message": "It should have at least 8 characters.",
@@ -10,8 +10,8 @@
"error_io_exception_user_message": "Try again: I/O error",
"error_json_exception_user_message": "Try again: Bad response from the server",
"error_no_such_algorithm_exception_user_message": "Encryption algorithm not found. Please update your OS!",
- "warning_corrupted_provider_details": "Stored provider details are corrupted. You can either update Bitmask (recommended) or update the provider details using a commercial CA certificate.",
- "warning_corrupted_provider_cert": "Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.",
- "warning_expired_provider_cert": "Stored provider certificate is expired. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.",
- "setup_error_text": "There was an error configuring Bitmask with your chosen provider."
+ "warning_corrupted_provider_details": "Stored provider details are corrupted. You can either update %s (recommended) or update the provider details using a commercial CA certificate.",
+ "warning_corrupted_provider_cert": "Stored provider certificate is invalid. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.",
+ "warning_expired_provider_cert": "Stored provider certificate is expired. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.",
+ "setup_error_text": "There was an error configuring %s with your chosen provider."
} \ No newline at end of file