diff options
Diffstat (limited to 'app/src')
18 files changed, 422 insertions, 172 deletions
| diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestVpnFragment.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEipFragment.java index 564e251c..4227f19a 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestVpnFragment.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEipFragment.java @@ -1,6 +1,6 @@  package se.leap.bitmaskclient.test; -public class TestVpnFragment extends BaseTestDashboardFragment { +public class TestEipFragment extends BaseTestDashboardFragment {      /**       * This test will fail if Android does not trust VPN connection. diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java index 3713e198..741a6f56 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java @@ -304,6 +304,8 @@ public class ConfigHelper {              } catch (JSONException e2) {                  return null;              } +        } catch (NullPointerException npe) { +            return null;          }      } @@ -322,7 +324,7 @@ public class ConfigHelper {          try {              JSONObject providerJson = new JSONObject(provider);              return providerJson.getString(Provider.DOMAIN); -        } catch (JSONException e) { +        } catch (JSONException | NullPointerException e) {              return null;          }      } diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index cb781009..a4db5f84 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -87,7 +87,7 @@ public class Dashboard extends ButterKnifeActivity {      @InjectView(R.id.providerName)      TextView provider_name; -    private VpnFragment eip_fragment; +    private EipFragment eip_fragment;      private UserStatusFragment user_status_fragment;      private static Provider provider = new Provider(); @@ -290,8 +290,8 @@ public class Dashboard extends ButterKnifeActivity {       * Inflates permanent UI elements of the View and contains logic for what       * service dependent UI elements to include.       */ -    //TODO: REFACTOR ME! Consider implementing a manager that handles most of VpnFragment's logic about handling EIP commands. -    //This way, we could avoid to create UI elements (like fragmentManager.replace(R.id.servicesCollection, eip_fragment, VpnFragment.TAG); ) +    //TODO: REFACTOR ME! Consider implementing a manager that handles most of EipFragment's logic about handling EIP commands. +    //This way, we could avoid to create UI elements (like fragmentManager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG); )      // just to start services and destroy them afterwards      private void buildDashboard(boolean hideAndTurnOnEipOnBoot) {          setContentView(R.layout.dashboard); @@ -305,9 +305,9 @@ public class Dashboard extends ButterKnifeActivity {          fragment_manager.replace(R.id.user_status_fragment, user_status_fragment, UserStatusFragment.TAG);          if (provider.hasEIP()) { -            fragment_manager.removePreviousFragment(VpnFragment.TAG); +            fragment_manager.removePreviousFragment(EipFragment.TAG);              eip_fragment = prepareEipFragment(hideAndTurnOnEipOnBoot); -            fragment_manager.replace(R.id.servicesCollection, eip_fragment, VpnFragment.TAG); +            fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG);              if (hideAndTurnOnEipOnBoot) {                  onBackPressed();              } @@ -320,13 +320,13 @@ public class Dashboard extends ButterKnifeActivity {       *                               has caused to start Dashboard       * @return the created VPNFragment       */ -    public VpnFragment prepareEipFragment(boolean hideAndTurnOnEipOnBoot) { -        VpnFragment eip_fragment = new VpnFragment(); +    public EipFragment prepareEipFragment(boolean hideAndTurnOnEipOnBoot) { +        EipFragment eip_fragment = new EipFragment();          if (hideAndTurnOnEipOnBoot && !isAlwaysOn()) {              preferences.edit().remove(EIP_RESTART_ON_BOOT).apply();              Bundle arguments = new Bundle(); -            arguments.putBoolean(VpnFragment.START_EIP_ON_BOOT, true); +            arguments.putBoolean(EipFragment.START_EIP_ON_BOOT, true);              Log.d(TAG, "set START_EIP_ON_BOOT argument for eip_fragment");              eip_fragment.setArguments(arguments); diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index f1463029..414b1f2a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -24,17 +24,21 @@ import android.content.DialogInterface;  import android.content.Intent;  import android.content.ServiceConnection;  import android.content.SharedPreferences; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter;  import android.os.Bundle;  import android.os.Handler;  import android.os.IBinder;  import android.os.RemoteException;  import android.os.ResultReceiver;  import android.support.v4.app.Fragment; +import android.support.v7.widget.AppCompatImageView;  import android.util.Log;  import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.Button; +import android.widget.TextView;  import java.util.Observable;  import java.util.Observer; @@ -46,11 +50,12 @@ import de.blinkt.openvpn.core.IOpenVPNServiceInternal;  import de.blinkt.openvpn.core.OpenVPNService;  import de.blinkt.openvpn.core.ProfileManager;  import de.blinkt.openvpn.core.VpnStatus; -import mbanje.kurt.fabbutton.FabButton;  import se.leap.bitmaskclient.eip.EIP;  import se.leap.bitmaskclient.eip.EipStatus;  import se.leap.bitmaskclient.eip.VoidVpnService; +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.EIP_ACTION_CHECK_CERT_VALIDITY;  import static se.leap.bitmaskclient.Constants.EIP_ACTION_START; @@ -66,23 +71,35 @@ import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;  import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;  import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; -public class VpnFragment extends Fragment implements Observer { +public class EipFragment extends Fragment implements Observer { -    public static String TAG = VpnFragment.class.getSimpleName(); +    public static String TAG = EipFragment.class.getSimpleName(); -    public static final String IS_PENDING = TAG + ".is_pending";      protected static final String IS_CONNECTED = TAG + ".is_connected";      public static final String START_EIP_ON_BOOT = "start on boot";      private SharedPreferences preferences; -    @InjectView(R.id.vpn_status_image) -    FabButton vpnStatusImage; +    @InjectView(R.id.background) +    AppCompatImageView background; + +    @InjectView(R.id.key) +    AppCompatImageView key; + +    @InjectView(R.id.cirle) +    AppCompatImageView circle; +      @InjectView(R.id.vpn_main_button)      Button mainButton; -    private static EIPReceiver eipReceiver; -    private static EipStatus eipStatus; +    @InjectView(R.id.routed_text) +    TextView routedText; + +    @InjectView(R.id.vpn_route) +    TextView vpnRoute; + +    private EIPReceiver eipReceiver; +    private EipStatus eipStatus;      private boolean wantsToConnect;      private IOpenVPNServiceInternal mService; @@ -156,6 +173,20 @@ public class VpnFragment extends Fragment implements Observer {      }      @OnClick(R.id.vpn_main_button) +    void onButtonClick() { +        handleIcon(); +    } + +    @OnClick(R.id.key) +    void onKeyClick() { +        handleIcon(); +    } + +    @OnClick(R.id.cirle) +    void onCircleClick() { +        handleIcon(); +    } +      void handleIcon() {          if (eipStatus.isConnected() || eipStatus.isConnecting())              handleSwitchOff(); @@ -194,8 +225,6 @@ public class VpnFragment extends Fragment implements Observer {              askPendingStartCancellation();          } else if (eipStatus.isConnected()) {              askToStopEIP(); -        } else { -            updateIcon();          }      } @@ -313,44 +342,32 @@ public class VpnFragment extends Fragment implements Observer {                      }                  });              } else { -                Log.e("VpnFragment", "activity is null"); +                Log.e("EipFragment", "activity is null");              }          }      }      private void handleNewState() { -        updateIcon(); -        updateButton(); -    } - -    private void updateIcon() { -        if (eipStatus.isBlocking()) { -            vpnStatusImage.showProgress(false); -            vpnStatusImage.setIcon(R.drawable.ic_stat_vpn_blocking, R.drawable.ic_stat_vpn_blocking); -            vpnStatusImage.setTag(R.drawable.ic_stat_vpn_blocking); -        } else if (eipStatus.isConnecting()) { -            vpnStatusImage.showProgress(true); -            vpnStatusImage.setIcon(R.drawable.ic_stat_vpn_empty_halo, R.drawable.ic_stat_vpn_empty_halo); -            vpnStatusImage.setTag(R.drawable.ic_stat_vpn_empty_halo); -        } else  if (eipStatus.isConnected()){ -            vpnStatusImage.showProgress(false); -            vpnStatusImage.setIcon(R.drawable.ic_stat_vpn, R.drawable.ic_stat_vpn); -            vpnStatusImage.setTag(R.drawable.ic_stat_vpn); -        } else { -            vpnStatusImage.setIcon(R.drawable.ic_stat_vpn_offline, R.drawable.ic_stat_vpn_offline); -            vpnStatusImage.setTag(R.drawable.ic_stat_vpn_offline); -            vpnStatusImage.showProgress(false); -        } -    } - -    private void updateButton() {          Activity activity = getActivity();          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();          }      } @@ -439,8 +456,22 @@ public class VpnFragment extends Fragment implements Observer {          }      } +    private void greyscaleBackground() { +        ColorMatrix matrix = new ColorMatrix(); +        matrix.setSaturation(0); +        ColorMatrixColorFilter cf = new ColorMatrixColorFilter(matrix); +        background.setColorFilter(cf); +        background.setImageAlpha(255); +    } -    public static EIPReceiver getReceiver() { -        return eipReceiver; +    private void colorBackgroundALittle() { +        background.setColorFilter(null); +        background.setImageAlpha(144);      } + +    private void colorBackground() { +        background.setColorFilter(null); +        background.setImageAlpha(255); +    } +  } diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java index f4e2ac5f..7629f0b7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java @@ -74,7 +74,7 @@ public class MainActivity extends AppCompatActivity {          switch (intent.getAction()) {              case ACTION_SHOW_VPN_FRAGMENT: -                fragment = new VpnFragment(); +                fragment = new EipFragment();                  break;              default:                  break; diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java index f60b5cc7..2b0c72db 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java @@ -451,6 +451,12 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity                  String providerName = ConfigHelper.getProviderName(handledProvider);                  String providerDomain = ConfigHelper.getProviderDomain(handledProvider); +                //FIXME: remove that lines as soon as Provider gets sent via broadcast +                if (resultCode == PROVIDER_OK && handledProvider == null) { +                    providerName = ConfigHelper.getProviderName(preferences); +                    providerDomain = ConfigHelper.getProviderDomain(preferences); +                } +                  if (providerName != null && providerName.equalsIgnoreCase(provider.getName()) &&                          providerDomain != null &&                          providerDomain.equalsIgnoreCase(provider.getDomain())) { 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 ebfb3ba7..090e8d26 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -28,8 +28,8 @@ import android.widget.Toast;  import se.leap.bitmaskclient.ConfigHelper;  import se.leap.bitmaskclient.ProviderListActivity; +import se.leap.bitmaskclient.EipFragment;  import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.VpnFragment;  import se.leap.bitmaskclient.fragments.AboutFragment;  import se.leap.bitmaskclient.fragments.LogFragment; @@ -296,7 +296,7 @@ public class NavigationDrawerFragment extends Fragment {          if (parent == mDrawerAccountsListView) {              mTitle = getString(R.string.vpn_fragment_title); -            fragment = new VpnFragment(); +            fragment = new EipFragment();          } else {              Log.d("Drawer", String.format("Selected position %d", position));              switch (position) { 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 a2ac9d66..eca5b881 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -18,7 +18,6 @@ package se.leap.bitmaskclient.eip;  import android.app.Activity;  import android.app.IntentService; -import android.content.Context;  import android.content.Intent;  import android.content.SharedPreferences;  import android.os.Bundle; @@ -30,7 +29,6 @@ import org.json.JSONObject;  import de.blinkt.openvpn.LaunchVPN;  import se.leap.bitmaskclient.OnBootReceiver; -import se.leap.bitmaskclient.VpnFragment;  import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;  import static se.leap.bitmaskclient.Constants.EIP_ACTION_IS_RUNNING; @@ -59,12 +57,11 @@ public final class EIP extends IntentService {      public final static String TAG = EIP.class.getSimpleName();      public final static String SERVICE_API_PATH = "config/eip-service.json"; -    private static Context context;      private static ResultReceiver mReceiver;      private static SharedPreferences preferences;      private static JSONObject eipDefinition; -    private static GatewaysManager gatewaysManager = new GatewaysManager(); +    private GatewaysManager gatewaysManager = new GatewaysManager();      private static Gateway gateway;      public EIP() { @@ -74,7 +71,6 @@ public final class EIP extends IntentService {      @Override      public void onCreate() {          super.onCreate(); -        context = getApplicationContext();          preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);          eipDefinition = eipDefinitionFromPreferences();          if (gatewaysManager.isEmpty()) @@ -86,18 +82,30 @@ public final class EIP extends IntentService {          String action = intent.getAction();          mReceiver = intent.getParcelableExtra(EIP_RECEIVER); -        if (action.equals(EIP_ACTION_START)) -            startEIP(); -        else if (action.equals(EIP_ACTION_START_ALWAYS_ON_EIP)) -            startAlwaysOnEIP(); -        else if (action.equals(EIP_ACTION_STOP)) -            stopEIP(); -        else if (action.equals(EIP_ACTION_IS_RUNNING)) -            isRunning(); -        else if (action.equals(EIP_ACTION_UPDATE)) -            updateEIPService(); -        else if (action.equals(EIP_ACTION_CHECK_CERT_VALIDITY)) -            checkCertValidity(); +        if (action == null) { +            return; +        } + +        switch (action) { +            case EIP_ACTION_START: +                startEIP(); +                break; +            case EIP_ACTION_START_ALWAYS_ON_EIP: +                startAlwaysOnEIP(); +                break; +            case EIP_ACTION_STOP: +                stopEIP(); +                break; +            case EIP_ACTION_IS_RUNNING: +                isRunning(); +                break; +            case EIP_ACTION_UPDATE: +                updateEIPService(); +                break; +            case EIP_ACTION_CHECK_CERT_VALIDITY: +                checkCertValidity(); +                break; +        }      }      /** @@ -114,7 +122,6 @@ public final class EIP extends IntentService {          gateway = gatewaysManager.select();          if (gateway != null && gateway.getProfile() != null) { -            mReceiver = VpnFragment.getReceiver();              launchActiveGateway();              tellToReceiver(EIP_ACTION_START, Activity.RESULT_OK);          } else @@ -134,7 +141,6 @@ public final class EIP extends IntentService {          gateway = gatewaysManager.select();          if (gateway != null && gateway.getProfile() != null) { -            //mReceiver = VpnFragment.getReceiver();              Log.d(TAG, "startAlwaysOnEIP eip launch avtive gateway vpn");              launchActiveGateway();          } else { @@ -147,7 +153,7 @@ public final class EIP extends IntentService {       * VpnService is started properly.       */      private void earlyRoutes() { -        Intent voidVpnLauncher = new Intent(context, VoidVpnLauncher.class); +        Intent voidVpnLauncher = new Intent(getApplicationContext(), VoidVpnLauncher.class);          voidVpnLauncher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);          startActivity(voidVpnLauncher);      } @@ -216,7 +222,7 @@ public final class EIP extends IntentService {      private void gatewaysFromPreferences() {          String gatewaysString = preferences.getString(Gateway.TAG, ""); -        gatewaysManager = new GatewaysManager(context, preferences); +        gatewaysManager = new GatewaysManager(this, preferences);          gatewaysManager.addFromString(gatewaysString);          preferences.edit().remove(Gateway.TAG).apply();      } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java index ddf152d2..0da74872 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java @@ -16,13 +16,15 @@   */  package se.leap.bitmaskclient.eip; -import android.content.*; +import android.content.Context;  import android.os.AsyncTask;  import android.support.annotation.VisibleForTesting; -import java.util.*; +import java.util.Observable; -import de.blinkt.openvpn.core.*; +import de.blinkt.openvpn.core.ConnectionStatus; +import de.blinkt.openvpn.core.LogItem; +import de.blinkt.openvpn.core.VpnStatus;  /**   * EipStatus is a Singleton that represents a reduced set of a vpn's ConnectionStatus. @@ -31,7 +33,7 @@ import de.blinkt.openvpn.core.*;   */  public class EipStatus extends Observable implements VpnStatus.StateListener {      public static String TAG = EipStatus.class.getSimpleName(); -    private static EipStatus current_status; +    private static EipStatus currentStatus;      public enum EipLevel {          CONNECTING,          DISCONNECTING, @@ -42,23 +44,23 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {      }      /** -     * vpn_level holds the connection status of the openvpn vpn and the traffic blocking +     * vpnLevel holds the connection status of the openvpn vpn and the traffic blocking       * void vpn. LEVEL_BLOCKING is set when the latter vpn is up. All other states are set by       * openvpn.       */ -    private ConnectionStatus vpn_level = ConnectionStatus.LEVEL_NOTCONNECTED; -    private static EipLevel current_eip_level = EipLevel.DISCONNECTED; +    private ConnectionStatus vpnLevel = ConnectionStatus.LEVEL_NOTCONNECTED; +    private static EipLevel currentEipLevel = EipLevel.DISCONNECTED; -    int last_error_line = 0; -    private String state, log_message; -    private int localized_res_id; +    private int lastErrorLine = 0; +    private String state, logMessage; +    private int localizedResId;      public static EipStatus getInstance() { -        if (current_status == null) { -            current_status = new EipStatus(); -            VpnStatus.addStateListener(current_status); +        if (currentStatus == null) { +            currentStatus = new EipStatus(); +            VpnStatus.addStateListener(currentStatus);          } -        return current_status; +        return currentStatus;      }      private EipStatus() { @@ -66,16 +68,16 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {      @Override      public void updateState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { -        ConnectionStatus tmp = current_status.getLevel(); -        current_status = getInstance(); -        current_status.setState(state); -        current_status.setLogMessage(logmessage); -        current_status.setLocalizedResId(localizedResId); -        current_status.setLevel(level); -        current_status.setEipLevel(level); -        if (tmp != current_status.getLevel()) { -            current_status.setChanged(); -            current_status.notifyObservers(); +        ConnectionStatus tmp = currentStatus.getLevel(); +        currentStatus = getInstance(); +        currentStatus.setState(state); +        currentStatus.setLogMessage(logmessage); +        currentStatus.setLocalizedResId(localizedResId); +        currentStatus.setLevel(level); +        currentStatus.setEipLevel(level); +        if (tmp != currentStatus.getLevel()) { +            currentStatus.setChanged(); +            currentStatus.notifyObservers();          }      } @@ -87,7 +89,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {      private void setEipLevel(ConnectionStatus level) {          switch (level) {              case LEVEL_CONNECTED: -                current_eip_level = EipLevel.CONNECTED; +                currentEipLevel = EipLevel.CONNECTED;                  break;              case LEVEL_VPNPAUSED:                  throw new IllegalStateException("Ics-Openvpn's VPNPAUSED state is not supported by Bitmask"); @@ -95,25 +97,25 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {              case LEVEL_CONNECTING_NO_SERVER_REPLY_YET:              case LEVEL_WAITING_FOR_USER_INPUT:              case LEVEL_START: -                current_eip_level = EipLevel.CONNECTING; +                currentEipLevel = EipLevel.CONNECTING;                  break;              case LEVEL_AUTH_FAILED:              case LEVEL_NOTCONNECTED: -                current_eip_level = EipLevel.DISCONNECTED; +                currentEipLevel = EipLevel.DISCONNECTED;                  break;              case LEVEL_NONETWORK:              case LEVEL_BLOCKING:                  setEipLevelWithDelay(level);                  break;              case UNKNOWN_LEVEL: -                current_eip_level = EipLevel.UNKNOWN; //?? +                currentEipLevel = EipLevel.UNKNOWN; //??                  break;          }      }      @VisibleForTesting      EipLevel getEipLevel() { -        return current_eip_level; +        return currentEipLevel;      }      /** @@ -123,7 +125,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {       * @param futureLevel       */      private void setEipLevelWithDelay(ConnectionStatus futureLevel) { -        new DelayTask(current_status.getLevel(), futureLevel).execute(); +        new DelayTask(currentStatus.getLevel(), futureLevel).execute();      }      private static class DelayTask extends AsyncTask<Void, Void, Void> { @@ -131,7 +133,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {          private final ConnectionStatus currentLevel;          private final ConnectionStatus futureLevel; -        public DelayTask(ConnectionStatus currentLevel, ConnectionStatus futureLevel) { +        DelayTask(ConnectionStatus currentLevel, ConnectionStatus futureLevel) {              this.currentLevel = currentLevel;              this.futureLevel = futureLevel;          } @@ -144,38 +146,38 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {              return null;          } -        protected void onPostExecute(Void result) {; -            if (currentLevel == current_status.getLevel()) { +        protected void onPostExecute(Void result) { +            if (currentLevel == currentStatus.getLevel()) {                  switch (futureLevel) {                      case LEVEL_NONETWORK: -                        current_eip_level = EipLevel.DISCONNECTED; +                        currentEipLevel = EipLevel.DISCONNECTED;                          break;                      case LEVEL_BLOCKING: -                        current_eip_level = EipLevel.BLOCKING; +                        currentEipLevel = EipLevel.BLOCKING;                          break;                      default:                          break;                  } -                current_status.setChanged(); -                current_status.notifyObservers(); +                currentStatus.setChanged(); +                currentStatus.notifyObservers();              }          }      }      public boolean isConnecting() { -        return current_eip_level == EipLevel.CONNECTING; +        return currentEipLevel == EipLevel.CONNECTING;      }      public boolean isConnected() { -        return current_eip_level == EipLevel.CONNECTED; +        return currentEipLevel == EipLevel.CONNECTED;      }      /** -     * @return true if current_eip_level is for at least a second {@link EipLevel#BLOCKING}. +     * @return true if currentEipLevel is for at least a second {@link EipLevel#BLOCKING}.       * See {@link #setEipLevelWithDelay(ConnectionStatus)}.       */      public boolean isBlocking() { -        return current_eip_level == EipLevel.BLOCKING; +        return currentEipLevel == EipLevel.BLOCKING;      }      /** @@ -183,20 +185,20 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {       * @return true immediately after traffic blocking VoidVpn was established.       */      public boolean isBlockingVpnEstablished() { -        return vpn_level == ConnectionStatus.LEVEL_BLOCKING; +        return vpnLevel == ConnectionStatus.LEVEL_BLOCKING;      }      public boolean isDisconnected() { -        return current_eip_level == EipLevel.DISCONNECTED; +        return currentEipLevel == EipLevel.DISCONNECTED;      }      /**       * ics-openvpn's paused state is not implemented yet -     * @return +     * @return true if vpn is paused false if not       */      @Deprecated      public boolean isPaused() { -        return vpn_level == ConnectionStatus.LEVEL_VPNPAUSED; +        return vpnLevel == ConnectionStatus.LEVEL_VPNPAUSED;      }      public String getState() { @@ -204,15 +206,15 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {      }      public String getLogMessage() { -        return log_message; +        return logMessage;      } -    public int getLocalizedResId() { -        return localized_res_id; +    int getLocalizedResId() { +        return localizedResId;      }      public ConnectionStatus getLevel() { -        return vpn_level; +        return vpnLevel;      }      private void setState(String state) { @@ -220,39 +222,40 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {      }      private void setLogMessage(String log_message) { -        this.log_message = log_message; +        this.logMessage = log_message;      }      private void setLocalizedResId(int localized_res_id) { -        this.localized_res_id = localized_res_id; +        this.localizedResId = localized_res_id;      }      private void setLevel(ConnectionStatus level) { -        this.vpn_level = level; +        this.vpnLevel = level;      }      public boolean errorInLast(int lines, Context context) {          return !lastError(lines, context).isEmpty();      } -    public String lastError(int lines, Context context) { +    private String lastError(int lines, Context context) {          String error = "";          String[] error_keywords = {"error", "ERROR", "fatal", "FATAL"};          LogItem[] log = VpnStatus.getlogbuffer(); -        if(log.length < last_error_line) -            last_error_line = 0; -        String message = ""; +        if(log.length < lastErrorLine) +            lastErrorLine = 0; +        String message;          for (int i = 1; i <= lines && log.length > i; i++) {              int line = log.length - i; -            LogItem log_item = log[line]; -            message = log_item.getString(context); -            for (int j = 0; j < error_keywords.length; j++) -                if (message.contains(error_keywords[j]) && line > last_error_line) { +            LogItem logItem = log[line]; +            message = logItem.getString(context); +            for (String errorKeyword: error_keywords) { +                if (message.contains(errorKeyword) && line > lastErrorLine) {                      error = message; -                    last_error_line = line; +                    lastErrorLine = line;                  } +            }          }          return error; @@ -260,7 +263,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {      @Override      public String toString() { -        return "State: " + state + " Level: " + vpn_level.toString(); +        return "State: " + state + " Level: " + vpnLevel.toString();      }  } diff --git a/app/src/main/res/drawable/black_circle.xml b/app/src/main/res/drawable/black_circle.xml new file mode 100644 index 00000000..533652d6 --- /dev/null +++ b/app/src/main/res/drawable/black_circle.xml @@ -0,0 +1,9 @@ +<?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> +</selector>
\ No newline at end of file diff --git a/app/src/main/res/drawable/vpn_connected.xml b/app/src/main/res/drawable/vpn_connected.xml new file mode 100644 index 00000000..ea4d61a2 --- /dev/null +++ b/app/src/main/res/drawable/vpn_connected.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" +android:width="48dp" +android:height="48dp" +android:viewportWidth="48" +android:viewportHeight="48"> + +<path +    android:fillColor="#ffffff" +    android:strokeWidth="1" +    android:pathData="M 12.187013,12.3125 C 5.4647724,12.3125 0,17.760254 0,24.5 c 0,6.739746 +5.4647724,12.21875 12.187013,12.21875 5.305097,0 9.803352,-3.408824 +11.47013,-8.15625 l 8.509091,-0.09375 1.745454,-2.09375 1.153247,-0.03125 +1.828239,2.182795 1.234013,-0.03125 2.049436,-2.307795 1.122078,0 +1.714286,2.21875 2.836364,0 L 48,24.4375 l -2.774026,-4.09375 -21.6,0 C +21.928439,15.65398 17.450952,12.3125 12.187013,12.3125 z m -4.8311688,8.90625 c +1.8370556,0 3.3350648,1.50191 3.3350648,3.34375 0,1.84184 -1.4980092,3.3125 +-3.3350648,3.3125 -1.8370556,0 -3.335065,-1.47066 -3.335065,-3.3125 0,-1.84184 +1.4980094,-3.34375 3.335065,-3.34375 z" /> +</vector>
\ No newline at end of file diff --git a/app/src/main/res/drawable/vpn_connecting.xml b/app/src/main/res/drawable/vpn_connecting.xml new file mode 100644 index 00000000..16c079c4 --- /dev/null +++ b/app/src/main/res/drawable/vpn_connecting.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" +    android:width="48dp" +    android:height="48dp" +    android:viewportWidth="48" +    android:viewportHeight="48"> + +    <path +        android:fillColor="#ffffff" +        android:strokeWidth="1" +        android:pathData="M12.1875,12.3125 C5.46526,12.3125,0,17.7603,0,24.5 +C0,31.2397,5.46526,36.7188,12.1875,36.7188 +C17.4926,36.7188,21.9895,33.3099,23.6563,28.5625 L32.1563,28.4688 +L33.9063,26.375 L35.0625,26.3438 L36.9063,28.5313 L38.125,28.5 L40.1875,26.1875 +L41.3125,26.1875 L43,28.4063 L45.8438,28.4063 L48,24.4375 L45.2188,20.3438 +L23.625,20.3438 C21.9275,15.654,17.4514,12.3125,12.1875,12.3125 Z +M12.2188,15.6875 C17.0994,15.6875,21.0313,19.6506,21.0313,24.5313 +C21.0313,29.4119,17.0994,33.375,12.2188,33.375 +C7.33805,33.375,3.375,29.4119,3.375,24.5313 +C3.375,19.6506,7.33805,15.6875,12.2188,15.6875 Z" /> +    <path +        android:strokeColor="#ffffff" +        android:strokeWidth="2.50000000000000000" +        android:pathData="M12.178,17.8729 L12.1779,24.6356 L8.61859,28.1949" /> +</vector>
\ No newline at end of file diff --git a/app/src/main/res/drawable/vpn_disconnected.xml b/app/src/main/res/drawable/vpn_disconnected.xml new file mode 100644 index 00000000..d6cf067b --- /dev/null +++ b/app/src/main/res/drawable/vpn_disconnected.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" +    android:width="48dp" +    android:height="48dp" +    android:viewportWidth="48" +    android:viewportHeight="48"> + +    <path +        android:fillColor="#ffffff" +        android:strokeWidth="1" +        android:pathData="M13.9636,12.4377 L28.7376,28.5002 L32.1662,28.4689 L33.9117,26.3752 +L35.0649,26.3439 L36.9039,28.5314 L38.1195,28.5002 L40.1766,26.1877 +L41.2987,26.1877 L43.013,28.4064 L45.8494,28.4064 L48,24.4377 L45.226,20.344 +L23.626,20.344 C22.1234,16.1928,18.44,13.0938,13.9637,12.4378 Z M8.47792,12.9065 +C3.56807,14.4767,0,19.059,0,24.5002 C0,31.24,5.46477,36.719,12.187,36.719 +C17.2792,36.719,21.6241,33.5759,23.439,29.1253 L8.47792,12.9065 Z +M7.35584,21.219 C9.1929,21.219,10.6909,22.7209,10.6909,24.5628 +C10.6909,26.4046,9.19289,27.8753,7.35584,27.8753 +C5.51878,27.8753,4.02077,26.4046,4.02077,24.5628 +C4.02077,22.721,5.51878,21.219,7.35583,21.219 Z" /> +    <group android:name="rotationGroup" +        android:rotation="47.263656"> +        <path +            android:fillColor="#ffffff" +            android:strokeWidth="1" +            android:pathData="M9.50852,-4.62741 L57.4577,-4.62741 L57.4577,-0.305379 L9.50852,-0.305379 L9.50852,-4.62741 Z" /> +    </group> +</vector>
\ No newline at end of file diff --git a/app/src/main/res/layout/eip_service_fragment.xml b/app/src/main/res/layout/eip_service_fragment.xml index cef01c18..aa7ba514 100644 --- a/app/src/main/res/layout/eip_service_fragment.xml +++ b/app/src/main/res/layout/eip_service_fragment.xml @@ -1,49 +1,151 @@  <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<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:id="@+id/relativeLayout"      android:layout_width="match_parent" -    android:layout_height="wrap_content" -    android:layout_marginTop="10dp"> +    android:layout_height="match_parent"> + +    <android.support.constraint.Guideline +        android:id="@+id/guideline_horizontal_top" +        android:layout_width="0dp" +        android:layout_height="0dp" +        android:orientation="horizontal" +        app:layout_constraintBottom_toBottomOf="parent" +        app:layout_constraintRight_toRightOf="parent" +        app:layout_constraintGuide_percent="0.3" +        /> + +    <android.support.constraint.Guideline +        android:id="@+id/guideline_vertical_left" +        android:layout_width="0dp" +        android:layout_height="0dp" +        android:orientation="vertical" +        app:layout_constraintBottom_toBottomOf="parent" +        app:layout_constraintGuide_percent="0.3" +        /> + + +    <android.support.constraint.Guideline +        android:id="@+id/guideline_horizontal_bottom" +        android:layout_width="0dp" +        android:layout_height="0dp" +        android:orientation="horizontal" +        app:layout_constraintBottom_toBottomOf="parent" +        app:layout_constraintRight_toRightOf="parent" +        app:layout_constraintGuide_percent="0.7" +        /> + +    <android.support.constraint.Guideline +        android:id="@+id/guideline_vertical_right" +        android:layout_width="0dp" +        android:layout_height="0dp" +        android:orientation="vertical" +        app:layout_constraintBottom_toBottomOf="parent" +        app:layout_constraintGuide_percent="0.7" +        /> + +    <android.support.v7.widget.AppCompatImageView +        android:id="@+id/background" +        android:layout_width="match_parent" +        android:layout_height="match_parent" +        android:scaleType="fitXY" +        app:srcCompat="@drawable/ic_colorsquare" /> +      <TextView          android:id="@+id/eipLabel"          android:layout_width="wrap_content"          android:layout_height="wrap_content" -        android:layout_centerHorizontal="true" -        android:layout_marginLeft="10dp" -        android:layout_marginStart="10dp" -        android:layout_marginTop="12dp" -        android:layout_marginBottom="12dp" +        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:text="@string/eip_service_label" -        android:textAppearance="?android:attr/textAppearanceMedium" /> +        android:textAppearance="?android:attr/textAppearanceMedium" +        app:layout_constraintEnd_toEndOf="parent" +        app:layout_constraintStart_toStartOf="parent" +        app:layout_constraintTop_toTopOf="parent" /> + + +    <android.support.v7.widget.AppCompatImageView +        android:id="@+id/cirle" +        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_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" /> -    <LinearLayout + +    <android.support.v7.widget.AppCompatButton +        android:id="@+id/vpn_main_button"          android:layout_width="wrap_content"          android:layout_height="wrap_content" -        android:orientation="horizontal" -        android:layout_below="@+id/eipLabel" -        android:layout_centerInParent="true"> - -        <Button -            android:id="@+id/vpn_main_button" -            android:layout_width="wrap_content" -            android:layout_height="wrap_content" -            android:textSize="12sp" -            /> - -        <se.leap.bitmaskclient.userstatus.FabButton -            android:id="@+id/vpn_status_image" -            android:layout_width="32dp" -            android:layout_height="32dp" -            android:layout_marginLeft="3dp" -            android:layout_marginStart="3dp" -            android:color="@android:color/holo_blue_dark" -            android:layout_gravity="center" -            android:visibility="visible" -            android:indeterminate="true" -            android:max="100" -            fbb_autoStart="true" -            fbb_progressColor="#ff170aff" -            fbb_progressWidthRatio="0.1" -            /> -    </LinearLayout> -</RelativeLayout> +        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/background" +        app:layout_constraintEnd_toEndOf="parent" +        app:layout_constraintStart_toStartOf="parent" +        android:text="@string/vpn.button.turn.on" +        style="@style/BitmaskButtonBlack" +        /> + +    <TextView +        android:id="@+id/routed_text" +        android:layout_width="wrap_content" +        android:layout_height="wrap_content" +        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:text="@string/vpn_securely_routed" +        android:visibility="visible" +        app:layout_constraintEnd_toEndOf="parent" +        app:layout_constraintStart_toStartOf="parent" +        app:layout_constraintTop_toBottomOf="@+id/eipLabel" /> + +    <TextView +        android:id="@+id/vpn_route" +        android:layout_width="wrap_content" +        android:layout_height="wrap_content" +        android:layout_marginEnd="@dimen/stdpadding" +        android:layout_marginStart="@dimen/stdpadding" +        android:layout_marginLeft="@dimen/stdpadding" +        android:layout_marginRight="@dimen/stdpadding" +        app:layout_constraintEnd_toEndOf="parent" +        app:layout_constraintStart_toStartOf="parent" +        app:layout_constraintTop_toBottomOf="@+id/routed_text" /> + +</android.support.constraint.ConstraintLayout> diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index b928a79b..9f36e474 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -31,4 +31,10 @@          <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/colors.xml b/app/src/main/res/values/colors.xml index a8a63e4b..53ead009 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -6,6 +6,8 @@      <color name="colorError">#ef9a9a</color>      <color name="colorSuccess">#a5d6a7</color> +    <color name="black800">#424242</color> +      <color name="red200">#ef9a9a</color>      <color name="pink200">#f48fb1</color>      <color name="purple200">#ce93d8</color> @@ -23,4 +25,6 @@      <color name="orange200">#ffcc80</color>      <color name="deepOrange200">#ffab91</color> +    <color name="white">#ffffff</color> +  </resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 01715c32..c1443138 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,6 +85,7 @@      <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="bitmask_log">Bitmask Log</string>      <string name="title_activity_main">Bitmask</string>      <string name="log_fragment_title">Log</string> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 3b1150ea..867fa54f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -67,4 +67,11 @@      <style name="BitmaskActivity">          <item name="android:padding">@dimen/activity_margin</item>      </style> + +    <style name="BitmaskButtonBlack" parent="android:Widget.Button"> +        <item name="android:textAllCaps">true</item> +        <item name="android:background">@color/black800</item> +        <item name="android:textColor">@color/white</item> +    </style> +  </resources>
\ No newline at end of file | 
