From b7c2e57824eed0bd45b80c96ae221194c55b121f Mon Sep 17 00:00:00 2001 From: Tanguy Herbron Date: Fri, 2 Mar 2018 12:19:57 +0100 Subject: [PATCH] Several fixs and UI update Fix fingerprint cancel button crash Update fingerprint dialog --- .../Activities/SettingsActivity.java | 258 +++++++++--------- .../FingerprintDialogFragment.java | 11 +- .../FingerprintHandler.java | 56 +++- .../layout/fragment_fingerprint_scanner.xml | 95 ++++--- app/src/main/res/values/dimens.xml | 2 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/pref_exchange.xml | 3 +- 7 files changed, 251 insertions(+), 175 deletions(-) diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/SettingsActivity.java b/app/src/main/java/com/nauk/coinfolio/Activities/SettingsActivity.java index eaa03d9..b97d755 100644 --- a/app/src/main/java/com/nauk/coinfolio/Activities/SettingsActivity.java +++ b/app/src/main/java/com/nauk/coinfolio/Activities/SettingsActivity.java @@ -21,6 +21,7 @@ import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; import android.preference.RingtonePreference; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyPermanentlyInvalidatedException; @@ -65,14 +66,6 @@ import javax.crypto.SecretKey; */ public class SettingsActivity extends AppCompatPreferenceActivity { - private static final String KEY_NAME = "NAUKEY"; - private Cipher cipher; - private KeyStore keyStore; - private KeyGenerator keyGenerator; - private FingerprintManager.CryptoObject cryptoObject; - private FingerprintManager fingerprintManager; - private KeyguardManager keyguardManager; - /** * A preference value change listener that updates the preference's summary * to reflect its new value. @@ -140,6 +133,9 @@ public class SettingsActivity extends AppCompatPreferenceActivity { finish(); return true; } + + Log.d("coinfolio", "hello"); + return super.onOptionsItemSelected(item); } @@ -169,120 +165,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity { super.onCreate(savedInstanceState); setupActionBar(); - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); - - if(preferences.getBoolean("enable_fingerprint", false)) - { - - FingerprintDialogFragment newFragment = FingerprintDialogFragment.newInstance(); - newFragment.setCancelable(false); - newFragment.show(getFragmentManager(), "dialog"); - - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) - { - keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); - fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE); - - if(!fingerprintManager.isHardwareDetected()) - { - findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); - } - - if(ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) - { - findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); - } - - if(!fingerprintManager.hasEnrolledFingerprints()) - { - findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); - } - - if(!keyguardManager.isKeyguardSecure()) - { - findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); - } - else - { - try { - generateKey(); - } catch (FingerprintException e) { - e.printStackTrace(); - } - - if(initCipher()) - { - cryptoObject = new FingerprintManager.CryptoObject(cipher); - - FingerprintHandler helper = new FingerprintHandler(this, newFragment); - helper.startAuth(fingerprintManager, cryptoObject); - } - } - } - } - } - - @Override - protected void onResume() { - super.onResume(); - Log.d("coinfolio", "Hello"); - } - - private void generateKey() throws FingerprintException - { - try { - keyStore = KeyStore.getInstance("AndroidKeyStore"); - keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); - keyStore.load(null); - keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_CBC) - .setUserAuthenticationRequired(true) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) - .build()); - - keyGenerator.generateKey(); - - } catch (KeyStoreException - | NoSuchAlgorithmException - | NoSuchProviderException - | InvalidAlgorithmParameterException - | CertificateException - | IOException e) { - e.printStackTrace(); - throw new FingerprintException(e); - } - } - - public boolean initCipher() - { - try { - cipher = Cipher.getInstance( - KeyProperties.KEY_ALGORITHM_AES + "/" - + KeyProperties.BLOCK_MODE_CBC + "/" - + KeyProperties.ENCRYPTION_PADDING_PKCS7); - } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { - throw new RuntimeException("Failed to get Cipher", e); - } - - try { - keyStore.load(null); - SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME, null); - cipher.init(Cipher.ENCRYPT_MODE, key); - return true; - } catch (KeyPermanentlyInvalidatedException e) { - return false; - } catch (KeyStoreException | CertificateException - | UnrecoverableKeyException | IOException - | NoSuchAlgorithmException | InvalidKeyException e) { - throw new RuntimeException("Failed to init Cipher", e); - } - } - - private class FingerprintException extends Exception { - public FingerprintException(Exception e) - { - super(e); - } } /** @@ -358,6 +240,15 @@ public class SettingsActivity extends AppCompatPreferenceActivity { @TargetApi(Build.VERSION_CODES.HONEYCOMB) public static class ExchangePreferenceFragment extends PreferenceFragment { + + private static final String KEY_NAME = "NAUKEY"; + private Cipher cipher; + private KeyStore keyStore; + private KeyGenerator keyGenerator; + private FingerprintManager.CryptoObject cryptoObject; + private FingerprintManager fingerprintManager; + private KeyguardManager keyguardManager; + @Override public void onCreate(Bundle savedInstanceState) { @@ -366,10 +257,12 @@ public class SettingsActivity extends AppCompatPreferenceActivity { setHasOptionsMenu(true); bindPreferenceSummaryToValue(findPreference("hitbtc_publickey")); - bindPreferenceSummaryToValue(findPreference("hitbtc_privatekey")); - bindPreferenceSummaryToValue(findPreference("binance_publickey")); + + bindPreferenceSummaryToValue(findPreference("hitbtc_privatekey")); bindPreferenceSummaryToValue(findPreference("binance_privatekey")); + + startFingerprintProtocol(); } @Override @@ -381,6 +274,123 @@ public class SettingsActivity extends AppCompatPreferenceActivity { } return super.onOptionsItemSelected(item); } + + + private void startFingerprintProtocol() + { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getContext()); + FingerprintDialogFragment newFragment = FingerprintDialogFragment.newInstance(); + + if(preferences.getBoolean("enable_fingerprint", false)) + { + + newFragment.setCancelable(false); + newFragment.show(getFragmentManager(), "dialog"); + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + { + keyguardManager = (KeyguardManager) this.getActivity().getSystemService(KEYGUARD_SERVICE); + fingerprintManager = (FingerprintManager) this.getActivity().getSystemService(FINGERPRINT_SERVICE); + + try { + if(!fingerprintManager.isHardwareDetected()) + { + this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); + } + + if(ActivityCompat.checkSelfPermission(this.getContext(), Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) + { + this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); + } + + if(!fingerprintManager.hasEnrolledFingerprints()) + { + this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); + } + + if(!keyguardManager.isKeyguardSecure()) + { + this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE); + } + else + { + try { + generateKey(); + } catch (FingerprintException e) { + e.printStackTrace(); + } + + if(initCipher()) + { + cryptoObject = new FingerprintManager.CryptoObject(cipher); + + FingerprintHandler helper = new FingerprintHandler(this.getContext(), newFragment); + helper.startAuth(fingerprintManager, cryptoObject); + } + } + } catch (NullPointerException e) { + e.printStackTrace(); + } + } + } + } + + private void generateKey() throws FingerprintException + { + try { + keyStore = KeyStore.getInstance("AndroidKeyStore"); + keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); + keyStore.load(null); + keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_CBC) + .setUserAuthenticationRequired(true) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) + .build()); + + keyGenerator.generateKey(); + + } catch (KeyStoreException + | NoSuchAlgorithmException + | NoSuchProviderException + | InvalidAlgorithmParameterException + | CertificateException + | IOException e) { + e.printStackTrace(); + throw new FingerprintException(e); + } + } + + public boolean initCipher() + { + try { + cipher = Cipher.getInstance( + KeyProperties.KEY_ALGORITHM_AES + "/" + + KeyProperties.BLOCK_MODE_CBC + "/" + + KeyProperties.ENCRYPTION_PADDING_PKCS7); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new RuntimeException("Failed to get Cipher", e); + } + + try { + keyStore.load(null); + SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME, null); + cipher.init(Cipher.ENCRYPT_MODE, key); + return true; + } catch (KeyPermanentlyInvalidatedException e) { + return false; + } catch (KeyStoreException | CertificateException + | UnrecoverableKeyException | IOException + | NoSuchAlgorithmException | InvalidKeyException e) { + throw new RuntimeException("Failed to init Cipher", e); + } + } + + private class FingerprintException extends Exception { + public FingerprintException(Exception e) + { + super(e); + } + } } /** diff --git a/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintDialogFragment.java b/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintDialogFragment.java index d24e461..662c12d 100644 --- a/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintDialogFragment.java +++ b/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintDialogFragment.java @@ -20,6 +20,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; import com.mattprecious.swirl.SwirlView; import com.nauk.coinfolio.Activities.SettingsActivity; @@ -42,11 +44,15 @@ public class FingerprintDialogFragment extends DialogFragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_fingerprint_scanner, container); + //getDialog().getWindow().setLayout(getResources().getDimensionPixelSize(R.dimen.fingerprint_dialog_width), getResources().getDimensionPixelSize(R.dimen.fingerprint_dialog_height)); + ((Button) view.findViewById(R.id.cancelButton)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + dismiss(); getActivity().finish(); } }); @@ -65,17 +71,20 @@ public class FingerprintDialogFragment extends DialogFragment{ swirlView.setState(SwirlView.State.ON); } - public void wrongFingerprint() + public void wrongFingerprint(String errorString) { ((SwirlView) this.getView().findViewById(R.id.swirl)).clearColorFilter(); ((SwirlView) this.getView().findViewById(R.id.swirlBackground)).clearColorFilter(); ((SwirlView) this.getView().findViewById(R.id.swirl)).setState(SwirlView.State.ERROR); ((SwirlView) this.getView().findViewById(R.id.swirlBackground)).setState(SwirlView.State.ERROR); + + ((TextView) this.getView().findViewById(R.id.fingerprint_error)).setText(errorString); } public void resetFingerprint() { ((SwirlView) this.getView().findViewById(R.id.swirlBackground)).setState(SwirlView.State.ON); + ((TextView) this.getView().findViewById(R.id.fingerprint_error)).setText(""); SwirlView swirlView = this.getView().findViewById(R.id.swirl); swirlView.clearColorFilter(); diff --git a/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintHandler.java b/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintHandler.java index de9b4d9..b52a472 100644 --- a/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintHandler.java +++ b/app/src/main/java/com/nauk/coinfolio/FingerprintToolkit/FingerprintHandler.java @@ -40,32 +40,58 @@ public class FingerprintHandler extends FingerprintManager.AuthenticationCallbac public void onAuthenticationError(int errMsgId, CharSequence errString) { //Toast.makeText(context, "Authentification error\n" + errString, Toast.LENGTH_LONG).show(); - dialogFragment.wrongFingerprint(); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - dialogFragment.resetFingerprint(); - } - }, 500); + if(dialogFragment.isVisible()) + { + dialogFragment.wrongFingerprint("Error"); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if(dialogFragment.isVisible()) + { + dialogFragment.resetFingerprint(); + } + } + }, 500); + } } @Override public void onAuthenticationFailed() { //Toast.makeText(context, "Authentification failed", Toast.LENGTH_LONG).show(); - dialogFragment.wrongFingerprint(); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - dialogFragment.resetFingerprint(); - } - }, 500); + if(dialogFragment.isVisible()) + { + dialogFragment.wrongFingerprint("Wrong fingerprint"); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if(dialogFragment.isVisible()) + { + dialogFragment.resetFingerprint(); + } + } + }, 500); + } } @Override public void onAuthenticationHelp(int helpMsgIf, CharSequence helpString) { - Toast.makeText(context, "Authentification help\n" + helpString, Toast.LENGTH_LONG).show(); + //Toast.makeText(context, "Authentification help\n" + helpString, Toast.LENGTH_LONG).show(); + + if(dialogFragment.isVisible()) + { + dialogFragment.wrongFingerprint(helpString.toString()); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if(dialogFragment.isVisible()) + { + dialogFragment.resetFingerprint(); + } + } + }, 500); + } } @Override diff --git a/app/src/main/res/layout/fragment_fingerprint_scanner.xml b/app/src/main/res/layout/fragment_fingerprint_scanner.xml index 567ee10..24fa4b7 100644 --- a/app/src/main/res/layout/fragment_fingerprint_scanner.xml +++ b/app/src/main/res/layout/fragment_fingerprint_scanner.xml @@ -1,44 +1,71 @@ - + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center"> - - - + android:orientation="vertical"> - + - + - + -