Bladeren bron

Merge pull request 'connection_functionality' (#8) from connection_functionality into dev

Reviewed-on: https://git.bubblev.org/bubblev/bubble-droid/pulls/8
pull/9/head
Gegham Kurghinyan 4 jaren geleden
bovenliggende
commit
ee7304b9f3
11 gewijzigde bestanden met toevoegingen van 311 en 110 verwijderingen
  1. +0
    -1
      ui/src/main/java/com/wireguard/android/Application.kt
  2. +56
    -13
      ui/src/main/java/com/wireguard/android/activity/LoginActivity.java
  3. +41
    -43
      ui/src/main/java/com/wireguard/android/activity/MainActivity.java
  4. +1
    -1
      ui/src/main/java/com/wireguard/android/api/ApiConstants.java
  5. +2
    -2
      ui/src/main/java/com/wireguard/android/api/network/ClientService.java
  6. +143
    -18
      ui/src/main/java/com/wireguard/android/repository/DataRepository.java
  7. +10
    -0
      ui/src/main/java/com/wireguard/android/util/UserStore.java
  8. +20
    -2
      ui/src/main/java/com/wireguard/android/viewmodel/LoginViewModel.java
  9. +28
    -3
      ui/src/main/java/com/wireguard/android/viewmodel/MainViewModel.java
  10. +2
    -27
      ui/src/main/res/layout/activity_main.xml
  11. +8
    -0
      ui/src/main/res/values/strings.xml

+ 0
- 1
ui/src/main/java/com/wireguard/android/Application.kt Bestand weergeven

@@ -60,7 +60,6 @@ class Application : android.app.Application(), OnSharedPreferenceChangeListener
override fun onCreate() {
Log.i(TAG, USER_AGENT)
super.onCreate()
DataRepository.buildRepositoryInstance()
asyncWorker = AsyncWorker(AsyncTask.SERIAL_EXECUTOR, Handler(Looper.getMainLooper()))
rootShell = RootShell(applicationContext)
toolsInstaller = ToolsInstaller(applicationContext, rootShell)


+ 56
- 13
ui/src/main/java/com/wireguard/android/activity/LoginActivity.java Bestand weergeven

@@ -1,10 +1,12 @@
package com.wireguard.android.activity;

import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import android.content.Intent;
import android.os.Bundle;
import android.security.KeyChain;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -14,9 +16,14 @@ import android.widget.Toast;

import com.wireguard.android.R;
import com.wireguard.android.model.User;
import com.wireguard.android.repository.DataRepository;
import com.wireguard.android.resource.StatusResource;
import com.wireguard.android.viewmodel.LoginViewModel;

import javax.security.cert.CertificateEncodingException;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;

public class LoginActivity extends BaseActivityBubble {

private LoginViewModel loginViewModel;
@@ -25,6 +32,12 @@ public class LoginActivity extends BaseActivityBubble {
private EditText password;
private Button sign;

private static final String BASE_URL_PREFIX = "https://";
private static final String BASE_URL_SUFFIX = ":1443/api/";
private static final String SEPARATOR = "\\.";
private static final int REQUEST_CODE = 1555;
private static final String CERTIFICATE_NAME = "Bubble Certificate";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -41,11 +54,21 @@ public class LoginActivity extends BaseActivityBubble {
private void initListeners() {
sign.setOnClickListener(new OnClickListener() {
@Override public void onClick(final View v) {
final String tunnelName = bubbleName.getText().toString().trim();
final String username = userName.getText().toString().trim();
final String password = LoginActivity.this.password.getText().toString().trim();
final String url = BASE_URL_PREFIX + bubbleName.getText().toString() + BASE_URL_SUFFIX;
if (url.split(SEPARATOR).length != 3) {
Toast.makeText(LoginActivity.this, getResources().getText(R.string.hostname_not_valid), Toast.LENGTH_LONG).show();
return;
}
if (DataRepository.getRepositoryInstance() == null) {
loginViewModel.buildRepositoryInstance(LoginActivity.this, url);
} else {
loginViewModel.buildClientService(url);
}
loginViewModel.setUserURL(LoginActivity.this, url);
final String usernameInput = userName.getText().toString().trim();
final String passwordInput = password.getText().toString().trim();
showLoadingDialog();
login(tunnelName, username, password);
login(usernameInput, passwordInput);
}
});
}
@@ -57,28 +80,48 @@ public class LoginActivity extends BaseActivityBubble {
sign = findViewById(R.id.signButton);
}

private void login(String tunnelName, String username, String password) {
loginViewModel.login(tunnelName, username, password, this).observe(this, new Observer<StatusResource<User>>() {
private void login(String username, String password) {
loginViewModel.login(username, password, this).observe(this, new Observer<StatusResource<User>>() {
@Override public void onChanged(final StatusResource<User> userStatusResource) {
switch (userStatusResource.status) {
case SUCCESS:
Toast.makeText(LoginActivity.this, "Success", Toast.LENGTH_SHORT).show();
Log.d("TAG", "Success");
closeLoadingDialog();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
loginViewModel.getCertificate(LoginActivity.this).observe(LoginActivity.this, new Observer<byte[]>() {
@Override public void onChanged(final byte[] encodedCertificate) {
closeLoadingDialog();
if (encodedCertificate.length == 0) {
Toast.makeText(LoginActivity.this, getString(R.string.failed_bubble), Toast.LENGTH_SHORT).show();
} else {
final Intent intent = KeyChain.createInstallIntent();
intent.putExtra(KeyChain.EXTRA_CERTIFICATE, encodedCertificate);
intent.putExtra(KeyChain.EXTRA_NAME, CERTIFICATE_NAME);
startActivityForResult(intent, REQUEST_CODE);
}
}
});
break;
case LOADING:
Log.d("TAG", "Loading");
break;
case ERROR:
closeLoadingDialog();
Toast.makeText(LoginActivity.this, "Login Failed", Toast.LENGTH_SHORT).show();
Toast.makeText(LoginActivity.this, getString(R.string.login_failed), Toast.LENGTH_SHORT).show();
Log.d("TAG", "Error");
break;
}
}
});
}

@Override protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
Toast.makeText(this, getString(R.string.success), Toast.LENGTH_SHORT).show();
Log.d("TAG", "Success");
final Intent mainActivityIntent = new Intent(this, MainActivity.class);
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainActivityIntent);
} else {
Toast.makeText(this, getString(R.string.cerificate_install), Toast.LENGTH_LONG).show();
}
}
}

+ 41
- 43
ui/src/main/java/com/wireguard/android/activity/MainActivity.java Bestand weergeven

@@ -2,6 +2,7 @@ package com.wireguard.android.activity;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.content.Intent;
import android.os.Bundle;
@@ -9,22 +10,14 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.wireguard.android.Application;
import com.wireguard.android.R;
import com.wireguard.android.backend.GoBackend;
import com.wireguard.android.backend.Tunnel;
import com.wireguard.android.model.ObservableTunnel;
import com.wireguard.android.viewmodel.MainViewModel;

public class MainActivity extends AppCompatActivity {
private MainViewModel mainViewModel;
private TextView bubbleStatus;
private TextView deviceStatus;
private Button connectButton;
public ObservableTunnel pendingTunnel;
private Boolean pendingTunnelUp;
private boolean connectionStateFlag;

private static final int REQUEST_CODE_VPN_PERMISSION = 23491;

@@ -39,8 +32,19 @@ public class MainActivity extends AppCompatActivity {
startActivity(intent);
finish();
}
mainViewModel.buildRepositoryInstance(this, mainViewModel.getUserURL(this));
initUI();
pendingTunnel = mainViewModel.getTunnel(this);
}

@Override protected void onResume() {
super.onResume();
if (mainViewModel.isVPNConnected(this, connectionStateFlag)) {
connectionStateFlag = false;
setConnectionStateUI(false);
} else {
connectionStateFlag = true;
setConnectionStateUI(true);
}
}

private void initUI() {
@@ -50,7 +54,6 @@ public class MainActivity extends AppCompatActivity {

private void initViews() {
bubbleStatus = findViewById(R.id.bubbleStatus);
deviceStatus = findViewById(R.id.deviceStatus);
connectButton = findViewById(R.id.connectButton);
}

@@ -63,44 +66,39 @@ public class MainActivity extends AppCompatActivity {
}

private void connect() {
setTunnelState(true);
}

private void setTunnelState(final Boolean checked) {
if(pendingTunnel!=null) {
final ObservableTunnel tunnel = pendingTunnel;
Application.getBackendAsync().thenAccept(backend -> {
if (backend instanceof GoBackend) {
final Intent intent = GoBackend.VpnService.prepare(this);
if (intent != null) {
pendingTunnelUp = checked;
startActivityForResult(intent, REQUEST_CODE_VPN_PERMISSION);
return;
}
}
setTunnelStateWithPermissionsResult(tunnel, checked);
});
}

}

private void setTunnelStateWithPermissionsResult(final ObservableTunnel tunnel, final boolean checked) {
tunnel.setStateAsync(Tunnel.State.of(checked)).whenComplete((observableTunnel, throwable) ->{
if(throwable==null){
Toast.makeText(this,"Connected",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(this,"Failed",Toast.LENGTH_SHORT).show();
}
final boolean state = mainViewModel.isVPNConnected(this, connectionStateFlag);
connectionStateFlag = state;
mainViewModel.connect(state, MainActivity.this).observe(MainActivity.this, new Observer<Boolean>() {
@Override public void onChanged(final Boolean state) {
setConnectionStateUI(state);
}
});
}

@Override protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_VPN_PERMISSION) {
if (pendingTunnel != null && pendingTunnelUp != null) setTunnelStateWithPermissionsResult(pendingTunnel, pendingTunnelUp);
pendingTunnel = null;
pendingTunnelUp = null;
if (resultCode == RESULT_OK) {
mainViewModel.connectWithPermission(connectionStateFlag, this)
.observe(this, new Observer<Boolean>() {
@Override public void onChanged(final Boolean state) {
setConnectionStateUI(state);
}
});
} else {
connectionStateFlag = false;
setConnectionStateUI(false);
}
}
}

private void setConnectionStateUI(boolean state) {
if (state) {
bubbleStatus.setText(getString(R.string.connected_bubble));
connectButton.setText(getString(R.string.disconnect));
} else {
bubbleStatus.setText(getString(R.string.not_connected_bubble));
connectButton.setText(getString(R.string.connect));
}
}
}

+ 1
- 1
ui/src/main/java/com/wireguard/android/api/ApiConstants.java Bestand weergeven

@@ -1,7 +1,6 @@
package com.wireguard.android.api;

public class ApiConstants {
public static final String BASE_URL = "https://jtest2.bubblesecure.com:1443/api/";
public static final String LOGIN_URL = "auth/login";
public static final String ALL_DEVICES_URL = "me/devices";
public static final String ADD_DEVICE_URL = "me/devices";
@@ -12,4 +11,5 @@ public class ApiConstants {
public static final String AUTHORIZATION_HEADER = "X-Bubble-Session";
public static final String DEVICE_NAME = "name";
public static final String DEVICE_TYPE = "deviceType";
public static final String CERTIFICATE_URL = "auth/cacert?deviceType=android";
}

+ 2
- 2
ui/src/main/java/com/wireguard/android/api/network/ClientService.java Bestand weergeven

@@ -28,7 +28,7 @@ public class ClientService {
}


public ClientApi createClientApi() {
public ClientApi createClientApi(String url) {

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

@@ -40,7 +40,7 @@ public class ClientService {
httpClient.addInterceptor(new UserAgentInterceptor(System.getProperty("http.agent")));

return new Retrofit.Builder()
.baseUrl(ApiConstants.BASE_URL)
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(httpClient.build())


+ 143
- 18
ui/src/main/java/com/wireguard/android/repository/DataRepository.java Bestand weergeven

@@ -1,15 +1,21 @@
package com.wireguard.android.repository;

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.widget.Toast;

import com.wireguard.android.Application;
import com.wireguard.android.R;
import com.wireguard.android.activity.MainActivity;
import com.wireguard.android.api.ApiConstants;
import com.wireguard.android.api.network.ClientApi;
import com.wireguard.android.api.network.ClientService;
import com.wireguard.android.api.network.NetworkBoundStatusResource;
import com.wireguard.android.backend.GoBackend;
import com.wireguard.android.backend.Tunnel;
import com.wireguard.android.backend.Tunnel.State;
import com.wireguard.android.configStore.FileConfigStore;
import com.wireguard.android.model.Device;
@@ -30,7 +36,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Scanner;

import javax.security.cert.CertificateEncodingException;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;

import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
@@ -46,33 +58,45 @@ public class DataRepository {
private ClientApi clientApi;
private CompositeDisposable compositeDisposable;
private final OkHttpClient client = new OkHttpClient();
private TunnelManager tunnelManager;
private ObservableTunnel pendingTunnel;

public static final String NO_INTERNET_CONNECTION = "no_internet_connection";
private static final String SEPARATOR = ":";
private static final String SPACE = " ";
private static final String DELIMITER = "\\A";
private static final int ANDROID_ID = 1;
private static String BASE_URL = "";
private static final String TUNNEL_NAME = "BubbleVPN";
private static final int REQUEST_CODE_VPN_PERMISSION = 23491;

private DataRepository() {
clientApi = ClientService.getInstance().createClientApi();
private DataRepository(Context context, String url) {
BASE_URL = url;
clientApi = ClientService.getInstance().createClientApi(url);
compositeDisposable = new CompositeDisposable();
tunnelManager = new TunnelManager(new FileConfigStore(context));
}

public static void buildRepositoryInstance() {
public static void buildRepositoryInstance(Context context, String url) {
if (instance == null) {
synchronized (DataRepository.class) {
if (instance == null) {
instance = new DataRepository();
instance = new DataRepository(context, url);
}
}
}
}

public void buildClientService(String url) {
BASE_URL = url;
clientApi = ClientService.getInstance().createClientApi(url);
}

public static DataRepository getRepositoryInstance() {
return instance;
}

public MutableLiveData<StatusResource<User>> login(String tunnelName, String username, String password, Context context) {
public MutableLiveData<StatusResource<User>> login(String username, String password, Context context) {
return new NetworkBoundStatusResource<User>() {

@Override protected void createCall() {
@@ -115,7 +139,7 @@ public class DataRepository {
addDevice(context);
}
}, throwable -> {
setMutableLiveData(StatusResource.error(throwable.getMessage()));
});
compositeDisposable.add(disposableAllDevices);
}
@@ -223,7 +247,7 @@ public class DataRepository {
final String deviceID = UserStore.getInstance(context).getDeviceID();
final String token = UserStore.getInstance(context).getToken();
Request request = new Request.Builder()
.url(ApiConstants.BASE_URL + ApiConstants.CONFIG_DEVICE_URL + deviceID + ApiConstants.CONFIG_VPN_URL)
.url(BASE_URL + ApiConstants.CONFIG_DEVICE_URL + deviceID + ApiConstants.CONFIG_VPN_URL)
.addHeader(ApiConstants.AUTHORIZATION_HEADER, token)
.build();
client.newCall(request).enqueue(new Callback() {
@@ -235,18 +259,19 @@ public class DataRepository {
final InputStream inputStream = response.body().byteStream();
final Scanner scanner = new Scanner(inputStream).useDelimiter(DELIMITER);
final String data = scanner.hasNext() ? scanner.next() : "";
createTunnel(data, tunnelName);
createTunnel(data);
}
});
}

private void createTunnel(String rawConfig, String tunnelName) {
private void createTunnel(final String rawConfig) {
try {
final byte[] configBytes = rawConfig.getBytes();
final Config config = Config.parse(new ByteArrayInputStream(configBytes));
Application.getTunnelManager().create(tunnelName, config).whenComplete((observableTunnel, throwable) -> {
Application.getTunnelManager().create(TUNNEL_NAME, config).whenComplete((observableTunnel, throwable) -> {
if (observableTunnel != null) {
TunnelStore.getInstance(context).setTunnel(tunnelName, rawConfig);
TunnelStore.getInstance(context).setTunnel(TUNNEL_NAME, rawConfig);
tunnelManager.setTunnelState(observableTunnel, State.DOWN);
setMutableLiveData(StatusResource.success());
} else {
setMutableLiveData(StatusResource.error(throwable.getMessage()));
@@ -300,7 +325,14 @@ public class DataRepository {
}


public ObservableTunnel getTunnel(Context context) {
private Config parseConfig(String data) throws IOException, BadConfigException {
final byte[] configText = data.getBytes();
final Config config = Config.parse(new ByteArrayInputStream(configText));
return config;
}


private ObservableTunnel createTunnel(final Context context, final boolean stateTunnel) {
//TODO implement config is null case
Config config = null;
try {
@@ -309,14 +341,107 @@ public class DataRepository {
return null;
}
final String name = TunnelStore.getInstance(context).getTunnelName();
final TunnelManager tunnelManager = new TunnelManager(new FileConfigStore(context));
final ObservableTunnel tunnel = new ObservableTunnel(tunnelManager, name, config, State.DOWN);
final ObservableTunnel tunnel;
if (stateTunnel) {
tunnel = new ObservableTunnel(tunnelManager, name, config, State.UP);
} else {
tunnel = new ObservableTunnel(tunnelManager, name, config, State.DOWN);
}
tunnelManager.setTunnelState(tunnel, tunnel.getState());

return tunnel;
}

private Config parseConfig(String data) throws IOException, BadConfigException {
final byte[] configText = data.getBytes();
final Config config = Config.parse(new ByteArrayInputStream(configText));
return config;
public void setUserURL(Context context, String url) {
UserStore.getInstance(context).setUserURL(url);
}

public ObservableTunnel getTunnel(Context context, boolean connectionStateFlag) {
ObservableTunnel tunnel = tunnelManager.getLastUsedTunnel();
if (tunnel == null) {
tunnel = createTunnel(context, connectionStateFlag);
}
return tunnel;
}

public MutableLiveData<byte[]> getCertificate(Context context) {
final MutableLiveData<byte[]> liveData = new MutableLiveData<>();
final Request request = new Request.Builder()
.url(BASE_URL + ApiConstants.CERTIFICATE_URL)
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(final okhttp3.Call call, final IOException e) {
liveData.postValue(new byte[]{});
}

@Override public void onResponse(final okhttp3.Call call, final Response response) throws IOException {
if (response.isSuccessful()) {
final InputStream inputStream = response.body().byteStream();
final Scanner scanner = new Scanner(inputStream).useDelimiter(DELIMITER);
final String data = scanner.hasNext() ? scanner.next() : "";
final byte[] cert = data.getBytes();
X509Certificate x509Certificate = null;
try {
x509Certificate = X509Certificate.getInstance(cert);
} catch (final CertificateException e) {
liveData.postValue(new byte[]{});
}
try {
liveData.postValue(x509Certificate.getEncoded());
} catch (final CertificateEncodingException e) {
liveData.postValue(new byte[]{});
}
} else {
liveData.postValue(new byte[]{});
}
}
});
return liveData;
}

public boolean isVPNConnected(Context context, boolean connectionStateFlag) {
pendingTunnel = getTunnel(context, connectionStateFlag);
return pendingTunnel.getState() == State.DOWN;
}

public MutableLiveData<Boolean> connect(final Boolean checked , Context context) {
MutableLiveData<Boolean> liveData = new MutableLiveData<>();
if (pendingTunnel != null) {
Application.getBackendAsync().thenAccept(backend -> {
if (backend instanceof GoBackend) {
final Intent intent = GoBackend.VpnService.prepare(context);
if (intent != null) {
if(context instanceof MainActivity) {
((MainActivity)context).startActivityForResult(intent, REQUEST_CODE_VPN_PERMISSION);
return;
}
}
}
connectWithPermission(checked,context).observe((LifecycleOwner) context, new Observer<Boolean>() {
@Override public void onChanged(final Boolean aBoolean) {
liveData.postValue(aBoolean);
}
});
});
}
return liveData;
}

public MutableLiveData<Boolean> connectWithPermission(final boolean checked , Context context) {
MutableLiveData<Boolean> liveData = new MutableLiveData<>();
pendingTunnel.setStateAsync(Tunnel.State.of(checked)).whenComplete((observableTunnel, throwable) ->{
if(throwable==null){
if(observableTunnel == State.DOWN) {
liveData.postValue(false);
}
else {
liveData.postValue(true);
}
}
else {
Toast.makeText(context,context.getString(R.string.failed_bubble),Toast.LENGTH_SHORT).show();
}
});
return liveData;
}
}

+ 10
- 0
ui/src/main/java/com/wireguard/android/util/UserStore.java Bestand weergeven

@@ -11,9 +11,11 @@ public class UserStore {
private static final String USER_DATA_KEY = "com.wireguard.android.util.bubbleUserResponse";
private static final String DEVICE_DATA_KEY = "com.wireguard.android.util.bubbleDeviceResponse";
private static final String DEVICE_ID_KEY = "com.wireguard.android.util.bubbleDeviceIDResponse";
private static final String USER_BASE_URL_KEY = "com.wireguard.android.util.bubbleUserURLResponse";
public static final String USER_TOKEN_DEFAULT_VALUE = "";
public static final String DEVICE_DEFAULT_VALUE = "";
public static final String DEVICE_ID_DEFAULT_VALUE = "";
public static final String USER_BASE_URL_DEFAULT_VALUE = "";

public static UserStore getInstance(Context context) {
if (instance == null) {
@@ -51,4 +53,12 @@ public class UserStore {
public String getDeviceID(){
return sharedPreferences.getString(DEVICE_ID_KEY,DEVICE_ID_DEFAULT_VALUE);
}

public void setUserURL(String url){
sharedPreferences.edit().putString(USER_BASE_URL_KEY,url).apply();
}

public String getUserURL(){
return sharedPreferences.getString(USER_BASE_URL_KEY,USER_BASE_URL_DEFAULT_VALUE);
}
}

+ 20
- 2
ui/src/main/java/com/wireguard/android/viewmodel/LoginViewModel.java Bestand weergeven

@@ -5,17 +5,35 @@ import android.content.Context;
import com.wireguard.android.model.User;
import com.wireguard.android.repository.DataRepository;
import com.wireguard.android.resource.StatusResource;
import com.wireguard.android.util.UserStore;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class LoginViewModel extends ViewModel {
public LiveData<StatusResource<User>> login(String tunnelName, String username, String password, Context context) {
return DataRepository.getRepositoryInstance().login(tunnelName,username, password, context);
public LiveData<StatusResource<User>> login(String username, String password, Context context) {
return DataRepository.getRepositoryInstance().login(username, password, context);
}

@Override protected void onCleared() {
super.onCleared();
DataRepository.getRepositoryInstance().clearDisposable();
}

public void buildRepositoryInstance(Context context, String url){
DataRepository.buildRepositoryInstance(context,url);
}

public void setUserURL(Context context, String url){
DataRepository.getRepositoryInstance().setUserURL(context,url);
}

public void buildClientService(String url){
DataRepository.getRepositoryInstance().buildClientService(url);
}

public MutableLiveData<byte[]> getCertificate(Context context){
return DataRepository.getRepositoryInstance().getCertificate(context);
}
}

+ 28
- 3
ui/src/main/java/com/wireguard/android/viewmodel/MainViewModel.java Bestand weergeven

@@ -3,15 +3,40 @@ package com.wireguard.android.viewmodel;
import android.content.Context;

import com.wireguard.android.model.ObservableTunnel;
import com.wireguard.android.model.TunnelManager;
import com.wireguard.android.repository.DataRepository;
import com.wireguard.android.util.TunnelStore;
import com.wireguard.android.util.UserStore;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class MainViewModel extends ViewModel {
public boolean isUserLoggedIn(Context context){
return DataRepository.getRepositoryInstance().isUserLoggedIn(context);
return !UserStore.USER_TOKEN_DEFAULT_VALUE.equals(UserStore.getInstance(context).getToken());
}

public ObservableTunnel getTunnel(Context context, boolean stateTunnel) {
return DataRepository.getRepositoryInstance().getTunnel(context,stateTunnel);
}

public void buildRepositoryInstance(Context context, String url){
DataRepository.buildRepositoryInstance(context,url);
}

public String getUserURL(Context context){
return UserStore.getInstance(context).getUserURL();
}

public MutableLiveData<Boolean> connectWithPermission(final boolean checked , Context context) {
return DataRepository.getRepositoryInstance().connectWithPermission(checked,context);
}

public MutableLiveData<Boolean> connect(final Boolean checked , Context context) {
return DataRepository.getRepositoryInstance().connect(checked,context);
}

public ObservableTunnel getTunnel(Context context) {
return DataRepository.getRepositoryInstance().getTunnel(context);
public boolean isVPNConnected(Context context, boolean connectionStateFlag) {
return DataRepository.getRepositoryInstance().isVPNConnected(context,connectionStateFlag);
}
}

+ 2
- 27
ui/src/main/res/layout/activity_main.xml Bestand weergeven

@@ -35,40 +35,15 @@
android:id="@+id/bubbleStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/running"
android:text="@string/not_connected_bubble"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.565"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.183" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/this_device_status"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.133"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.255" />

<TextView
android:id="@+id/deviceStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/not_connected"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.811"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.254" />

<Button
android:id="@+id/connectButton"
android:layout_width="wrap_content"


+ 8
- 0
ui/src/main/res/values/strings.xml Bestand weergeven

@@ -242,4 +242,12 @@
<string name="disable_apps">Disable Apps</string>
<string name="turnInternet">Please turn on internet connection</string>
<string name="progress_bar_text">Loading</string>
<string name="not_connected_bubble">Not Connected</string>
<string name="connected_bubble">Connected</string>
<string name="failed_bubble">Failed</string>
<string name="disconnect">Disconnect</string>
<string name="hostname_not_valid">Hostname not valid</string>
<string name="login_failed">Login Failed</string>
<string name="cerificate_install">"Please install a certificate"</string>
<string name="success">Success</string>
</resources>

Laden…
Annuleren
Opslaan