summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
authorFup Duck <fupduck@sacknagel.com>2018-01-09 19:54:57 +0100
committerFup Duck <fupduck@sacknagel.com>2018-01-09 19:54:57 +0100
commit8806e6ae477e0b20806851f5f8f3c0141a63ad9d (patch)
treeadeb3d5dba2bff20880bd5101b0a16bceb747889 /app/src
parent3addd20598f7fee2d41a24d64b375a2f63874457 (diff)
create LoginActivity and SignUpActivity
Diffstat (limited to 'app/src')
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java18
-rw-r--r--app/src/main/AndroidManifest.xml19
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java30
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Dashboard.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/LoginActivity.java29
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java134
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/SignupActivity.java66
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java3
-rw-r--r--app/src/main/res/layout/a_login.xml29
-rw-r--r--app/src/main/res/layout/a_signup.xml29
-rw-r--r--app/src/main/res/layout/provider_credentials_login.xml36
-rw-r--r--app/src/main/res/layout/provider_credentials_signup.xml24
-rw-r--r--app/src/main/res/layout/provider_header.xml17
-rw-r--r--app/src/main/res/values/colors.xml2
-rw-r--r--app/src/main/res/values/strings.xml3
-rw-r--r--app/src/main/res/values/styles.xml5
-rw-r--r--app/src/main/res/values/themes.xml8
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/ProviderDetailActivity.java3
20 files changed, 438 insertions, 29 deletions
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
index c97daea6..363a90fe 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
@@ -1,6 +1,5 @@
package se.leap.bitmaskclient;
-import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
@@ -17,10 +16,9 @@ import org.json.JSONObject;
import java.util.ArrayList;
-import butterknife.ButterKnife;
import butterknife.InjectView;
-public class ProviderDetailActivity extends Activity {
+public class ProviderDetailActivity extends ButterKnifeActivity {
final public static String TAG = "providerDetailActivity";
private SharedPreferences preferences;
@@ -41,7 +39,6 @@ public class ProviderDetailActivity extends Activity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.provider_detail_fragment);
- ButterKnife.inject(this);
preferences = getSharedPreferences(Constants.SHARED_PREFERENCES, MODE_PRIVATE);
try {
@@ -71,15 +68,18 @@ public class ProviderDetailActivity extends Activity {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String text = ((TextView) view).getText().toString();
+ Intent intent;
if (text.equals(getString(R.string.login_button))) {
Log.d(TAG, "login selected");
+ intent = new Intent(getApplicationContext(), LoginActivity.class);
} else if (text.equals(getString(R.string.signup_button))) {
Log.d(TAG, "signup selected");
- } else if (text.equals(getString(R.string.use_anonymously_button))) {
- Intent intent = new Intent(getApplicationContext(), MainActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
- startActivity(intent);
+ intent = new Intent(getApplicationContext(), SignupActivity.class);
+ } else {
+ intent = new Intent(getApplicationContext(), MainActivity.class);
}
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ startActivity(intent);
}
});
} catch (JSONException e) {
@@ -108,7 +108,7 @@ public class ProviderDetailActivity extends Activity {
@Override
public void onBackPressed() {
SharedPreferences.Editor editor = preferences.edit();
- editor.remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(Constants.PROVIDER_ALLOW_ANONYMOUS).remove(Constants.PROVIDER_KEY).apply();
+ editor.remove(Provider.KEY).remove(ProviderListContent.ProviderItem.DANGER_ON).remove(Constants.PROVIDER_ALLOW_ANONYMOUS).remove(Constants.PROVIDER_KEY).apply();
super.onBackPressed();
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8407d76d..14ac77ef 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,7 +38,7 @@
android:icon="@drawable/icon"
android:label="@string/app_name"
android:logo="@drawable/icon"
- android:theme="@style/AppTheme">
+ android:theme="@style/BitmaskTheme">
<service
android:name=".eip.VoidVpnService"
android:permission="android.permission.BIND_VPN_SERVICE">
@@ -71,12 +71,12 @@
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity
android:name="de.blinkt.openvpn.LaunchVPN"
- android:label="@string/vpn_launch_title"></activity>
+ android:label="@string/vpn_launch_title" />
<activity
android:name=".Dashboard"
android:label="@string/app_name"
android:launchMode="singleTop"
- android:uiOptions="splitActionBarWhenNarrow"></activity>
+ android:uiOptions="splitActionBarWhenNarrow" />
<activity
android:name=".StartActivity"
android:label="@string/app_name"
@@ -89,6 +89,11 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/title_activity_main" />
+
<activity
android:name=".ConfigurationWizard"
android:label="@string/configuration_wizard_title" />
@@ -97,6 +102,10 @@
android:name=".ProviderDetailActivity"
android:label="@string/provider_details_title" />
+ <activity android:name=".LoginActivity" />
+ <activity android:name=".SignupActivity"
+ android:theme="@style/BitmaskTheme"/>
+
<service
android:name=".eip.EIP"
android:exported="false">
@@ -111,10 +120,6 @@
<action android:name="se.leap.bitmaskclient.EIP.IS_RUNNING"/>
</intent-filter>
</service>
-
- <activity
- android:name=".MainActivity"
- android:label="@string/title_activity_main"></activity>
</application>
</manifest> \ No newline at end of file
diff --git a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java
index 601615b6..9253cfe6 100644
--- a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java
+++ b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java
@@ -69,7 +69,7 @@ import static android.view.View.VISIBLE;
* @author cyberta
*/
-public abstract class BaseConfigurationWizard extends AppCompatActivity
+public abstract class BaseConfigurationWizard extends ButterKnifeActivity
implements NewProviderDialog.NewProviderDialogInterface, DownloadFailedDialog.DownloadFailedDialogInterface, ProviderAPIResultReceiver.Receiver {
@InjectView(R.id.progressbar_configuration_wizard)
protected ProgressBar mProgressBar;
@@ -166,7 +166,6 @@ public abstract class BaseConfigurationWizard extends AppCompatActivity
private void setUpInitialUI() {
setContentView(R.layout.configuration_wizard_activity);
- ButterKnife.inject(this);
hideProgressBar();
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java b/app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java
new file mode 100644
index 00000000..41164463
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java
@@ -0,0 +1,30 @@
+package se.leap.bitmaskclient;
+
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+
+import butterknife.ButterKnife;
+
+/**
+ * Automatically inject with ButterKnife after calling setContentView
+ */
+
+public abstract class ButterKnifeActivity extends AppCompatActivity {
+
+ @Override
+ public void setContentView(View view) {
+ super.setContentView(view);
+ ButterKnife.inject(this);
+ }
+
+ @Override
+ public void setContentView(int layoutResID) {
+ super.setContentView(layoutResID);
+ ButterKnife.inject(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ }
+}
diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
index 8c33a6cd..b36c8cc2 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
@@ -57,7 +57,7 @@ import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;
* @author Sean Leonard <meanderingcode@aetherislands.net>
* @author parmegv
*/
-public class Dashboard extends AppCompatActivity {
+public class Dashboard extends ButterKnifeActivity {
public static final String TAG = Dashboard.class.getSimpleName();
@@ -280,7 +280,6 @@ public class Dashboard extends AppCompatActivity {
// just to start services and destroy them afterwards
private void buildDashboard(boolean hideAndTurnOnEipOnBoot) {
setContentView(R.layout.dashboard);
- ButterKnife.inject(this);
provider_name.setText(provider.getDomain());
diff --git a/app/src/main/java/se/leap/bitmaskclient/LoginActivity.java b/app/src/main/java/se/leap/bitmaskclient/LoginActivity.java
new file mode 100644
index 00000000..1b36d807
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/LoginActivity.java
@@ -0,0 +1,29 @@
+package se.leap.bitmaskclient;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+
+import butterknife.OnClick;
+
+/**
+ * Created by fupduck on 09.01.18.
+ */
+
+public class LoginActivity extends ProviderCredentialsBaseActivity {
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.a_login);
+
+ setProviderHeaderText("providerNAME");
+ setProviderHeaderLogo(R.drawable.mask);
+ }
+
+ @Override
+ @OnClick(R.id.button)
+ void handleButton() {
+ login(getUsername(), getPassword());
+ }
+
+}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
new file mode 100644
index 00000000..c61b078f
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
@@ -0,0 +1,134 @@
+package se.leap.bitmaskclient;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.design.widget.TextInputEditText;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import butterknife.InjectView;
+import butterknife.OnClick;
+import se.leap.bitmaskclient.userstatus.SessionDialog;
+import se.leap.bitmaskclient.userstatus.User;
+
+/**
+ * Created by fupduck on 09.01.18.
+ */
+
+public abstract class ProviderCredentialsBaseActivity extends ButterKnifeActivity {
+
+ protected ProviderAPIResultReceiver providerAPIResultReceiver;
+
+ @InjectView(R.id.provider_header_logo)
+ ImageView providerHeaderLogo;
+
+ @InjectView(R.id.provider_header_text)
+ TextView providerHeaderText;
+
+ @InjectView(R.id.provider_credentials_username)
+ TextInputEditText providerCredentialsUsername;
+
+ @InjectView(R.id.provider_credentials_password)
+ TextInputEditText providerCredentialsPassword;
+
+ @InjectView(R.id.button)
+ Button providerCredentialsButton;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), new ProviderCredentialsReceiver(this));
+
+ }
+
+ @OnClick(R.id.button)
+ abstract void handleButton();
+
+ protected void setProviderHeaderLogo(@DrawableRes int providerHeaderLogo) {
+ this.providerHeaderLogo.setImageResource(providerHeaderLogo);
+ }
+
+ protected void setProviderHeaderText(String providerHeaderText) {
+ this.providerHeaderText.setText(providerHeaderText);
+ }
+
+ protected void setProviderHeaderText(@StringRes int providerHeaderText) {
+ this.providerHeaderText.setText(providerHeaderText);
+ }
+
+ protected void setButtonText(@StringRes int buttonText) {
+ providerCredentialsButton.setText(buttonText);
+ }
+
+ String getUsername() {
+ return providerCredentialsUsername.getText().toString();
+ }
+
+ String getPassword() {
+ return providerCredentialsPassword.getText().toString();
+ }
+
+ void login(String username, String password) {
+ User.setUserName(username);
+ Bundle parameters = bundlePassword(password);
+ ProviderAPICommand.execute(parameters, ProviderAPI.LOG_IN, providerAPIResultReceiver);
+ }
+
+ public void signUp(String username, String password) {
+ User.setUserName(username);
+ Bundle parameters = bundlePassword(password);
+ ProviderAPICommand.execute(parameters, ProviderAPI.SIGN_UP, providerAPIResultReceiver);
+ }
+ protected Bundle bundlePassword(String password) {
+ Bundle parameters = new Bundle();
+ if (!password.isEmpty())
+ parameters.putString(SessionDialog.PASSWORD, password);
+ return parameters;
+ }
+
+ public static class ProviderCredentialsReceiver implements ProviderAPIResultReceiver.Receiver{
+
+ private ProviderCredentialsBaseActivity activity;
+
+ ProviderCredentialsReceiver(ProviderCredentialsBaseActivity activity) {
+ this.activity = activity;
+ }
+
+ @Override
+ public void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == ProviderAPI.SUCCESSFUL_SIGNUP) {
+ String username = resultData.getString(SessionDialog.USERNAME);
+ String password = resultData.getString(SessionDialog.PASSWORD);
+ activity.login(username, password);
+ } else if (resultCode == ProviderAPI.FAILED_SIGNUP) {
+ //MainActivity.sessionDialog(resultData);
+ } else if (resultCode == ProviderAPI.SUCCESSFUL_LOGIN) {
+ Intent intent = new Intent(activity, MainActivity.class);
+ activity.startActivity(intent);
+ } else if (resultCode == ProviderAPI.FAILED_LOGIN) {
+ //MainActivity.sessionDialog(resultData);
+// TODO MOVE
+// } else if (resultCode == ProviderAPI.SUCCESSFUL_LOGOUT) {
+// if (switching_provider) activity.switchProvider();
+// } else if (resultCode == ProviderAPI.LOGOUT_FAILED) {
+// activity.setResult(RESULT_CANCELED);
+// } else if (resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
+// activity.eip_fragment.updateEipService();
+// activity.setResult(RESULT_OK);
+// } else if (resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) {
+// activity.setResult(RESULT_CANCELED);
+// } else if (resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) {
+// activity.eip_fragment.updateEipService();
+// activity.setResult(RESULT_OK);
+// } else if (resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE) {
+// activity.setResult(RESULT_CANCELED);
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/se/leap/bitmaskclient/SignupActivity.java b/app/src/main/java/se/leap/bitmaskclient/SignupActivity.java
new file mode 100644
index 00000000..f6344065
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/SignupActivity.java
@@ -0,0 +1,66 @@
+package se.leap.bitmaskclient;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.TextInputEditText;
+import android.support.design.widget.TextInputLayout;
+import android.text.Editable;
+import android.text.TextWatcher;
+
+import butterknife.InjectView;
+import butterknife.OnClick;
+
+/**
+ * Create an account with a provider
+ */
+
+public class SignupActivity extends ProviderCredentialsBaseActivity {
+
+ @InjectView(R.id.provider_credentials_password_verification)
+ TextInputEditText providerCredentialsPasswordVerification;
+
+ @InjectView(R.id.provider_credentials_password_verification_layout)
+ TextInputLayout providerCredentialsPasswordVerificationLayout;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.a_signup);
+
+ setProviderHeaderText("providerNAME");
+ setProviderHeaderLogo(R.drawable.mask);
+
+ setButtonText(R.string.signup_button);
+
+ providerCredentialsPasswordVerification.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if(getPassword().equals(getPasswordVerification())) {
+ providerCredentialsPasswordVerificationLayout.setError(null);
+ } else {
+ providerCredentialsPasswordVerificationLayout.setError(getString(R.string.password_mismatch));
+ }
+ }
+ });
+ }
+
+ @Override
+ @OnClick(R.id.button)
+ void handleButton() {
+ if (getPassword().equals(getPasswordVerification())) {
+ signUp(getUsername(), getPassword());
+ }
+ }
+
+ private String getPasswordVerification() {
+ return providerCredentialsPasswordVerification.getText().toString();
+ }
+}
diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java
index 1256c619..d86da957 100644
--- a/app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java
+++ b/app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java
@@ -51,7 +51,7 @@ public class SessionDialog extends DialogFragment {
final public static String USERNAME = "username";
final public static String PASSWORD = "password";
- public static enum ERRORS {
+ public enum ERRORS {
USERNAME_MISSING,
PASSWORD_INVALID_LENGTH,
RISEUP_WARNING
@@ -156,9 +156,9 @@ public class SessionDialog extends DialogFragment {
* @author parmegv
*/
public interface SessionDialogInterface {
- public void logIn(String username, String password);
+ void logIn(String username, String password);
- public void signUp(String username, String password);
+ void signUp(String username, String password);
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java
index a6439a16..07c102e4 100644
--- a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java
@@ -2,7 +2,6 @@ package se.leap.bitmaskclient.userstatus;
import android.content.Context;
import android.os.Bundle;
-import android.os.Handler;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
@@ -18,7 +17,6 @@ import java.util.Observer;
import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
-import se.leap.bitmaskclient.Dashboard;
import se.leap.bitmaskclient.MainActivity;
import se.leap.bitmaskclient.Provider;
import se.leap.bitmaskclient.ProviderAPI;
@@ -74,7 +72,6 @@ public class UserStatusFragment extends Fragment implements Observer, SessionDia
@Override
public void onAttach(Context activity) {
super.onAttach(activity);
- providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler(), Dashboard.dashboardReceiver);
}
public void restoreSessionStatus(Bundle savedInstanceState) {
diff --git a/app/src/main/res/layout/a_login.xml b/app/src/main/res/layout/a_login.xml
new file mode 100644
index 00000000..5ecb807c
--- /dev/null
+++ b/app/src/main/res/layout/a_login.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ layout="@layout/provider_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <include layout="@layout/provider_credentials_login"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/login_button"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"/>
+
+ </RelativeLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/a_signup.xml b/app/src/main/res/layout/a_signup.xml
new file mode 100644
index 00000000..edcaea45
--- /dev/null
+++ b/app/src/main/res/layout/a_signup.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ layout="@layout/provider_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <include layout="@layout/provider_credentials_signup"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/login_button"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"/>
+
+ </RelativeLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/provider_credentials_login.xml b/app/src/main/res/layout/provider_credentials_login.xml
new file mode 100644
index 00000000..9c52b9b5
--- /dev/null
+++ b/app/src/main/res/layout/provider_credentials_login.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto" >
+
+ <android.support.design.widget.TextInputLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/auth_username"
+ app:errorEnabled="true">
+
+ <android.support.design.widget.TextInputEditText
+ android:id="@+id/provider_credentials_username"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:inputType="text" />
+
+ </android.support.design.widget.TextInputLayout>
+
+ <android.support.design.widget.TextInputLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:passwordToggleEnabled="true"
+ android:hint="@string/password"
+ app:errorEnabled="true">
+
+ <android.support.design.widget.TextInputEditText
+ android:id="@+id/provider_credentials_password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textPassword"
+ />
+
+ </android.support.design.widget.TextInputLayout>
+
+</merge> \ No newline at end of file
diff --git a/app/src/main/res/layout/provider_credentials_signup.xml b/app/src/main/res/layout/provider_credentials_signup.xml
new file mode 100644
index 00000000..c2e3dcd3
--- /dev/null
+++ b/app/src/main/res/layout/provider_credentials_signup.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto" >
+
+ <include layout="@layout/provider_credentials_login" />
+
+ <android.support.design.widget.TextInputLayout
+ android:id="@+id/provider_credentials_password_verification_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:passwordToggleEnabled="true"
+ android:hint="@string/password"
+ app:errorEnabled="true">
+
+ <android.support.design.widget.TextInputEditText
+ android:id="@+id/provider_credentials_password_verification"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textPassword"
+ />
+
+ </android.support.design.widget.TextInputLayout>
+
+</merge> \ No newline at end of file
diff --git a/app/src/main/res/layout/provider_header.xml b/app/src/main/res/layout/provider_header.xml
new file mode 100644
index 00000000..89cbd7b2
--- /dev/null
+++ b/app/src/main/res/layout/provider_header.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto" >
+
+ <ImageView
+ android:id="@+id/provider_header_logo"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:srcCompat="@drawable/mask" />
+
+ <TextView
+ android:id="@+id/provider_header_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="" />
+
+</merge>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 49415189..a8a63e4b 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -3,6 +3,8 @@
<color name="colorPrimary">#b39ddb</color>
<color name="colorPrimaryDark">#ac97d2</color>
<color name="colorBackground">#fffafafa</color>
+ <color name="colorError">#ef9a9a</color>
+ <color name="colorSuccess">#a5d6a7</color>
<color name="red200">#ef9a9a</color>
<color name="pink200">#f48fb1</color>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 22736245..134d67ab 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -27,7 +27,10 @@
<string name="use_anonymously_button">Use anonymously</string>
<string name="username_hint">username</string>
<string name="username_ask">Please enter your username</string>
+ <string name="password_ask">Please enter your password</string>
<string name="password_hint">password</string>
+ <string name="password_match">Passwords match</string>
+ <string name="password_mismatch">Passwords do not match</string>
<string name="user_message">User message</string>
<string name="about_fragment_title">About Bitmask</string>
<string name="error_srp_math_error_user_message">Try again: server math error.</string>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 4cdf2c00..b4e81bc4 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -59,4 +59,9 @@
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
+
+ <style name="BitmaskButton" parent="android:Widget.Button">
+ <item name="android:textAllCaps">true</item>
+ <item name="android:color">@color/colorPrimary</item>
+ </style>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index a64779e5..76cfd866 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,12 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
+ <style name="BitmaskTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
+ <item name="textColorError">@color/colorError</item>
+
+ <item name="android:buttonStyle">@style/BitmaskButton</item>
+
</style>
+
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="android:windowBackground">@drawable/splash_page</item>
</style>
+
</resources>
diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderDetailActivity.java b/app/src/production/java/se/leap/bitmaskclient/ProviderDetailActivity.java
index 0c5b1957..ae50fc8a 100644
--- a/app/src/production/java/se/leap/bitmaskclient/ProviderDetailActivity.java
+++ b/app/src/production/java/se/leap/bitmaskclient/ProviderDetailActivity.java
@@ -20,7 +20,7 @@ import java.util.ArrayList;
import butterknife.ButterKnife;
import butterknife.InjectView;
-public class ProviderDetailActivity extends Activity {
+public class ProviderDetailActivity extends ButterKnifeActivity {
final public static String TAG = "providerDetailActivity";
private SharedPreferences preferences;
@@ -41,7 +41,6 @@ public class ProviderDetailActivity extends Activity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.provider_detail_fragment);
- ButterKnife.inject(this);
preferences = getSharedPreferences(Constants.SHARED_PREFERENCES, MODE_PRIVATE);
try {