diff --git a/mifosng-android/src/main/AndroidManifest.xml b/mifosng-android/src/main/AndroidManifest.xml index b3798e825bc..a669f26ebbd 100755 --- a/mifosng-android/src/main/AndroidManifest.xml +++ b/mifosng-android/src/main/AndroidManifest.xml @@ -132,6 +132,10 @@ android:label="@string/sync_savingsaccounttransactions" android:screenOrientation="portrait"/> + diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/SplashScreenActivity.java b/mifosng-android/src/main/java/com/mifos/mifosxdroid/SplashScreenActivity.java index dd5441745ca..1ca5db30bea 100755 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/SplashScreenActivity.java +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/SplashScreenActivity.java @@ -12,6 +12,7 @@ import com.mifos.mifosxdroid.core.MifosBaseActivity; import com.mifos.mifosxdroid.login.LoginActivity; import com.mifos.mifosxdroid.online.DashboardActivity; +import com.mifos.utils.ForegroundChecker; import com.mifos.utils.PrefManager; @@ -24,6 +25,7 @@ public class SplashScreenActivity extends MifosBaseActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); + ForegroundChecker.init(); if (!PrefManager.isAuthenticated()) { PrefManager.setInstanceUrl(BaseUrl.PROTOCOL_HTTPS + BaseUrl.API_ENDPOINT + BaseUrl.API_PATH); diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/core/MifosBaseActivity.java b/mifosng-android/src/main/java/com/mifos/mifosxdroid/core/MifosBaseActivity.java index c89b91fcf1c..40762ce3513 100755 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/core/MifosBaseActivity.java +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/core/MifosBaseActivity.java @@ -24,13 +24,16 @@ import com.mifos.mifosxdroid.injection.component.ActivityComponent; import com.mifos.mifosxdroid.injection.component.DaggerActivityComponent; import com.mifos.mifosxdroid.injection.module.ActivityModule; +import com.mifos.mifosxdroid.passcode.PassCodeActivity; import com.mifos.utils.Constants; +import com.mifos.utils.ForegroundChecker; import com.mifos.utils.PrefManager; /** * @author fomenkoo */ -public class MifosBaseActivity extends AppCompatActivity implements BaseActivityCallback { +public class MifosBaseActivity extends AppCompatActivity implements BaseActivityCallback, + ForegroundChecker.Listener { protected Toolbar toolbar; private ActivityComponent mActivityComponent; @@ -128,8 +131,12 @@ public void hideKeyboard(View view) { @Override public void logout() { - PrefManager.clearPrefs(); - startActivity(new Intent(this, SplashScreenActivity.class)); + if (PrefManager.getPassCodeStatus()) { + startActivity(new Intent(this, PassCodeActivity.class)); + } else { + PrefManager.clearPrefs(); + startActivity(new Intent(this, SplashScreenActivity.class)); + } finish(); } @@ -158,4 +165,24 @@ public void clearFragmentBackStack() { fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE); } } + + @Override + protected void onResume() { + super.onResume(); + ForegroundChecker.get().addListener(this); + ForegroundChecker.get().onActivityResumed(); + } + + @Override + protected void onPause() { + super.onPause(); + ForegroundChecker.get().onActivityPaused(); + } + + @Override + public void onBecameForeground() { + Intent intent = new Intent(this, PassCodeActivity.class); + intent.putExtra(Constants.INTIAL_LOGIN, false); + startActivity(intent); + } } diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/injection/component/ActivityComponent.java b/mifosng-android/src/main/java/com/mifos/mifosxdroid/injection/component/ActivityComponent.java index 47a300e3382..ac8426f2a4e 100644 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/injection/component/ActivityComponent.java +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/injection/component/ActivityComponent.java @@ -57,6 +57,7 @@ import com.mifos.mifosxdroid.online.search.SearchFragment; import com.mifos.mifosxdroid.online.surveylist.SurveyListFragment; import com.mifos.mifosxdroid.online.surveysubmit.SurveySubmitFragment; +import com.mifos.mifosxdroid.passcode.PassCodeActivity; import dagger.Component; @@ -70,6 +71,8 @@ public interface ActivityComponent { void inject(LoginActivity loginActivity); + void inject(PassCodeActivity passCodeActivity); + void inject(CenterListFragment centerListFragment); void inject(ClientChargeFragment clientChargeFragment); diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/login/LoginActivity.java b/mifosng-android/src/main/java/com/mifos/mifosxdroid/login/LoginActivity.java index b8529aa0316..677fa051bbb 100755 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/login/LoginActivity.java +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/login/LoginActivity.java @@ -24,7 +24,9 @@ import com.mifos.mifosxdroid.core.MifosBaseActivity; import com.mifos.mifosxdroid.core.util.Toaster; import com.mifos.mifosxdroid.online.DashboardActivity; +import com.mifos.mifosxdroid.passcode.PassCodeActivity; import com.mifos.objects.user.User; +import com.mifos.utils.Constants; import com.mifos.utils.Network; import com.mifos.utils.PrefManager; import com.mifos.utils.ValidationUtil; @@ -180,7 +182,13 @@ public void onLoginSuccessful(User user) { Toast.makeText(this, getString(R.string.toast_welcome) + " " + user.getUsername(), Toast.LENGTH_SHORT).show(); - startActivity(new Intent(this, DashboardActivity.class)); + if (PrefManager.getPassCodeStatus()) { + startActivity(new Intent(this, DashboardActivity.class)); + } else { + Intent intent = new Intent(this, PassCodeActivity.class); + intent.putExtra(Constants.INTIAL_LOGIN, true); + startActivity(intent); + } finish(); } diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/passcode/PassCodeActivity.java b/mifosng-android/src/main/java/com/mifos/mifosxdroid/passcode/PassCodeActivity.java new file mode 100644 index 00000000000..3754f9303f7 --- /dev/null +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/passcode/PassCodeActivity.java @@ -0,0 +1,222 @@ +package com.mifos.mifosxdroid.passcode; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.content.ContextCompat; +import android.support.v4.widget.NestedScrollView; +import android.support.v7.widget.AppCompatButton; +import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.mifos.mifosxdroid.R; +import com.mifos.mifosxdroid.core.MifosBaseActivity; +import com.mifos.mifosxdroid.core.util.Toaster; +import com.mifos.mifosxdroid.login.LoginActivity; +import com.mifos.mifosxdroid.online.DashboardActivity; +import com.mifos.utils.Constants; +import com.mifos.utils.EncryptionUtil; +import com.mifos.utils.Network; +import com.mifos.utils.PassCodeView; +import com.mifos.utils.PrefManager; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class PassCodeActivity extends MifosBaseActivity { + + @BindView(R.id.cl_rootview) + NestedScrollView clRootview; + + @BindView(R.id.btn_login) + AppCompatButton btnLogin; + + @BindView(R.id.btn_forgot_passcode) + AppCompatButton btnForgotPasscode; + + @BindView(R.id.pv_passcode) + PassCodeView passCodeView; + + @BindView(R.id.btn_skip) + AppCompatButton btnSkip; + + @BindView(R.id.btn_save) + AppCompatButton btnSave; + + @BindView(R.id.tv_passcode) + TextView tvPasscodeIntro; + + @BindView(R.id.iv_visibility) + ImageView ivVisibility; + + private int counter = 0; + private boolean isInitialScreen; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_pass_code); + getActivityComponent().inject(this); + ButterKnife.bind(this); + + isInitialScreen = getIntent().getBooleanExtra(Constants.INTIAL_LOGIN, false); + + if (PrefManager.getPassCodeStatus()) { + btnSkip.setVisibility(View.GONE); + btnSave.setVisibility(View.GONE); + tvPasscodeIntro.setVisibility(View.GONE); + btnLogin.setVisibility(View.VISIBLE); + btnForgotPasscode.setVisibility(View.VISIBLE); + } + } + + @OnClick(R.id.btn_skip) + public void skip() { + startDashBoardActivity(); + } + + @OnClick(R.id.btn_save) + public void savePassCode() { + if (isPassCodeLengthCorrect()) { + PrefManager.setPassCode(EncryptionUtil.getHash(passCodeView.getPasscode())); + startDashBoardActivity(); + } + } + + @OnClick(R.id.btn_login) + public void loginUsingPassCode() { + + if (!isInternetAvailable()) { + return; + } + + if (counter == 3) { + Toaster.show(clRootview, R.string.incorrect_passcode_more_than_three); + PrefManager.clearPrefs(); + startLoginActivity(); + return; + } + + if (isPassCodeLengthCorrect()) { + String passwordEntered = EncryptionUtil.getHash(passCodeView.getPasscode()); + if (PrefManager.getPassCode().equals(passwordEntered)) { + startDashBoardActivity(); + } else { + counter++; + passCodeView.clearPasscodeField(); + Toaster.show(clRootview, R.string.incorrect_passcode); + } + } + } + + @OnClick(R.id.btn_forgot_passcode) + public void forgotPassCode() { + PrefManager.clearPrefs(); + startLoginActivity(); + } + + private boolean isInternetAvailable() { + if (Network.isOnline(this)) { + return true; + } else { + Toaster.show(clRootview, getString(R.string.error_not_connected_internet)); + return false; + } + } + + @OnClick(R.id.btn_one) + public void clickedOne() { + passCodeView.enterCode(getString(R.string.one)); + } + + @OnClick(R.id.btn_two) + public void clickedTwo() { + passCodeView.enterCode(getString(R.string.two)); + } + + @OnClick(R.id.btn_three) + public void clickedThree() { + passCodeView.enterCode(getString(R.string.three)); + } + + @OnClick(R.id.btn_four) + public void clickedFour() { + passCodeView.enterCode(getString(R.string.four)); + } + + @OnClick(R.id.btn_five) + public void clickedFive() { + passCodeView.enterCode(getString(R.string.five)); + } + + @OnClick(R.id.btn_six) + public void clickedSix() { + passCodeView.enterCode(getString(R.string.six)); + } + + @OnClick(R.id.btn_seven) + public void clickedSeven() { + passCodeView.enterCode(getString(R.string.seven)); + } + + @OnClick(R.id.btn_eight) + public void clickedEight() { + passCodeView.enterCode(getString(R.string.eight)); + } + + @OnClick(R.id.btn_nine) + public void clickedNine() { + passCodeView.enterCode(getString(R.string.nine)); + } + + @OnClick(R.id.btn_zero) + public void clickedZero() { + passCodeView.enterCode(getString(R.string.zero)); + } + + @OnClick(R.id.btn_back) + public void clickedBackSpace() { + passCodeView.backSpace(); + } + + @OnClick(R.id.iv_visibility) + public void visibilityChange() { + passCodeView.revertPassCodeVisibility(); + if (!passCodeView.passcodeVisible()) { + ivVisibility.setColorFilter(ContextCompat.getColor(PassCodeActivity.this, + R.color.light_grey)); + } else { + ivVisibility.setColorFilter(ContextCompat.getColor(PassCodeActivity.this, + R.color.gray_dark)); + } + } + private boolean isPassCodeLengthCorrect() { + if (passCodeView.getPasscode().length() == 4) { + return true; + } + Toaster.show(clRootview, getString(R.string.error_passcode)); + return false; + } + + private void startDashBoardActivity() { + startActivity(new Intent(this, DashboardActivity.class)); + finish(); + } + + private void startLoginActivity() { + Intent i = new Intent(PassCodeActivity.this, LoginActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(i); + finish(); + } + + @Override + public void onBackPressed() { + //enabling back press only for initial login. + if (isInitialScreen) { + super.onBackPressed(); + } + } +} diff --git a/mifosng-android/src/main/java/com/mifos/utils/Constants.java b/mifosng-android/src/main/java/com/mifos/utils/Constants.java index 6cb2403610e..6a043398066 100755 --- a/mifosng-android/src/main/java/com/mifos/utils/Constants.java +++ b/mifosng-android/src/main/java/com/mifos/utils/Constants.java @@ -133,6 +133,8 @@ public class Constants { public static final String ACTIVATE_TYPE = "activation_type"; + public static final String INTIAL_LOGIN = "initial_login"; + //This needs to be 8 bits because validateRequestPermissionsRequestCode // in FragmentActivity requires requestCode to be of 8 bits, meaning the range is from 0 to 255. public static final int REQUEST_PERMISSION_SETTING = 254; diff --git a/mifosng-android/src/main/java/com/mifos/utils/EncryptionUtil.java b/mifosng-android/src/main/java/com/mifos/utils/EncryptionUtil.java new file mode 100644 index 00000000000..48c44d3016f --- /dev/null +++ b/mifosng-android/src/main/java/com/mifos/utils/EncryptionUtil.java @@ -0,0 +1,24 @@ +package com.mifos.utils; + +import android.util.Log; + +/** + * Created by mayankjindal on 30/06/17. + */ + +public class EncryptionUtil { + + static { + try { + System.loadLibrary("encryption"); + } catch (UnsatisfiedLinkError e) { + Log.e("LoadJniLib", "Error: Could not load native library: " + e.getMessage()); + } + } + + private static final native String getPassCodeHash(String passcode); + + public static String getHash(String passCode) { + return getPassCodeHash(passCode); + } +} diff --git a/mifosng-android/src/main/java/com/mifos/utils/ForegroundChecker.java b/mifosng-android/src/main/java/com/mifos/utils/ForegroundChecker.java new file mode 100644 index 00000000000..f9b175f2247 --- /dev/null +++ b/mifosng-android/src/main/java/com/mifos/utils/ForegroundChecker.java @@ -0,0 +1,94 @@ +package com.mifos.utils; + +import android.os.Handler; + +/** + * Created by mayankjindal on 18/07/17. + */ + +public class ForegroundChecker { + public static final long CHECK_DELAY = 500; + public static final int MIN_BACKGROUND_THRESHOLD = 5; + public static final String TAG = ForegroundChecker.class.getName(); + + public interface Listener { + public void onBecameForeground(); + } + + private static ForegroundChecker instance; + + private boolean foreground = false, paused = true; + private Handler handler = new Handler(); + private Listener listener; + private Runnable check; + private long backgroundTimeStart; + + public static ForegroundChecker init() { + if (instance == null) { + instance = new ForegroundChecker(); + } + return instance; + } + + public static ForegroundChecker get() { + if (instance == null) { + init(); + } + return instance; + } + + private ForegroundChecker() { + backgroundTimeStart = -1; + } + + public boolean isForeground() { + return foreground; + } + + public boolean isBackground() { + return !foreground; + } + + public void addListener(Listener listener) { + this.listener = listener; + } + + public void onActivityResumed() { + paused = false; + boolean wasBackground = !foreground; + foreground = true; + + if (check != null) + handler.removeCallbacks(check); + + if (wasBackground) { + + int secondsInBackground = (int) ((System.currentTimeMillis() - backgroundTimeStart) / + 1000) % 60; + + if (backgroundTimeStart != -1 && secondsInBackground >= MIN_BACKGROUND_THRESHOLD && + listener != null) { + listener.onBecameForeground(); + } + + } + } + + public void onActivityPaused() { + paused = true; + + if (check != null) + handler.removeCallbacks(check); + + handler.postDelayed(check = new Runnable() { + @Override + public void run() { + if (foreground && paused) { + foreground = false; + backgroundTimeStart = System.currentTimeMillis(); + + } + } + }, CHECK_DELAY); + } +} diff --git a/mifosng-android/src/main/java/com/mifos/utils/PassCodeView.java b/mifosng-android/src/main/java/com/mifos/utils/PassCodeView.java new file mode 100644 index 00000000000..4f95a3972f5 --- /dev/null +++ b/mifosng-android/src/main/java/com/mifos/utils/PassCodeView.java @@ -0,0 +1,115 @@ +package com.mifos.utils; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.support.annotation.Nullable; +import android.support.v4.content.ContextCompat; +import android.util.AttributeSet; +import android.view.View; + +import com.mifos.mifosxdroid.R; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by mayankjindal on 18/07/17. + */ + +public class PassCodeView extends View { + + private Paint emptyCirclePaint, fillCirclePaint; + private final int PASSWORD_LENGTH = 4; + private List passwordList; + private boolean isPasscodeVisible; + + public PassCodeView(Context context) { + super(context); + init(); + } + + public PassCodeView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(); + } + + public PassCodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + + private void init() { + emptyCirclePaint = new Paint(); + emptyCirclePaint.setColor(ContextCompat.getColor(getContext(), R.color.primary)); + emptyCirclePaint.setAntiAlias(true); + emptyCirclePaint.setStyle(Paint.Style.STROKE); + emptyCirclePaint.setStrokeWidth(1f); + + fillCirclePaint = new Paint(); + fillCirclePaint.setColor(ContextCompat.getColor(getContext(), R.color.primary)); + fillCirclePaint.setAntiAlias(true); + fillCirclePaint.setTextSize(getResources().getDimension(R.dimen.text_medium)); + fillCirclePaint.setStyle(Paint.Style.FILL); + + passwordList = new ArrayList<>(); + isPasscodeVisible = false; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + int stackSize = passwordList.size(); + int xPosition = getWidth() / (PASSWORD_LENGTH * 2); + for (int i = 1; i <= PASSWORD_LENGTH; i++) { + if (stackSize >= i) { + if (!isPasscodeVisible) { + canvas.drawCircle(xPosition, getHeight() / 2, 8f, fillCirclePaint); + } else { + canvas.drawText(passwordList.get(i - 1), xPosition , getHeight() / 2 + + getHeight() / 8, fillCirclePaint); + } + } else { + canvas.drawCircle(xPosition , getHeight() / 2, 8f, emptyCirclePaint); + } + xPosition += getWidth() / PASSWORD_LENGTH; + } + } + + public void enterCode(String character) { + if (passwordList.size() < PASSWORD_LENGTH) { + passwordList.add(character); + invalidate(); + } + } + + public String getPasscode() { + StringBuilder builder = new StringBuilder(); + for (String character : passwordList) { + builder.append(character); + } + return builder.toString(); + } + + public void clearPasscodeField() { + passwordList.clear(); + invalidate(); + } + + public void backSpace() { + if (passwordList.size() > 0) { + passwordList.remove(passwordList.size() - 1); + invalidate(); + } + } + + public void revertPassCodeVisibility() { + isPasscodeVisible = !isPasscodeVisible; + invalidate(); + } + + public boolean passcodeVisible() { + return isPasscodeVisible; + } +} diff --git a/mifosng-android/src/main/java/com/mifos/utils/PrefManager.java b/mifosng-android/src/main/java/com/mifos/utils/PrefManager.java index 716f22243a4..c4b288a0556 100755 --- a/mifosng-android/src/main/java/com/mifos/utils/PrefManager.java +++ b/mifosng-android/src/main/java/com/mifos/utils/PrefManager.java @@ -24,6 +24,8 @@ public class PrefManager { private static final String PORT = "preferences_port"; private static final String USER_STATUS = "user_status"; private static final String USER_DETAILS = "user_details"; + private static final String PASSCODE = "passcode"; + private static final String PASSCODE_STATUS = "passcode_status"; private static Gson gson = new Gson(); @@ -159,6 +161,15 @@ public static void setPort(String port) { putString(PORT, port); } + public static String getPassCode() { + return getString(PASSCODE, ""); + } + + public static void setPassCode(String passCode) { + putString(PASSCODE, passCode); + setPassCodeStatus(true); + } + /** * Set User Status, * If O then user is Online @@ -175,6 +186,21 @@ public static void setUserStatus(int statusCode) { public static int getUserStatus() { return getInt(USER_STATUS, 0); } -} + /** + * Set Pass Code Status, + * If false then pass code is not set + * If true then pass code is set + */ + public static void setPassCodeStatus(boolean statusCode) { + putBoolean(PASSCODE_STATUS, true); + } + /** + * @return the Pref value of pass code status. + * default is false(pass code is not set) + */ + public static Boolean getPassCodeStatus() { + return getBoolean(PASSCODE_STATUS, false); + } +} \ No newline at end of file diff --git a/mifosng-android/src/main/jniLibs/arm64-v8a/libencryption.so b/mifosng-android/src/main/jniLibs/arm64-v8a/libencryption.so new file mode 100755 index 00000000000..db8c572b138 Binary files /dev/null and b/mifosng-android/src/main/jniLibs/arm64-v8a/libencryption.so differ diff --git a/mifosng-android/src/main/jniLibs/armeabi-v7a/libencryption.so b/mifosng-android/src/main/jniLibs/armeabi-v7a/libencryption.so new file mode 100755 index 00000000000..77063967663 Binary files /dev/null and b/mifosng-android/src/main/jniLibs/armeabi-v7a/libencryption.so differ diff --git a/mifosng-android/src/main/jniLibs/armeabi/libencryption.so b/mifosng-android/src/main/jniLibs/armeabi/libencryption.so new file mode 100755 index 00000000000..fbb5752b89f Binary files /dev/null and b/mifosng-android/src/main/jniLibs/armeabi/libencryption.so differ diff --git a/mifosng-android/src/main/jniLibs/mips/libencryption.so b/mifosng-android/src/main/jniLibs/mips/libencryption.so new file mode 100755 index 00000000000..cf197c2961e Binary files /dev/null and b/mifosng-android/src/main/jniLibs/mips/libencryption.so differ diff --git a/mifosng-android/src/main/jniLibs/mips64/libencryption.so b/mifosng-android/src/main/jniLibs/mips64/libencryption.so new file mode 100755 index 00000000000..f4b696c8afb Binary files /dev/null and b/mifosng-android/src/main/jniLibs/mips64/libencryption.so differ diff --git a/mifosng-android/src/main/jniLibs/x86/libencryption.so b/mifosng-android/src/main/jniLibs/x86/libencryption.so new file mode 100755 index 00000000000..46239497675 Binary files /dev/null and b/mifosng-android/src/main/jniLibs/x86/libencryption.so differ diff --git a/mifosng-android/src/main/jniLibs/x86_64/libencryption.so b/mifosng-android/src/main/jniLibs/x86_64/libencryption.so new file mode 100755 index 00000000000..a60ad9d7365 Binary files /dev/null and b/mifosng-android/src/main/jniLibs/x86_64/libencryption.so differ diff --git a/mifosng-android/src/main/res/drawable-xhdpi/ic_backspace_48px.xml b/mifosng-android/src/main/res/drawable-xhdpi/ic_backspace_48px.xml new file mode 100644 index 00000000000..7b8ee72bc33 --- /dev/null +++ b/mifosng-android/src/main/res/drawable-xhdpi/ic_backspace_48px.xml @@ -0,0 +1,4 @@ + + + diff --git a/mifosng-android/src/main/res/drawable-xhdpi/ic_visibility_48px.xml b/mifosng-android/src/main/res/drawable-xhdpi/ic_visibility_48px.xml new file mode 100644 index 00000000000..7bf3ea193fa --- /dev/null +++ b/mifosng-android/src/main/res/drawable-xhdpi/ic_visibility_48px.xml @@ -0,0 +1,5 @@ + + + diff --git a/mifosng-android/src/main/res/drawable-xhdpi/mifos_logo.jpg b/mifosng-android/src/main/res/drawable-xhdpi/mifos_logo.jpg new file mode 100644 index 00000000000..a067a3c8edb Binary files /dev/null and b/mifosng-android/src/main/res/drawable-xhdpi/mifos_logo.jpg differ diff --git a/mifosng-android/src/main/res/layout/activity_pass_code.xml b/mifosng-android/src/main/res/layout/activity_pass_code.xml new file mode 100644 index 00000000000..eb945f5caa5 --- /dev/null +++ b/mifosng-android/src/main/res/layout/activity_pass_code.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mifosng-android/src/main/res/values/dimens.xml b/mifosng-android/src/main/res/values/dimens.xml index 514d7fe4082..98a35d5b0e8 100755 --- a/mifosng-android/src/main/res/values/dimens.xml +++ b/mifosng-android/src/main/res/values/dimens.xml @@ -7,10 +7,17 @@ 16dp 16dp + 24dp + 8dp + 16dp 8dp 8dp + 56dp 4dp 3dp + 72dp + 20sp + 16sp 18sp diff --git a/mifosng-android/src/main/res/values/strings.xml b/mifosng-android/src/main/res/values/strings.xml index b38421590ff..045fbd64297 100755 --- a/mifosng-android/src/main/res/values/strings.xml +++ b/mifosng-android/src/main/res/values/strings.xml @@ -686,6 +686,23 @@ Empty Notes Failed to Fetch Notes SyncClientPayloadActivity + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + Skip + Setup a passcode to login + Pass Code + Forgot passcode, login manually + Incorrect Passcode + You have entered incorrect Passcode more than 3 times + Passcode should be of 4 digit \ No newline at end of file