Skip to content

Commit

Permalink
use Observable#fromAsync instead of Observable#create (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mauin authored Aug 7, 2016
1 parent 28f7582 commit 1e28910
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
import com.mtramin.rxfingerprint.data.FingerprintAuthenticationResult;
import com.mtramin.rxfingerprint.data.FingerprintResult;

import rx.AsyncEmitter;
import rx.Observable;
import rx.Subscriber;

import static rx.AsyncEmitter.BackpressureMode.LATEST;

/**
* Authenticates the user with his fingerprint.
Expand All @@ -43,29 +45,29 @@ private FingerprintAuthenticationObservable(Context context) {
* @return Observable {@link FingerprintAuthenticationResult}
*/
static Observable<FingerprintAuthenticationResult> create(Context context) {
return Observable.create(new FingerprintAuthenticationObservable(context));
return Observable.fromAsync(new FingerprintAuthenticationObservable(context), LATEST);
}

@Nullable
@Override
protected FingerprintManagerCompat.CryptoObject initCryptoObject(Subscriber<? super FingerprintAuthenticationResult> subscriber) {
protected FingerprintManagerCompat.CryptoObject initCryptoObject(AsyncEmitter<FingerprintAuthenticationResult> subscriber) {
// Simple authentication does not need CryptoObject
return null;
}

@Override
protected void onAuthenticationSucceeded(Subscriber<? super FingerprintAuthenticationResult> subscriber, FingerprintManagerCompat.AuthenticationResult result) {
subscriber.onNext(new FingerprintAuthenticationResult(FingerprintResult.AUTHENTICATED, null));
subscriber.onCompleted();
protected void onAuthenticationSucceeded(AsyncEmitter<FingerprintAuthenticationResult> emitter, FingerprintManagerCompat.AuthenticationResult result) {
emitter.onNext(new FingerprintAuthenticationResult(FingerprintResult.AUTHENTICATED, null));
emitter.onCompleted();
}

@Override
protected void onAuthenticationHelp(Subscriber<? super FingerprintAuthenticationResult> subscriber, int helpMessageId, String helpString) {
subscriber.onNext(new FingerprintAuthenticationResult(FingerprintResult.HELP, helpString));
protected void onAuthenticationHelp(AsyncEmitter<FingerprintAuthenticationResult> emitter, int helpMessageId, String helpString) {
emitter.onNext(new FingerprintAuthenticationResult(FingerprintResult.HELP, helpString));
}

@Override
protected void onAuthenticationFailed(Subscriber<? super FingerprintAuthenticationResult> subscriber) {
subscriber.onNext(new FingerprintAuthenticationResult(FingerprintResult.FAILED, null));
protected void onAuthenticationFailed(AsyncEmitter<FingerprintAuthenticationResult> emitter) {
emitter.onNext(new FingerprintAuthenticationResult(FingerprintResult.FAILED, null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import rx.AsyncEmitter;
import rx.Observable;
import rx.Subscriber;

import static rx.AsyncEmitter.BackpressureMode.LATEST;

/**
* Decrypts data with fingerprint authentication. Initializes a {@link Cipher} for decryption which
Expand Down Expand Up @@ -68,7 +70,7 @@ private FingerprintDecryptionObservable(Context context, String keyName, String
* @return Observable result of the decryption
*/
static Observable<FingerprintDecryptionResult> create(Context context, String keyName, String encrypted) {
return Observable.create(new FingerprintDecryptionObservable(context, keyName, encrypted));
return Observable.fromAsync(new FingerprintDecryptionObservable(context, keyName, encrypted), LATEST);
}

/**
Expand All @@ -80,12 +82,12 @@ static Observable<FingerprintDecryptionResult> create(Context context, String ke
* @return Observable result of the decryption
*/
static Observable<FingerprintDecryptionResult> create(Context context, String encrypted) {
return Observable.create(new FingerprintDecryptionObservable(context, null, encrypted));
return Observable.fromAsync(new FingerprintDecryptionObservable(context, null, encrypted), LATEST);
}

@Nullable
@Override
protected FingerprintManagerCompat.CryptoObject initCryptoObject(Subscriber<? super FingerprintDecryptionResult> subscriber) {
protected FingerprintManagerCompat.CryptoObject initCryptoObject(AsyncEmitter<FingerprintDecryptionResult> subscriber) {
CryptoProvider cryptoProvider = new CryptoProvider(this.context, this.keyName);
try {
Cipher cipher = cryptoProvider.initDecryptionCipher(encryptedData.getIv());
Expand All @@ -97,26 +99,26 @@ protected FingerprintManagerCompat.CryptoObject initCryptoObject(Subscriber<? su
}

@Override
protected void onAuthenticationSucceeded(Subscriber<? super FingerprintDecryptionResult> subscriber, FingerprintManagerCompat.AuthenticationResult result) {
protected void onAuthenticationSucceeded(AsyncEmitter<FingerprintDecryptionResult> emitter, FingerprintManagerCompat.AuthenticationResult result) {
try {
Cipher cipher = result.getCryptoObject().getCipher();
String decrypted = new String(cipher.doFinal(encryptedData.getMessage()));

subscriber.onNext(new FingerprintDecryptionResult(FingerprintResult.AUTHENTICATED, null, decrypted));
subscriber.onCompleted();
emitter.onNext(new FingerprintDecryptionResult(FingerprintResult.AUTHENTICATED, null, decrypted));
emitter.onCompleted();
} catch (BadPaddingException | IllegalBlockSizeException e) {
subscriber.onError(e);
emitter.onError(e);
}

}

@Override
protected void onAuthenticationHelp(Subscriber<? super FingerprintDecryptionResult> subscriber, int helpMessageId, String helpString) {
subscriber.onNext(new FingerprintDecryptionResult(FingerprintResult.HELP, helpString, null));
protected void onAuthenticationHelp(AsyncEmitter<FingerprintDecryptionResult> emitter, int helpMessageId, String helpString) {
emitter.onNext(new FingerprintDecryptionResult(FingerprintResult.HELP, helpString, null));
}

@Override
protected void onAuthenticationFailed(Subscriber<? super FingerprintDecryptionResult> subscriber) {
subscriber.onNext(new FingerprintDecryptionResult(FingerprintResult.FAILED, null, null));
protected void onAuthenticationFailed(AsyncEmitter<FingerprintDecryptionResult> emitter) {
emitter.onNext(new FingerprintDecryptionResult(FingerprintResult.FAILED, null, null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;

import rx.AsyncEmitter;
import rx.Observable;
import rx.Subscriber;

import static rx.AsyncEmitter.BackpressureMode.LATEST;

/**
* Encrypts data with fingerprint authentication. Initializes a {@link Cipher} for encryption which
Expand Down Expand Up @@ -69,60 +71,60 @@ private FingerprintEncryptionObservable(Context context, String keyName, String
*
* @param context context to use
* @param keyName name of the key in the keystore
*@param toEncrypt data to encrypt @return Observable {@link FingerprintEncryptionResult}
* @param toEncrypt data to encrypt @return Observable {@link FingerprintEncryptionResult}
*/
static Observable<FingerprintEncryptionResult> create(Context context, String keyName, String toEncrypt) {
return Observable.create(new FingerprintEncryptionObservable(context, keyName, toEncrypt));
return Observable.fromAsync(new FingerprintEncryptionObservable(context, keyName, toEncrypt), LATEST);
}

/**
* Creates a new FingerprintEncryptionObservable that will listen to fingerprint authentication
* to encrypt the given data.
*
* @param context context to use
*@param toEncrypt data to encrypt @return Observable {@link FingerprintEncryptionResult}
* @param toEncrypt data to encrypt @return Observable {@link FingerprintEncryptionResult}
*/
static Observable<FingerprintEncryptionResult> create(Context context, String toEncrypt) {
return Observable.create(new FingerprintEncryptionObservable(context, null, toEncrypt));
return Observable.fromAsync(new FingerprintEncryptionObservable(context, null, toEncrypt), LATEST);
}

@Nullable
@Override
protected FingerprintManagerCompat.CryptoObject initCryptoObject(Subscriber<? super FingerprintEncryptionResult> subscriber) {
protected FingerprintManagerCompat.CryptoObject initCryptoObject(AsyncEmitter<FingerprintEncryptionResult> emitter) {
CryptoProvider cryptoProvider = new CryptoProvider(this.context, this.keyName);
try {
Cipher cipher = cryptoProvider.initEncryptionCipher();
return new FingerprintManagerCompat.CryptoObject(cipher);
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | InvalidAlgorithmParameterException |CertificateException | UnrecoverableKeyException | KeyStoreException | IOException e) {
subscriber.onError(e);
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | InvalidAlgorithmParameterException | CertificateException | UnrecoverableKeyException | KeyStoreException | IOException e) {
emitter.onError(e);
return null;
}

}

@Override
protected void onAuthenticationSucceeded(Subscriber<? super FingerprintEncryptionResult> subscriber, FingerprintManagerCompat.AuthenticationResult result) {
protected void onAuthenticationSucceeded(AsyncEmitter<FingerprintEncryptionResult> emitter, FingerprintManagerCompat.AuthenticationResult result) {
try {
Cipher cipher = result.getCryptoObject().getCipher();
byte[] encryptedBytes = cipher.doFinal(toEncrypt.getBytes("UTF-8"));
byte[] ivBytes = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();

CryptoData cryptoData = CryptoData.fromBytes(encryptedBytes, ivBytes);

subscriber.onNext(new FingerprintEncryptionResult(FingerprintResult.AUTHENTICATED, null, cryptoData.toString()));
subscriber.onCompleted();
emitter.onNext(new FingerprintEncryptionResult(FingerprintResult.AUTHENTICATED, null, cryptoData.toString()));
emitter.onCompleted();
} catch (IllegalBlockSizeException | BadPaddingException | InvalidParameterSpecException | UnsupportedEncodingException e) {
subscriber.onError(e);
emitter.onError(e);
}
}

@Override
protected void onAuthenticationHelp(Subscriber<? super FingerprintEncryptionResult> subscriber, int helpMessageId, String helpString) {
subscriber.onNext(new FingerprintEncryptionResult(FingerprintResult.HELP, helpString, null));
protected void onAuthenticationHelp(AsyncEmitter<FingerprintEncryptionResult> emitter, int helpMessageId, String helpString) {
emitter.onNext(new FingerprintEncryptionResult(FingerprintResult.HELP, helpString, null));
}

@Override
protected void onAuthenticationFailed(Subscriber<? super FingerprintEncryptionResult> subscriber) {
subscriber.onNext(new FingerprintEncryptionResult(FingerprintResult.FAILED, null, null));
protected void onAuthenticationFailed(AsyncEmitter<FingerprintEncryptionResult> emitter) {
emitter.onNext(new FingerprintEncryptionResult(FingerprintResult.FAILED, null, null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@

import com.mtramin.rxfingerprint.data.FingerprintAuthenticationException;

import rx.Observable;
import rx.AsyncEmitter;
import rx.Subscriber;
import rx.functions.Action1;
import rx.subscriptions.Subscriptions;

/**
* Base observable for Fingerprint authentication. Provides abstract methods that allow
* to alter the input and result of the authentication.
*/
abstract class FingerprintObservable<T> implements Observable.OnSubscribe<T> {
abstract class FingerprintObservable<T> implements Action1<AsyncEmitter<T>> {

protected final Context context;
private CancellationSignal cancellationSignal;
Expand All @@ -48,48 +49,49 @@ abstract class FingerprintObservable<T> implements Observable.OnSubscribe<T> {
}

@Override
public void call(final Subscriber<? super T> subscriber) {
public void call(AsyncEmitter<T> asyncEmitter) {
if (!RxFingerprint.isAvailable(context)) {
subscriber.onError(new IllegalAccessException("Fingerprint authentication is not available on this device! Ensure that the device has a Fingerprint sensor and enrolled Fingerprints by calling RxFingerprint#available(Context) first"));
asyncEmitter.onError(new IllegalAccessException("Fingerprint authentication is not available on this device! Ensure that the device has a Fingerprint sensor and enrolled Fingerprints by calling RxFingerprint#available(Context) first"));
}

AuthenticationCallback callback = createAuthenticationCallback(subscriber);
AuthenticationCallback callback = createAuthenticationCallback(asyncEmitter);
cancellationSignal = new CancellationSignal();
FingerprintManagerCompat.CryptoObject cryptoObject = initCryptoObject(subscriber);
FingerprintManagerCompat.CryptoObject cryptoObject = initCryptoObject(asyncEmitter);
FingerprintManagerCompat.from(context).authenticate(cryptoObject, 0, cancellationSignal, callback, null);

subscriber.add(Subscriptions.create(() -> {
asyncEmitter.setSubscription(Subscriptions.create(() -> {
if (cancellationSignal != null && !cancellationSignal.isCanceled()) {
cancellationSignal.cancel();
}
}));

}

@NonNull
private AuthenticationCallback createAuthenticationCallback(final Subscriber<? super T> subscriber) {
private AuthenticationCallback createAuthenticationCallback(final AsyncEmitter<T> emitter) {
return new AuthenticationCallback() {
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
super.onAuthenticationError(errMsgId, errString);
subscriber.onError(new FingerprintAuthenticationException(errString));
emitter.onError(new FingerprintAuthenticationException(errString));
}

@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
FingerprintObservable.this.onAuthenticationFailed(subscriber);
FingerprintObservable.this.onAuthenticationFailed(emitter);
}

@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
super.onAuthenticationHelp(helpMsgId, helpString);
FingerprintObservable.this.onAuthenticationHelp(subscriber, helpMsgId, helpString.toString());
FingerprintObservable.this.onAuthenticationHelp(emitter, helpMsgId, helpString.toString());
}

@Override
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
FingerprintObservable.this.onAuthenticationSucceeded(subscriber, result);
FingerprintObservable.this.onAuthenticationSucceeded(emitter, result);
}
};
}
Expand All @@ -103,30 +105,28 @@ public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationRes
* that is to be used in the authentication. May be {@code null}.
*/
@Nullable
protected abstract FingerprintManagerCompat.CryptoObject initCryptoObject(Subscriber<? super T> subscriber);
protected abstract FingerprintManagerCompat.CryptoObject initCryptoObject(AsyncEmitter<T> subscriber);

/**
* Action to execute when fingerprint authentication was successful.
* Should return the needed result via the given {@link Subscriber}.
* <p/>
* Should call {@link Subscriber#onCompleted()}.
*
* @param subscriber current subscriber
* @param subscriber current subscriber
* @param result result of the successful fingerprint authentication
*/
protected abstract void onAuthenticationSucceeded(Subscriber<? super T> subscriber, FingerprintManagerCompat.AuthenticationResult result);
protected abstract void onAuthenticationSucceeded(AsyncEmitter<T> subscriber, FingerprintManagerCompat.AuthenticationResult result);

/**
* Action to execute when the fingerprint authentication returned a help result.
* Should return the needed actions to the subscriber via the given {@link Subscriber}.
* <p/>
* Should <b>not</b> {@link Subscriber#onCompleted()}.
*
* @param subscriber current subscriber
* @param subscriber current subscriber
* @param helpMessageId ID of the help message returned from the {@link FingerprintManagerCompat}
* @param helpString Help message string returned by the {@link FingerprintManagerCompat}
*/
protected abstract void onAuthenticationHelp(Subscriber<? super T> subscriber, int helpMessageId, String helpString);
protected abstract void onAuthenticationHelp(AsyncEmitter<T> subscriber, int helpMessageId, String helpString);

/**
* Action to execute when the fingerprint authentication failed.
Expand All @@ -137,5 +137,5 @@ public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationRes
*
* @param subscriber current subscriber
*/
protected abstract void onAuthenticationFailed(Subscriber<? super T> subscriber);
protected abstract void onAuthenticationFailed(AsyncEmitter<T> subscriber);
}
5 changes: 3 additions & 2 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ android {


dependencies {
// compile project(':rxfingerprint');
compile project(':rxfingerprint');
// compile "com.mtramin:rxfingerprint:$versions.name"

compile "com.android.support:appcompat-v7:$versions.supportLibrary"
compile "com.mtramin:rxfingerprint:$versions.name"
}

0 comments on commit 1e28910

Please sign in to comment.