Reviewed-on: https://git.bubblev.org/bubblev/bubble-droid/pulls/3pull/5/head
@@ -34,6 +34,10 @@ buildscript { | |||
gsonVersion = '2.8.6' | |||
retrofitVersion = '2.7.2' | |||
converterGsonVersion = '2.7.2' | |||
appcompatVersion = '1.1.0' | |||
constraintlayoutVersion = '1.1.3' | |||
lifecycleExtensionVersion = '2.2.0' | |||
lifecycleViewModelVersion = '2.2.0' | |||
groupName = 'com.wireguard.android' | |||
} | |||
@@ -1,6 +1,5 @@ | |||
distributionBase=GRADLE_USER_HOME | |||
distributionPath=wrapper/dists | |||
distributionSha256Sum=d08f7e24d061910382c2fda9915e6ed42dd1480ae2e99211f92c70190cb697e0 | |||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-all.zip | |||
zipStoreBase=GRADLE_USER_HOME | |||
zipStorePath=wrapper/dists |
@@ -86,6 +86,10 @@ dependencies { | |||
implementation "com.google.code.gson:gson:$gsonVersion" | |||
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" | |||
implementation "com.squareup.retrofit2:converter-gson:$converterGsonVersion" | |||
implementation "androidx.appcompat:appcompat:$appcompatVersion" | |||
implementation "androidx.constraintlayout:constraintlayout:$constraintlayoutVersion" | |||
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleExtensionVersion" | |||
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycleViewModelVersion" | |||
} | |||
tasks.withType(JavaCompile) { | |||
@@ -4,6 +4,7 @@ | |||
package="com.wireguard.android" | |||
android:installLocation="internalOnly"> | |||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | |||
<uses-permission android:name="android.permission.CAMERA" /> | |||
<uses-permission android:name="android.permission.INTERNET" /> | |||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> | |||
@@ -35,39 +36,35 @@ | |||
android:roundIcon="@mipmap/ic_launcher_round" | |||
android:supportsRtl="true" | |||
android:theme="@style/AppTheme"> | |||
<activity | |||
android:name=".activity.TunnelToggleActivity" | |||
android:theme="@style/NoBackgroundTheme" /> | |||
<activity android:name=".activity.MainActivity"> | |||
<intent-filter> | |||
<action android:name="android.intent.action.MAIN" /> | |||
<category android:name="android.intent.category.LAUNCHER" /> | |||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" /> | |||
</intent-filter> | |||
<intent-filter> | |||
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" /> | |||
</intent-filter> | |||
</activity> | |||
<activity android:name=".activity.LoginActivity" /> | |||
<activity | |||
android:name=".activity.TunnelToggleActivity" | |||
android:theme="@style/NoBackgroundTheme" /> | |||
<activity android:name=".activity.MainWireGuardActivity"> | |||
<!--TODO: Review if the filter is needed for the Bubble app"--> | |||
<!-- <intent-filter>--> | |||
<!-- <action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />--> | |||
<!-- </intent-filter>--> | |||
</activity> | |||
<activity | |||
android:name=".activity.SettingsActivity" | |||
android:label="@string/settings" | |||
android:parentActivityName=".activity.MainActivity" /> | |||
android:parentActivityName=".activity.MainWireGuardActivity" /> | |||
<activity | |||
android:name=".activity.TunnelCreatorActivity" | |||
android:label="@string/create_activity_title" | |||
android:parentActivityName=".activity.MainActivity" /> | |||
android:parentActivityName=".activity.MainWireGuardActivity" /> | |||
<activity | |||
android:name="com.journeyapps.barcodescanner.CaptureActivity" | |||
android:screenOrientation="fullSensor" | |||
tools:replace="screenOrientation" /> | |||
<activity | |||
android:name=".activity.LogViewerActivity" | |||
android:label="@string/log_viewer_title"> | |||
@@ -88,7 +85,6 @@ | |||
<action android:name="android.intent.action.BOOT_COMPLETED" /> | |||
</intent-filter> | |||
</receiver> | |||
<receiver | |||
android:name=".model.TunnelManager$IntentReceiver" | |||
android:permission="${applicationId}.permission.CONTROL_TUNNELS"> | |||
@@ -103,7 +99,6 @@ | |||
android:name=".QuickTileService" | |||
android:icon="@drawable/ic_tile" | |||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> | |||
<intent-filter> | |||
<action android:name="android.service.quicksettings.action.QS_TILE" /> | |||
</intent-filter> | |||
@@ -113,4 +108,5 @@ | |||
android:value="false" /> | |||
</service> | |||
</application> | |||
</manifest> | |||
</manifest> |
@@ -22,6 +22,7 @@ import com.wireguard.android.backend.GoBackend | |||
import com.wireguard.android.backend.WgQuickBackend | |||
import com.wireguard.android.configStore.FileConfigStore | |||
import com.wireguard.android.model.TunnelManager | |||
import com.wireguard.android.repository.DataRepository | |||
import com.wireguard.android.util.AsyncWorker | |||
import com.wireguard.android.util.ExceptionLoggers | |||
import com.wireguard.android.util.ModuleLoader | |||
@@ -59,6 +60,7 @@ 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) | |||
@@ -16,7 +16,7 @@ import android.util.Log | |||
import androidx.annotation.RequiresApi | |||
import androidx.databinding.Observable | |||
import androidx.databinding.Observable.OnPropertyChangedCallback | |||
import com.wireguard.android.activity.MainActivity | |||
import com.wireguard.android.activity.MainWireGuardActivity | |||
import com.wireguard.android.activity.TunnelToggleActivity | |||
import com.wireguard.android.backend.Tunnel | |||
import com.wireguard.android.model.ObservableTunnel | |||
@@ -65,7 +65,7 @@ class QuickTileService : TileService() { | |||
} | |||
} | |||
} else { | |||
val intent = Intent(this, MainActivity::class.java) | |||
val intent = Intent(this, MainWireGuardActivity::class.java) | |||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) | |||
startActivityAndCollapse(intent) | |||
} | |||
@@ -0,0 +1,79 @@ | |||
package com.wireguard.android.activity; | |||
import androidx.appcompat.app.AppCompatActivity; | |||
import androidx.lifecycle.Observer; | |||
import androidx.lifecycle.ViewModelProvider; | |||
import android.os.Bundle; | |||
import android.util.Log; | |||
import android.view.View; | |||
import android.view.View.OnClickListener; | |||
import android.widget.Button; | |||
import android.widget.EditText; | |||
import android.widget.Toast; | |||
import com.wireguard.android.R; | |||
import com.wireguard.android.api.ApiConstants; | |||
import com.wireguard.android.model.User; | |||
import com.wireguard.android.resource.StatusResource; | |||
import com.wireguard.android.viewmodel.LoginViewModel; | |||
import java.util.HashMap; | |||
public class LoginActivity extends AppCompatActivity { | |||
private LoginViewModel loginViewModel; | |||
private EditText bubbleName; | |||
private EditText userName; | |||
private EditText password; | |||
private Button sign; | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.activity_login); | |||
initUI(); | |||
loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class); | |||
} | |||
private void initUI() { | |||
initViews(); | |||
initListeners(); | |||
} | |||
private void initListeners() { | |||
sign.setOnClickListener(new OnClickListener() { | |||
@Override public void onClick(final View v) { | |||
final String username = userName.getText().toString().trim(); | |||
final String password = LoginActivity.this.password.getText().toString().trim(); | |||
login(username,password); | |||
} | |||
}); | |||
} | |||
private void initViews() { | |||
bubbleName = findViewById(R.id.bubbleName); | |||
userName = findViewById(R.id.userName); | |||
password = findViewById(R.id.password); | |||
sign = findViewById(R.id.signButton); | |||
} | |||
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"); | |||
break; | |||
case LOADING: | |||
Log.d("TAG","Loading"); | |||
break; | |||
case ERROR: | |||
Toast.makeText(LoginActivity.this,"Login Failed",Toast.LENGTH_SHORT).show(); | |||
Log.d("TAG","Error"); | |||
break; | |||
} | |||
} | |||
}); | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
package com.wireguard.android.activity; | |||
import androidx.appcompat.app.AppCompatActivity; | |||
import androidx.lifecycle.ViewModelProvider; | |||
import android.content.Intent; | |||
import android.os.Bundle; | |||
import com.wireguard.android.R; | |||
import com.wireguard.android.viewmodel.MainViewModel; | |||
public class MainActivity extends AppCompatActivity { | |||
private MainViewModel mainViewModel; | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
mainViewModel = new ViewModelProvider(this).get(MainViewModel.class); | |||
if (mainViewModel.isUserLoggedIn(this)) { | |||
setContentView(R.layout.activity_main); | |||
} else { | |||
Intent intent = new Intent(this, LoginActivity.class); | |||
startActivity(intent); | |||
finish(); | |||
} | |||
} | |||
} |
@@ -23,7 +23,7 @@ import com.wireguard.android.model.ObservableTunnel | |||
* WireGuard application, and contains several fragments for listing, viewing details of, and | |||
* editing the configuration and interface state of WireGuard tunnels. | |||
*/ | |||
class MainActivity : BaseActivity(), FragmentManager.OnBackStackChangedListener { | |||
class MainWireGuardActivity : BaseActivity(), FragmentManager.OnBackStackChangedListener { | |||
private var actionBar: ActionBar? = null | |||
private var isTwoPaneLayout = false | |||
@@ -2,4 +2,7 @@ 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 USERNAME = "username"; | |||
public static final String PASSWORD = "password"; | |||
} |
@@ -1,6 +1,19 @@ | |||
package com.wireguard.android.api.network; | |||
import com.wireguard.android.api.ApiConstants; | |||
import com.wireguard.android.model.User; | |||
import java.util.HashMap; | |||
import retrofit2.Call; | |||
import retrofit2.http.Body; | |||
import retrofit2.http.POST; | |||
/** | |||
Interface for API Calls | |||
**/ | |||
public interface ClientApi { | |||
@POST(ApiConstants.LOGIN_URL) | |||
Call<User> login(@Body HashMap<String,String> params); | |||
} |
@@ -0,0 +1,40 @@ | |||
package com.wireguard.android.model; | |||
public class AutoUpdatePolicy { | |||
private boolean driverUpdates; | |||
private boolean appUpdates; | |||
private boolean dataUpdates; | |||
private boolean newStuff; | |||
public void setDriverUpdates(final boolean driverUpdates) { | |||
this.driverUpdates = driverUpdates; | |||
} | |||
public void setAppUpdates(final boolean appUpdates) { | |||
this.appUpdates = appUpdates; | |||
} | |||
public void setDataUpdates(final boolean dataUpdates) { | |||
this.dataUpdates = dataUpdates; | |||
} | |||
public void setNewStuff(final boolean newStuff) { | |||
this.newStuff = newStuff; | |||
} | |||
public boolean isDriverUpdates() { | |||
return driverUpdates; | |||
} | |||
public boolean isAppUpdates() { | |||
return appUpdates; | |||
} | |||
public boolean isDataUpdates() { | |||
return dataUpdates; | |||
} | |||
public boolean isNewStuff() { | |||
return newStuff; | |||
} | |||
} |
@@ -0,0 +1,304 @@ | |||
package com.wireguard.android.model; | |||
import com.google.gson.annotations.Expose; | |||
import com.google.gson.annotations.SerializedName; | |||
public class User { | |||
@SerializedName("uuid") | |||
@Expose | |||
private String uuid; | |||
@SerializedName("related") | |||
@Expose | |||
private String related; | |||
@SerializedName("children") | |||
@Expose | |||
private String children; | |||
@SerializedName("name") | |||
@Expose | |||
private String name; | |||
@SerializedName("parent") | |||
@Expose | |||
private String parent; | |||
@SerializedName("url") | |||
@Expose | |||
private String url; | |||
@SerializedName("description") | |||
@Expose | |||
private String description; | |||
@SerializedName("locale") | |||
@Expose | |||
private String locale; | |||
@SerializedName("admin") | |||
@Expose | |||
private boolean admin; | |||
@SerializedName("sage") | |||
@Expose | |||
private boolean sage; | |||
@SerializedName("suspended") | |||
@Expose | |||
private boolean suspended; | |||
@SerializedName("locked") | |||
@Expose | |||
private boolean locked; | |||
@SerializedName("deleted") | |||
@Expose | |||
private String deleted; | |||
@SerializedName("lastLogin") | |||
@Expose | |||
private long lastLogin; | |||
@SerializedName("firstLogin") | |||
@Expose | |||
private String firstLogin; | |||
@SerializedName("termsAgreed") | |||
@Expose | |||
private long termsAgreed; | |||
@SerializedName("preferredPlan") | |||
@Expose | |||
private String preferredPlan; | |||
@SerializedName("autoUpdatePolicy") | |||
@Expose | |||
private AutoUpdatePolicy autoUpdatePolicy; | |||
@SerializedName("promoError") | |||
@Expose | |||
private String promoError; | |||
@SerializedName("apiToken") | |||
@Expose | |||
private String apiToken; | |||
@SerializedName("policy") | |||
@Expose | |||
private String policy; | |||
@SerializedName("sendWelcomeEmail") | |||
@Expose | |||
private String sendWelcomeEmail; | |||
@SerializedName("loginRequest") | |||
@Expose | |||
private String loginRequest; | |||
@SerializedName("multifactorAuth") | |||
@Expose | |||
private String multifactorAuth; | |||
@SerializedName("remoteHost") | |||
@Expose | |||
private String remoteHost; | |||
@SerializedName("token") | |||
@Expose | |||
private String token; | |||
@SerializedName("shortId") | |||
@Expose | |||
private String shortId; //27 | |||
public void setUuid(final String uuid) { | |||
this.uuid = uuid; | |||
} | |||
public void setRelated(final String related) { | |||
this.related = related; | |||
} | |||
public void setChildren(final String children) { | |||
this.children = children; | |||
} | |||
public void setName(final String name) { | |||
this.name = name; | |||
} | |||
public void setParent(final String parent) { | |||
this.parent = parent; | |||
} | |||
public void setUrl(final String url) { | |||
this.url = url; | |||
} | |||
public void setDescription(final String description) { | |||
this.description = description; | |||
} | |||
public void setLocale(final String locale) { | |||
this.locale = locale; | |||
} | |||
public void setAdmin(final boolean admin) { | |||
this.admin = admin; | |||
} | |||
public void setSage(final boolean sage) { | |||
this.sage = sage; | |||
} | |||
public void setSuspended(final boolean suspended) { | |||
this.suspended = suspended; | |||
} | |||
public void setLocked(final boolean locked) { | |||
this.locked = locked; | |||
} | |||
public void setDeleted(final String deleted) { | |||
this.deleted = deleted; | |||
} | |||
public void setLastLogin(final long lastLogin) { | |||
this.lastLogin = lastLogin; | |||
} | |||
public void setFirstLogin(final String firstLogin) { | |||
this.firstLogin = firstLogin; | |||
} | |||
public void setTermsAgreed(final long termsAgreed) { | |||
this.termsAgreed = termsAgreed; | |||
} | |||
public void setPreferredPlan(final String preferredPlan) { | |||
this.preferredPlan = preferredPlan; | |||
} | |||
public void setAutoUpdatePolicy(final AutoUpdatePolicy autoUpdatePolicy) { | |||
this.autoUpdatePolicy = autoUpdatePolicy; | |||
} | |||
public void setPromoError(final String promoError) { | |||
this.promoError = promoError; | |||
} | |||
public void setApiToken(final String apiToken) { | |||
this.apiToken = apiToken; | |||
} | |||
public void setPolicy(final String policy) { | |||
this.policy = policy; | |||
} | |||
public void setSendWelcomeEmail(final String sendWelcomeEmail) { | |||
this.sendWelcomeEmail = sendWelcomeEmail; | |||
} | |||
public void setLoginRequest(final String loginRequest) { | |||
this.loginRequest = loginRequest; | |||
} | |||
public void setMultifactorAuth(final String multifactorAuth) { | |||
this.multifactorAuth = multifactorAuth; | |||
} | |||
public void setRemoteHost(final String remoteHost) { | |||
this.remoteHost = remoteHost; | |||
} | |||
public void setToken(final String token) { | |||
this.token = token; | |||
} | |||
public void setShortId(final String shortId) { | |||
this.shortId = shortId; | |||
} | |||
public String getUuid() { | |||
return uuid; | |||
} | |||
public String getRelated() { | |||
return related; | |||
} | |||
public String getChildren() { | |||
return children; | |||
} | |||
public String getName() { | |||
return name; | |||
} | |||
public String getParent() { | |||
return parent; | |||
} | |||
public String getUrl() { | |||
return url; | |||
} | |||
public String getDescription() { | |||
return description; | |||
} | |||
public String getLocale() { | |||
return locale; | |||
} | |||
public boolean isAdmin() { | |||
return admin; | |||
} | |||
public boolean isSage() { | |||
return sage; | |||
} | |||
public boolean isSuspended() { | |||
return suspended; | |||
} | |||
public boolean isLocked() { | |||
return locked; | |||
} | |||
public String getDeleted() { | |||
return deleted; | |||
} | |||
public long getLastLogin() { | |||
return lastLogin; | |||
} | |||
public String getFirstLogin() { | |||
return firstLogin; | |||
} | |||
public long getTermsAgreed() { | |||
return termsAgreed; | |||
} | |||
public String getPreferredPlan() { | |||
return preferredPlan; | |||
} | |||
public AutoUpdatePolicy getAutoUpdatePolicy() { | |||
return autoUpdatePolicy; | |||
} | |||
public String getPromoError() { | |||
return promoError; | |||
} | |||
public String getApiToken() { | |||
return apiToken; | |||
} | |||
public String getPolicy() { | |||
return policy; | |||
} | |||
public String getSendWelcomeEmail() { | |||
return sendWelcomeEmail; | |||
} | |||
public String getLoginRequest() { | |||
return loginRequest; | |||
} | |||
public String getMultifactorAuth() { | |||
return multifactorAuth; | |||
} | |||
public String getRemoteHost() { | |||
return remoteHost; | |||
} | |||
public String getToken() { | |||
return token; | |||
} | |||
public String getShortId() { | |||
return shortId; | |||
} | |||
} |
@@ -1,12 +1,27 @@ | |||
package com.wireguard.android.repository; | |||
import android.content.Context; | |||
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.model.User; | |||
import com.wireguard.android.resource.StatusResource; | |||
import com.wireguard.android.util.UserStore; | |||
import java.util.HashMap; | |||
import androidx.lifecycle.MutableLiveData; | |||
import retrofit2.Call; | |||
import retrofit2.Callback; | |||
import retrofit2.Response; | |||
public class DataRepository { | |||
private static volatile DataRepository instance; | |||
private ClientApi clientApi; | |||
public static final String NO_INTERNET_CONNECTION = "no_internet_connection"; | |||
private DataRepository() | |||
{ | |||
clientApi = ClientService.getInstance().createClientApi(); | |||
@@ -26,4 +41,46 @@ public class DataRepository { | |||
return instance; | |||
} | |||
public MutableLiveData<StatusResource<User>> login(String username,String password , Context context){ | |||
return new NetworkBoundStatusResource<User>(){ | |||
@Override protected void createCall() { | |||
HashMap<String,String> data = new HashMap<>(); | |||
data.put(ApiConstants.USERNAME,username); | |||
data.put(ApiConstants.PASSWORD,password); | |||
clientApi.login(data).enqueue(new Callback<User>() { | |||
@Override public void onResponse(final Call<User> call, final Response<User> response) { | |||
if(response.isSuccessful()) { | |||
String token = response.body().getToken(); | |||
UserStore.getInstance(context).setToken(token); | |||
setMutableLiveData(StatusResource.success()); | |||
} | |||
else { | |||
String errorMessage = createErrorMessage(call,response); | |||
setMutableLiveData(StatusResource.error(errorMessage)); | |||
} | |||
} | |||
@Override public void onFailure(final Call<User> call, final Throwable t) { | |||
if(t instanceof Exception){ | |||
setMutableLiveData(StatusResource.error(NO_INTERNET_CONNECTION)); | |||
} | |||
} | |||
}); | |||
} | |||
}.getMutableLiveData(); | |||
} | |||
private String createErrorMessage(Call call, retrofit2.Response response) { | |||
return "Error: User agent: " + System.getProperty("http.agent") + ", Request body: " + call.request().body() + ", URL: " + | |||
call.request().url() + ", Code: " + response.code() + ", Message: " + | |||
response.message(); | |||
} | |||
public boolean isUserLoggedIn(Context context) | |||
{ | |||
return !UserStore.USER_TOKEN_DEFAULT_VALUE.equals(UserStore.getInstance(context).getToken()); | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
package com.wireguard.android.util; | |||
import android.content.Context; | |||
import android.content.SharedPreferences; | |||
public class UserStore { | |||
private static UserStore instance; | |||
private SharedPreferences sharedPreferences; | |||
private static final String USER_SHARED_PREF = "com.wireguard.android.util.bubbleUserSharedPref"; | |||
private static final String USER_DATA_KEY = "com.wireguard.android.util.bubbleUserResponse"; | |||
public static final String USER_TOKEN_DEFAULT_VALUE = ""; | |||
public static UserStore getInstance(Context context) { | |||
if (instance == null) { | |||
synchronized (UserStore.class) { | |||
if (instance == null) { | |||
instance = new UserStore(context); | |||
} | |||
} | |||
} | |||
return instance; | |||
} | |||
private UserStore(Context context) { | |||
sharedPreferences = context.getSharedPreferences(USER_SHARED_PREF, Context.MODE_PRIVATE); | |||
} | |||
public void setToken(String response) { | |||
sharedPreferences.edit().putString(USER_DATA_KEY, response).apply(); | |||
} | |||
public String getToken() { | |||
return sharedPreferences.getString(USER_DATA_KEY, USER_TOKEN_DEFAULT_VALUE); | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
package com.wireguard.android.viewmodel; | |||
import android.content.Context; | |||
import com.wireguard.android.model.User; | |||
import com.wireguard.android.repository.DataRepository; | |||
import com.wireguard.android.resource.StatusResource; | |||
import java.util.HashMap; | |||
import androidx.lifecycle.LiveData; | |||
import androidx.lifecycle.ViewModel; | |||
public class LoginViewModel extends ViewModel { | |||
public LiveData<StatusResource<User>> login(String username,String password, Context context){ | |||
return DataRepository.getRepositoryInstance().login(username,password,context); | |||
} | |||
} |
@@ -0,0 +1,11 @@ | |||
package com.wireguard.android.viewmodel; | |||
import android.content.Context; | |||
import com.wireguard.android.repository.DataRepository; | |||
import androidx.lifecycle.ViewModel; | |||
public class MainViewModel extends ViewModel { | |||
public boolean isUserLoggedIn(Context context){ | |||
return DataRepository.getRepositoryInstance().isUserLoggedIn(context); | |||
} | |||
} |
@@ -3,7 +3,7 @@ | |||
xmlns:tools="http://schemas.android.com/tools" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
tools:context=".activity.MainActivity"> | |||
tools:context=".activity.MainWireGuardActivity"> | |||
<LinearLayout | |||
android:id="@+id/master_detail_wrapper" | |||
@@ -0,0 +1,90 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<androidx.constraintlayout.widget.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" | |||
tools:context="com.wireguard.android.activity.LoginActivity"> | |||
<TextView | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/bubble_name" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
app:layout_constraintVertical_bias="0.105" /> | |||
<EditText | |||
android:id="@+id/bubbleName" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:textSize="18sp" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.504" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
app:layout_constraintVertical_bias="0.159" /> | |||
<TextView | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_marginTop="160dp" | |||
android:text="@string/user_name" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.482" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
<EditText | |||
android:id="@+id/userName" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:textSize="18sp" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.504" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
app:layout_constraintVertical_bias="0.276" /> | |||
<TextView | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/password" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.472" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
app:layout_constraintVertical_bias="0.363" /> | |||
<EditText | |||
android:id="@+id/password" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:inputType="textPassword" | |||
android:textSize="18sp" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.51" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
app:layout_constraintVertical_bias="0.435" /> | |||
<Button | |||
android:id="@+id/signButton" | |||
android:layout_width="95dp" | |||
android:layout_height="49dp" | |||
android:layout_marginBottom="272dp" | |||
android:background="@color/secondary_color" | |||
android:text="@string/sign_in" | |||
android:textSize="15sp" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" /> | |||
</androidx.constraintlayout.widget.ConstraintLayout> |
@@ -0,0 +1,84 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<androidx.constraintlayout.widget.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" | |||
tools:context="com.wireguard.android.activity.MainActivity"> | |||
<TextView | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/my_bubble" | |||
android:textSize="20sp" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.498" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
app:layout_constraintVertical_bias="0.085" /> | |||
<TextView | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/bubble_status" | |||
android:textSize="20sp" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.112" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
app:layout_constraintVertical_bias="0.183" /> | |||
<TextView | |||
android:id="@+id/bubbleStatus" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/running" | |||
android:textSize="20sp" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.565" | |||
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" | |||
android:layout_height="wrap_content" | |||
android:layout_marginTop="264dp" | |||
android:text="@string/connect" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.492" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
</androidx.constraintlayout.widget.ConstraintLayout> |
@@ -5,7 +5,7 @@ | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:fitsSystemWindows="true" | |||
tools:context=".activity.MainActivity"> | |||
tools:context=".activity.MainWireGuardActivity"> | |||
<androidx.fragment.app.FragmentContainerView | |||
android:id="@+id/detail_container" | |||
@@ -226,4 +226,19 @@ | |||
<string name="biometric_prompt_private_key_title">Authenticate to view private key</string> | |||
<string name="biometric_auth_error">Authentication failure</string> | |||
<string name="biometric_auth_error_reason">Authentication failure: %s</string> | |||
<!--Bubble constants--> | |||
<string name="bubble_name">Bubble Name</string> | |||
<string name="user_name">User Name:</string> | |||
<string name="password">Password:</string> | |||
<string name="sign_in">SIGN IN</string> | |||
<string name="don_t_have_a_bubble">Don\'t have a Bubble?</string> | |||
<string name="start_new_bubble">Start New Bubble</string> | |||
<string name="my_bubble">My Bubble</string> | |||
<string name="bubble_status">Bubble Status:</string> | |||
<string name="running">Running</string> | |||
<string name="this_device_status">This Device Status:</string> | |||
<string name="not_connected">Not Connected</string> | |||
<string name="connect">Connect</string> | |||
<string name="disable_apps">Disable Apps</string> | |||
<string name="turnInternet">Please turn on internet connection</string> | |||
</resources> |