|
|
@@ -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; |
|
|
@@ -34,7 +40,9 @@ 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; |
|
|
@@ -51,16 +59,18 @@ public class DataRepository { |
|
|
|
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 String BASE_URL = ""; |
|
|
|
private static final String TUNNEL_NAME = "BubbleVPN"; |
|
|
|
private static final int REQUEST_CODE_VPN_PERMISSION = 23491; |
|
|
|
|
|
|
|
private DataRepository(Context context,String url) { |
|
|
|
private DataRepository(Context context, String url) { |
|
|
|
BASE_URL = url; |
|
|
|
clientApi = ClientService.getInstance().createClientApi(url); |
|
|
|
compositeDisposable = new CompositeDisposable(); |
|
|
@@ -71,13 +81,13 @@ public class DataRepository { |
|
|
|
if (instance == null) { |
|
|
|
synchronized (DataRepository.class) { |
|
|
|
if (instance == null) { |
|
|
|
instance = new DataRepository(context,url); |
|
|
|
instance = new DataRepository(context, url); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void buildClientService(String url){ |
|
|
|
public void buildClientService(String url) { |
|
|
|
BASE_URL = url; |
|
|
|
clientApi = ClientService.getInstance().createClientApi(url); |
|
|
|
} |
|
|
@@ -261,7 +271,7 @@ public class DataRepository { |
|
|
|
Application.getTunnelManager().create(TUNNEL_NAME, config).whenComplete((observableTunnel, throwable) -> { |
|
|
|
if (observableTunnel != null) { |
|
|
|
TunnelStore.getInstance(context).setTunnel(TUNNEL_NAME, rawConfig); |
|
|
|
tunnelManager.setTunnelState(observableTunnel,State.DOWN); |
|
|
|
tunnelManager.setTunnelState(observableTunnel, State.DOWN); |
|
|
|
setMutableLiveData(StatusResource.success()); |
|
|
|
} else { |
|
|
|
setMutableLiveData(StatusResource.error(throwable.getMessage())); |
|
|
@@ -322,7 +332,7 @@ public class DataRepository { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public ObservableTunnel createTunnel(final Context context, final boolean stateTunnel){ |
|
|
|
private ObservableTunnel createTunnel(final Context context, final boolean stateTunnel) { |
|
|
|
//TODO implement config is null case |
|
|
|
Config config = null; |
|
|
|
try { |
|
|
@@ -330,45 +340,31 @@ public class DataRepository { |
|
|
|
} catch (final IOException | BadConfigException e) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
final String name = TunnelStore.getInstance(context).getTunnelName(); |
|
|
|
final String name = TunnelStore.getInstance(context).getTunnelName(); |
|
|
|
final ObservableTunnel tunnel; |
|
|
|
if(stateTunnel){ |
|
|
|
tunnel = new ObservableTunnel(tunnelManager, name, config, State.UP); |
|
|
|
if (stateTunnel) { |
|
|
|
tunnel = new ObservableTunnel(tunnelManager, name, config, State.UP); |
|
|
|
} else { |
|
|
|
tunnel = new ObservableTunnel(tunnelManager, name, config, State.DOWN); |
|
|
|
} |
|
|
|
else { |
|
|
|
tunnel = new ObservableTunnel(tunnelManager, name, config, State.DOWN); |
|
|
|
} |
|
|
|
tunnelManager.setTunnelState(tunnel,tunnel.getState()); |
|
|
|
tunnelManager.setTunnelState(tunnel, tunnel.getState()); |
|
|
|
|
|
|
|
return tunnel; |
|
|
|
} |
|
|
|
public void setUserURL(Context context, String url){ |
|
|
|
|
|
|
|
public void setUserURL(Context context, String url) { |
|
|
|
UserStore.getInstance(context).setUserURL(url); |
|
|
|
} |
|
|
|
|
|
|
|
public ObservableTunnel getTunnel(Context context, boolean connectionStateFlag) |
|
|
|
{ |
|
|
|
public ObservableTunnel getTunnel(Context context, boolean connectionStateFlag) { |
|
|
|
ObservableTunnel tunnel = tunnelManager.getLastUsedTunnel(); |
|
|
|
if(tunnel == null) { |
|
|
|
if (tunnel == null) { |
|
|
|
tunnel = createTunnel(context, connectionStateFlag); |
|
|
|
} |
|
|
|
return tunnel; |
|
|
|
} |
|
|
|
|
|
|
|
public MutableLiveData<Boolean> getTunnelState(ObservableTunnel pendingTunnel) |
|
|
|
{ |
|
|
|
MutableLiveData<Boolean> liveData = new MutableLiveData<>(); |
|
|
|
tunnelManager.getTunnelState(pendingTunnel).whenComplete((state, throwable) -> { |
|
|
|
if (state == State.DOWN) { |
|
|
|
liveData.postValue(true); |
|
|
|
} else if (state == State.UP) { |
|
|
|
liveData.postValue(false); |
|
|
|
} |
|
|
|
}); |
|
|
|
return liveData; |
|
|
|
} |
|
|
|
|
|
|
|
public MutableLiveData<byte[]> getCertificate(Context context){ |
|
|
|
public MutableLiveData<byte[]> getCertificate(Context context) { |
|
|
|
final MutableLiveData<byte[]> liveData = new MutableLiveData<>(); |
|
|
|
final Request request = new Request.Builder() |
|
|
|
.url(BASE_URL + ApiConstants.CERTIFICATE_URL) |
|
|
@@ -395,12 +391,57 @@ public class DataRepository { |
|
|
|
} catch (final CertificateEncodingException e) { |
|
|
|
liveData.postValue(new byte[]{}); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
} 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; |
|
|
|
} |
|
|
|
} |