diff options
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> |