summaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Constants.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipFragment.java180
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivity.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/StartActivity.java17
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java10
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java23
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/views/VpnStateImage.java83
-rw-r--r--app/src/main/res/drawable/progressbar_circle.xml83
-rw-r--r--app/src/main/res/layout-xlarge/eip_service_fragment.xml33
-rw-r--r--app/src/main/res/layout/eip_service_fragment.xml45
-rw-r--r--app/src/main/res/layout/v_main_button.xml132
-rw-r--r--app/src/main/res/values/dimens.xml1
12 files changed, 434 insertions, 180 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java
index 12b56b93..2b7a8113 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Constants.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java
@@ -44,6 +44,7 @@ public interface Constants {
String EIP_REQUEST = "EIP.REQUEST";
String EIP_RESTART_ON_BOOT = "EIP.RESTART_ON_BOOT";
String EIP_IS_ALWAYS_ON = "EIP.EIP_IS_ALWAYS_ON";
+ String EIP_EARLY_ROUTES = "EIP.EARLY_ROUTES";
//////////////////////////////////////////////
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
index 5adb732a..fb57aea8 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
@@ -48,6 +48,8 @@ import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
import de.blinkt.openvpn.core.OpenVPNService;
import se.leap.bitmaskclient.eip.EipCommand;
import se.leap.bitmaskclient.eip.EipStatus;
+import se.leap.bitmaskclient.eip.VoidVpnService;
+import se.leap.bitmaskclient.views.VpnStateImage;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
@@ -75,11 +77,8 @@ public class EipFragment extends Fragment implements Observer {
@InjectView(R.id.background)
AppCompatImageView background;
- @InjectView(R.id.key)
- AppCompatImageView key;
-
- @InjectView(R.id.cirle)
- AppCompatImageView circle;
+ @InjectView(R.id.vpn_state_image)
+ VpnStateImage vpnStateImage;
@InjectView(R.id.vpn_main_button)
Button mainButton;
@@ -225,13 +224,8 @@ public class EipFragment extends Fragment implements Observer {
handleIcon();
}
- @OnClick(R.id.key)
- void onKeyClick() {
- handleIcon();
- }
-
- @OnClick(R.id.cirle)
- void onCircleClick() {
+ @OnClick(R.id.vpn_state_image)
+ void onVpnStateImageClick() {
handleIcon();
}
@@ -282,11 +276,15 @@ public class EipFragment extends Fragment implements Observer {
public void startEipFromScratch() {
saveStatus(true);
Context context = getContext();
- if (context != null) {
- EipCommand.startVPN(context);
- } else {
+ if (context == null) {
Log.e(TAG, "context is null when trying to start VPN");
+ return;
}
+ EipCommand.startVPN(context, false);
+ vpnStateImage.showProgress();
+ routedText.setVisibility(GONE);
+ vpnRoute.setVisibility(GONE);
+ colorBackgroundALittle();
}
protected void stopEipIfPossible() {
@@ -300,58 +298,60 @@ public class EipFragment extends Fragment implements Observer {
private void askPendingStartCancellation() {
Activity activity = getActivity();
- if (activity != null) {
- AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
- showPendingStartCancellation = true;
- alertDialog = alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title))
- .setMessage(activity.getString(R.string.eip_cancel_connect_text))
- .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- stopEipIfPossible();
- }
- })
- .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- }
- }).setOnDismissListener(new DialogInterface.OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- showPendingStartCancellation = false;
- }
- }).show();
- } else {
+ if (activity == null) {
Log.e(TAG, "activity is null when asking to cancel");
+ return;
}
+
+ AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
+ showPendingStartCancellation = true;
+ alertDialog = alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title))
+ .setMessage(activity.getString(R.string.eip_cancel_connect_text))
+ .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ stopEipIfPossible();
+ }
+ })
+ .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ }).setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ showPendingStartCancellation = false;
+ }
+ }).show();
+
}
protected void askToStopEIP() {
Activity activity = getActivity();
- if (activity != null) {
- AlertDialog.Builder alertBuilder = new AlertDialog.Builder(activity);
- showAskToStopEip = true;
- alertDialog = alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title))
- .setMessage(activity.getString(R.string.eip_warning_browser_inconsistency))
- .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- stopEipIfPossible();
- }
- })
- .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- }
- }).setOnDismissListener(new DialogInterface.OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- showAskToStopEip = false;
- }
- }).show();
- } else {
+ if (activity == null) {
Log.e(TAG, "activity is null when asking to stop EIP");
+ return;
}
+ AlertDialog.Builder alertBuilder = new AlertDialog.Builder(activity);
+ showAskToStopEip = true;
+ alertDialog = alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title))
+ .setMessage(activity.getString(R.string.eip_warning_browser_inconsistency))
+ .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ stopEipIfPossible();
+ }
+ })
+ .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ }).setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ showAskToStopEip = false;
+ }
+ }).show();
}
@Override
@@ -374,29 +374,33 @@ public class EipFragment extends Fragment implements Observer {
private void handleNewState() {
Activity activity = getActivity();
- if (activity != null) {
- if (eipStatus.isConnecting()) {
- mainButton.setText(activity.getString(android.R.string.cancel));
- key.setImageResource(R.drawable.vpn_connecting);
- routedText.setVisibility(GONE);
- vpnRoute.setVisibility(GONE);
- colorBackgroundALittle();
- } else if (eipStatus.isConnected() || isOpenVpnRunningWithoutNetwork()) {
- mainButton.setText(activity.getString(R.string.vpn_button_turn_off));
- key.setImageResource(R.drawable.vpn_connected);
- routedText.setVisibility(VISIBLE);
- vpnRoute.setVisibility(VISIBLE);
- vpnRoute.setText(ConfigHelper.getProviderName(preferences));
- colorBackground();
- } else {
- mainButton.setText(activity.getString(R.string.vpn_button_turn_on));
- key.setImageResource(R.drawable.vpn_disconnected);
- routedText.setVisibility(GONE);
- vpnRoute.setVisibility(GONE);
- greyscaleBackground();
- }
- } else {
+ if (activity == null) {
Log.e(TAG, "activity is null while trying to handle new state");
+ return;
+ }
+
+ if (eipStatus.isConnecting()) {
+ mainButton.setText(activity.getString(android.R.string.cancel));
+ vpnStateImage.setStateIcon(R.drawable.vpn_connecting);
+ vpnStateImage.showProgress();
+ routedText.setVisibility(GONE);
+ vpnRoute.setVisibility(GONE);
+ colorBackgroundALittle();
+ } else if (eipStatus.isConnected() || isOpenVpnRunningWithoutNetwork()) {
+ mainButton.setText(activity.getString(R.string.vpn_button_turn_off));
+ vpnStateImage.setStateIcon(R.drawable.vpn_connected);
+ vpnStateImage.stopProgress(true);
+ routedText.setVisibility(VISIBLE);
+ vpnRoute.setVisibility(VISIBLE);
+ vpnRoute.setText(ConfigHelper.getProviderName(preferences));
+ colorBackground();
+ } else {
+ mainButton.setText(activity.getString(R.string.vpn_button_turn_on));
+ vpnStateImage.setStateIcon(R.drawable.vpn_disconnected);
+ vpnStateImage.stopProgress(false);
+ routedText.setVisibility(GONE);
+ vpnRoute.setVisibility(GONE);
+ greyscaleBackground();
}
}
@@ -415,13 +419,15 @@ public class EipFragment extends Fragment implements Observer {
private void bindOpenVpnService() {
Activity activity = getActivity();
- if (activity != null) {
- Intent intent = new Intent(activity, OpenVPNService.class);
- intent.setAction(OpenVPNService.START_SERVICE);
- activity.bindService(intent, openVpnConnection, Context.BIND_AUTO_CREATE);
- } else {
+ if (activity == null) {
Log.e(TAG, "activity is null when binding OpenVpn");
+ return;
}
+
+ Intent intent = new Intent(activity, OpenVPNService.class);
+ intent.setAction(OpenVPNService.START_SERVICE);
+ activity.bindService(intent, openVpnConnection, Context.BIND_AUTO_CREATE);
+
}
private void greyscaleBackground() {
@@ -439,7 +445,7 @@ public class EipFragment extends Fragment implements Observer {
private void colorBackground() {
background.setColorFilter(null);
- background.setImageAlpha(255);
+ background.setImageAlpha(210);
}
private void downloadVpnCertificate() {
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
index 91b7f66c..6e778309 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
@@ -194,7 +194,7 @@ public class MainActivity extends AppCompatActivity implements Observer {
case REQUEST_CODE_CONFIGURE_LEAP:
break;
case REQUEST_CODE_LOG_IN:
- EipCommand.startVPN(this);
+ EipCommand.startVPN(this, true);
break;
}
}
@@ -303,7 +303,7 @@ public class MainActivity extends AppCompatActivity implements Observer {
switch (resultCode) {
case CORRECTLY_DOWNLOADED_EIP_SERVICE:
provider = resultData.getParcelable(PROVIDER_KEY);
- EipCommand.startVPN(this);
+ EipCommand.startVPN(this, true);
break;
case INCORRECTLY_DOWNLOADED_EIP_SERVICE:
// TODO CATCH ME IF YOU CAN - WHAT DO WE WANT TO DO?
@@ -312,7 +312,7 @@ public class MainActivity extends AppCompatActivity implements Observer {
case CORRECTLY_DOWNLOADED_VPN_CERTIFICATE:
provider = resultData.getParcelable(PROVIDER_KEY);
ConfigHelper.storeProviderInPreferences(preferences, provider);
- EipCommand.startVPN(this);
+ EipCommand.startVPN(this, true);
break;
case INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE:
if (LeapSRPSession.loggedIn() || provider.allowsAnonymous()) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
index 288b157f..39717bd8 100644
--- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
@@ -14,6 +14,7 @@ import java.lang.annotation.RetentionPolicy;
import de.blinkt.openvpn.core.VpnStatus;
import se.leap.bitmaskclient.eip.EIP;
+import se.leap.bitmaskclient.eip.EipCommand;
import se.leap.bitmaskclient.userstatus.User;
import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE;
@@ -163,7 +164,7 @@ public class StartActivity extends Activity {
} else {
Log.d(TAG, "vpn provider is configured");
if (getIntent() != null && getIntent().getBooleanExtra(EIP_RESTART_ON_BOOT, false)) {
- eipCommand(EIP_ACTION_START);
+ EipCommand.startVPN(this, true);
finish();
return;
}
@@ -191,7 +192,7 @@ public class StartActivity extends Activity {
if (resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) {
Provider provider = data.getParcelableExtra(Provider.KEY);
ConfigHelper.storeProviderInPreferences(preferences, provider);
- eipCommand(EIP_ACTION_START);
+ EipCommand.startVPN(this, false);
showMainActivity();
} else if (resultCode == RESULT_CANCELED) {
finish();
@@ -207,16 +208,4 @@ public class StartActivity extends Activity {
finish();
}
-
- /**
- * Send a command to EIP
- *
- * @param action A valid String constant from EIP class representing an Intent
- * filter for the EIP class
- */
- private void eipCommand(String action) {
- Intent vpn_intent = new Intent(this.getApplicationContext(), EIP.class);
- vpn_intent.setAction(action);
- this.startService(vpn_intent);
- }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
index 88047f55..cbce1a81 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -43,6 +43,7 @@ import static se.leap.bitmaskclient.Constants.EIP_ACTION_IS_RUNNING;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_ALWAYS_ON_VPN;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP;
+import static se.leap.bitmaskclient.Constants.EIP_EARLY_ROUTES;
import static se.leap.bitmaskclient.Constants.EIP_RECEIVER;
import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
@@ -95,7 +96,8 @@ public final class EIP extends IntentService {
switch (action) {
case EIP_ACTION_START:
- startEIP();
+ boolean earlyRoutes = intent.getBooleanExtra(EIP_EARLY_ROUTES, true);
+ startEIP(earlyRoutes);
break;
case EIP_ACTION_START_ALWAYS_ON_VPN:
startEIPAlwaysOnVpn();
@@ -117,8 +119,8 @@ public final class EIP extends IntentService {
* Intent to {@link de.blinkt.openvpn.LaunchVPN}.
* It also sets up early routes.
*/
- private void startEIP() {
- if (!EipStatus.getInstance().isBlockingVpnEstablished()) {
+ private void startEIP(boolean earlyRoutes) {
+ if (!EipStatus.getInstance().isBlockingVpnEstablished() && earlyRoutes) {
earlyRoutes();
}
@@ -181,7 +183,7 @@ public final class EIP extends IntentService {
}
private void stopEIP() {
- // TODO try to do anything! stop eip from here if possible...
+ // TODO stop eip from here if possible...
EipStatus eipStatus = EipStatus.getInstance();
int resultCode = RESULT_CANCELED;
if (eipStatus.isConnected() || eipStatus.isConnecting())
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
index aa06b462..d2c8b4fc 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
@@ -1,5 +1,6 @@
package se.leap.bitmaskclient.eip;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.ResultReceiver;
@@ -11,6 +12,7 @@ import org.jetbrains.annotations.Nullable;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP;
+import static se.leap.bitmaskclient.Constants.EIP_EARLY_ROUTES;
import static se.leap.bitmaskclient.Constants.EIP_RECEIVER;
/**
@@ -20,7 +22,7 @@ import static se.leap.bitmaskclient.Constants.EIP_RECEIVER;
public class EipCommand {
public static void execute(@NotNull Context context, @NotNull String action) {
- execute(context, action, null);
+ execute(context, action, null, null);
}
/**
@@ -30,21 +32,26 @@ public class EipCommand {
* filter for the EIP class
* @param resultReceiver The resultreceiver to reply to
*/
- public static void execute(@NotNull Context context, @NotNull String action, @Nullable ResultReceiver resultReceiver) {
+ public static void execute(@NotNull Context context, @NotNull String action, @Nullable ResultReceiver resultReceiver, @Nullable Intent vpnIntent) {
// TODO validate "action"...how do we get the list of intent-filters for a class via Android API?
- Intent vpnIntent = new Intent(context.getApplicationContext(), EIP.class);
+ if (vpnIntent == null) {
+ vpnIntent = new Intent();
+ }
+ vpnIntent.setComponent(new ComponentName(context.getApplicationContext(), EIP.class));
vpnIntent.setAction(action);
if (resultReceiver != null)
vpnIntent.putExtra(EIP_RECEIVER, resultReceiver);
context.startService(vpnIntent);
}
- public static void startVPN(@NonNull Context context) {
- execute(context, EIP_ACTION_START);
+ public static void startVPN(@NonNull Context context, boolean earlyRoutes) {
+ Intent baseIntent = new Intent();
+ baseIntent.putExtra(EIP_EARLY_ROUTES, earlyRoutes);
+ execute(context, EIP_ACTION_START, null, baseIntent);
}
public static void startVPN(@NonNull Context context, ResultReceiver resultReceiver) {
- execute(context, EIP_ACTION_START, resultReceiver);
+ execute(context, EIP_ACTION_START, resultReceiver, null);
}
public static void stopVPN(@NonNull Context context) {
@@ -52,7 +59,7 @@ public class EipCommand {
}
public static void stopVPN(@NonNull Context context, ResultReceiver resultReceiver) {
- execute(context, EIP_ACTION_STOP, resultReceiver);
+ execute(context, EIP_ACTION_STOP, resultReceiver, null);
}
public static void checkVpnCertificate(@NonNull Context context) {
@@ -60,7 +67,7 @@ public class EipCommand {
}
public static void checkVpnCertificate(@NonNull Context context, ResultReceiver resultReceiver) {
- execute(context, EIP_ACTION_CHECK_CERT_VALIDITY, resultReceiver);
+ execute(context, EIP_ACTION_CHECK_CERT_VALIDITY, resultReceiver, null);
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/views/VpnStateImage.java b/app/src/main/java/se/leap/bitmaskclient/views/VpnStateImage.java
new file mode 100644
index 00000000..2efd83d6
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/views/VpnStateImage.java
@@ -0,0 +1,83 @@
+package se.leap.bitmaskclient.views;
+
+import android.content.Context;
+import android.support.constraint.ConstraintLayout;
+import android.support.v7.widget.AppCompatImageView;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.widget.ProgressBar;
+
+import se.leap.bitmaskclient.R;
+
+/**
+ * Created by cyberta on 12.02.18.
+ */
+
+
+public class VpnStateImage extends ConstraintLayout {
+
+ ProgressBar progressBar;
+ AppCompatImageView stateIcon;
+
+ public VpnStateImage(Context context) {
+ super(context);
+ initLayout(context);
+ }
+
+ public VpnStateImage(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initLayout(context);
+ }
+
+ public VpnStateImage(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initLayout(context);
+ }
+
+ void initLayout(Context context) {
+ LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View rootview = inflater.inflate(R.layout.v_main_button, this, true);
+ stateIcon = rootview.findViewById(R.id.vpn_state_key);
+ progressBar = rootview.findViewById(R.id.progressBar);
+ progressBar.setIndeterminate(true);
+ }
+
+ public void showProgress() {
+ progressBar.setVisibility(VISIBLE);
+ }
+
+
+ public void stopProgress(boolean animated) {
+ if (!animated) {
+ progressBar.setVisibility(GONE);
+ return;
+ }
+
+ AlphaAnimation fadeOutAnimation = new AlphaAnimation(1.0f, 0.0f);
+ fadeOutAnimation.setDuration(1000);
+ fadeOutAnimation.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {}
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ progressBar.setVisibility(GONE);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {}
+ });
+
+ progressBar.startAnimation(fadeOutAnimation);
+ }
+
+ public void setStateIcon(int resource) {
+ stateIcon.setImageResource(resource);
+ }
+
+
+}
diff --git a/app/src/main/res/drawable/progressbar_circle.xml b/app/src/main/res/drawable/progressbar_circle.xml
new file mode 100644
index 00000000..6257e3af
--- /dev/null
+++ b/app/src/main/res/drawable/progressbar_circle.xml
@@ -0,0 +1,83 @@
+<?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">
+ <shape
+ android:shape="ring"
+ android:useLevel="true">
+ <gradient
+ android:endColor="#00ce93d8"
+ android:centerColor="#ce93d8"
+ android:startColor="#00ce93d8"
+ android:type="sweep"
+ />
+ </shape>
+ </rotate>
+ </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-xlarge/eip_service_fragment.xml b/app/src/main/res/layout-xlarge/eip_service_fragment.xml
index 497d2c0b..b7af5797 100644
--- a/app/src/main/res/layout-xlarge/eip_service_fragment.xml
+++ b/app/src/main/res/layout-xlarge/eip_service_fragment.xml
@@ -69,41 +69,16 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
- <android.support.v7.widget.AppCompatImageView
- android:id="@+id/cirle"
+ <se.leap.bitmaskclient.views.VpnStateImage
+ android:id="@+id/vpn_state_image"
android:layout_width="0dp"
android:layout_height="0dp"
- 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:layout_margin="@dimen/stdpadding"
app:layout_constraintBottom_toTopOf="@+id/guideline_horizontal_bottom"
app:layout_constraintEnd_toStartOf="@+id/guideline_vertical_right"
- app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/guideline_vertical_left"
app:layout_constraintTop_toTopOf="@+id/guideline_horizontal_top"
- app:layout_constraintVertical_bias="0.0"
- app:srcCompat="@drawable/black_circle" />
-
- <android.support.v7.widget.AppCompatImageView
- android:id="@+id/key"
- android:layout_width="0dp"
- android:layout_height="0dp"
- 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"
- app:layout_constraintBottom_toBottomOf="@+id/cirle"
- app:layout_constraintEnd_toEndOf="@+id/cirle"
- app:layout_constraintStart_toStartOf="@+id/cirle"
- app:layout_constraintTop_toTopOf="@+id/cirle"
- app:srcCompat="@drawable/vpn_connected" />
-
+ app:layout_constraintDimensionRatio="1:1" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/vpn_main_button"
diff --git a/app/src/main/res/layout/eip_service_fragment.xml b/app/src/main/res/layout/eip_service_fragment.xml
index 497d2c0b..814ec310 100644
--- a/app/src/main/res/layout/eip_service_fragment.xml
+++ b/app/src/main/res/layout/eip_service_fragment.xml
@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:id="@+id/eipServiceFragment"
- >
+ android:id="@+id/eipServiceFragment">
<android.support.constraint.Guideline
android:id="@+id/guideline_horizontal_top"
@@ -14,7 +12,7 @@
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintGuide_percent="0.3"
+ app:layout_constraintGuide_percent="0.225"
/>
<android.support.constraint.Guideline
@@ -23,7 +21,7 @@
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintGuide_percent="0.3"
+ app:layout_constraintGuide_percent="0.225"
/>
@@ -34,7 +32,7 @@
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintGuide_percent="0.7"
+ app:layout_constraintGuide_percent="0.775"
/>
<android.support.constraint.Guideline
@@ -43,7 +41,7 @@
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintGuide_percent="0.7"
+ app:layout_constraintGuide_percent="0.775"
/>
<android.support.v7.widget.AppCompatImageView
@@ -70,40 +68,17 @@
app:layout_constraintTop_toTopOf="parent" />
- <android.support.v7.widget.AppCompatImageView
- android:id="@+id/cirle"
+ <se.leap.bitmaskclient.views.VpnStateImage
+ android:id="@+id/vpn_state_image"
android:layout_width="0dp"
android:layout_height="0dp"
- 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:layout_margin="@dimen/stdpadding"
app:layout_constraintBottom_toTopOf="@+id/guideline_horizontal_bottom"
app:layout_constraintEnd_toStartOf="@+id/guideline_vertical_right"
- app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/guideline_vertical_left"
app:layout_constraintTop_toTopOf="@+id/guideline_horizontal_top"
- app:layout_constraintVertical_bias="0.0"
- app:srcCompat="@drawable/black_circle" />
-
- <android.support.v7.widget.AppCompatImageView
- android:id="@+id/key"
- android:layout_width="0dp"
- android:layout_height="0dp"
- 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"
- app:layout_constraintBottom_toBottomOf="@+id/cirle"
- app:layout_constraintEnd_toEndOf="@+id/cirle"
- app:layout_constraintStart_toStartOf="@+id/cirle"
- app:layout_constraintTop_toTopOf="@+id/cirle"
- app:srcCompat="@drawable/vpn_connected" />
-
+ app:layout_constraintDimensionRatio="1:1"
+ />
<android.support.v7.widget.AppCompatButton
android:id="@+id/vpn_main_button"
diff --git a/app/src/main/res/layout/v_main_button.xml b/app/src/main/res/layout/v_main_button.xml
new file mode 100644
index 00000000..ad1ac4ba
--- /dev/null
+++ b/app/src/main/res/layout/v_main_button.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+
+ <android.support.constraint.Guideline
+ android:id="@+id/vpn_btn_guideline_left"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_percent="0.125" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/vpn_btn_guideline_right"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_percent="0.875" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/vpn_btn_guideline_top"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.125" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/vpn_btn_guideline_bottom"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.875" />
+
+
+ <android.support.constraint.Guideline
+ android:id="@+id/icn_guideline_left"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_percent="0.2" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/icn_guideline_right"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_percent="0.8" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/icn_guideline_top"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.2" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/icn_guideline_bottom"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.8" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/border_guideline_left"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_percent="0.025" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/border_guideline_right"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_percent="0.975" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/border_guideline_top"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.025" />
+
+ <android.support.constraint.Guideline
+ android:id="@+id/border_guideline_bottom"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.975" />
+
+
+ <ProgressBar
+ android:id="@+id/progressBar"
+ style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toBottomOf="@id/border_guideline_bottom"
+ app:layout_constraintEnd_toEndOf="@id/border_guideline_right"
+ app:layout_constraintStart_toStartOf="@id/border_guideline_left"
+ app:layout_constraintTop_toTopOf="@id/border_guideline_top"
+ android:indeterminate="true"
+ android:indeterminateDuration="2000"
+ android:indeterminateDrawable="@drawable/progressbar_circle"
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:indeterminateBehavior="cycle"
+ />
+
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/circle"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toTopOf="@+id/vpn_btn_guideline_bottom"
+ app:layout_constraintEnd_toStartOf="@+id/vpn_btn_guideline_right"
+ app:layout_constraintStart_toStartOf="@+id/vpn_btn_guideline_left"
+ app:layout_constraintTop_toTopOf="@+id/vpn_btn_guideline_top"
+ app:srcCompat="@drawable/black_circle" />
+
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/vpn_state_key"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toTopOf="@id/icn_guideline_bottom"
+ app:layout_constraintEnd_toStartOf="@id/icn_guideline_right"
+ app:layout_constraintStart_toStartOf="@id/icn_guideline_left"
+ app:layout_constraintTop_toTopOf="@id/icn_guideline_top"
+ app:srcCompat="@drawable/vpn_connected" />
+
+</android.support.constraint.ConstraintLayout> \ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 87d8e266..f160487b 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -7,6 +7,7 @@
<dimen name="paddingItemsSidebarLog">20dp</dimen>
<dimen name="stdpadding">8dp</dimen>
<dimen name="standard_margin">8dp</dimen>
+ <dimen name="mainbutton_padding">20dp</dimen>
<bool name="logSildersAlwaysVisible">false</bool>
<dimen name="diameter">48dp</dimen>