Skip to content

Commit

Permalink
-updated java doc for util functions
Browse files Browse the repository at this point in the history
  • Loading branch information
pm-dimagi committed Feb 20, 2025
1 parent ce5fd3d commit e9fccc0
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 57 deletions.
114 changes: 88 additions & 26 deletions app/src/org/commcare/utils/BiometricsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,72 @@
import androidx.fragment.app.FragmentActivity;

/**
* Helper class for biometric configuration and verification
*
* @author dviggiano
* Helper class for biometric configuration and verification.
* Provides methods to check biometric availability, configure biometrics,
* and perform authentication using fingerprint or PIN or Password.
* Supports both biometric strong authentication and device credentials.
*/
public class BiometricsHelper {

/**
* Enum simplifying the availability of a biometric method
* Enum representing the availability and configuration status of a biometric method.
*/
public enum ConfigurationStatus {
NotAvailable,
NotConfigured,
Configured
NotAvailable, // Biometrics not available on the device
NotConfigured, // Biometrics available but not set up
Configured // Biometrics set up and ready for authentication
}

private static final int StrongBiometric = BiometricManager.Authenticators.BIOMETRIC_STRONG;
private static final int PinBiometric = BiometricManager.Authenticators.DEVICE_CREDENTIAL;

/**
* Checks the fingerprint authentication status.
*
* @param context The application context.
* @param biometricManager The BiometricManager instance.
* @return The fingerprint configuration status.
*/
public static ConfigurationStatus checkFingerprintStatus(Context context, BiometricManager biometricManager) {
return checkStatus(context, biometricManager, StrongBiometric);
}

/**
* Determines if fingerprint authentication is configured on the device.
*
* @param context The application context.
* @param biometricManager The BiometricManager instance.
* @return True if fingerprint authentication is configured, false otherwise.
*/
public static boolean isFingerprintConfigured(Context context, BiometricManager biometricManager) {
return checkStatus(context, biometricManager, StrongBiometric) == ConfigurationStatus.Configured;
}

/**
* Prompts the user to configure fingerprint authentication.
*
* @param activity The current activity.
* @return True if the configuration process starts successfully, false otherwise.
*/
public static boolean configureFingerprint(Activity activity) {
return configureBiometric(activity, StrongBiometric);
}

/**
* Initiates fingerprint authentication.
*
* @param activity The fragment activity.
* @param biometricManager The BiometricManager instance.
* @param allowExtraOptions Whether to allow alternative authentication options (e.g., PIN).
* @param callback The callback for authentication results.
*/
public static void authenticateFingerprint(FragmentActivity activity,
BiometricManager biometricManager,
boolean allowExtraOptions,
BiometricPrompt.AuthenticationCallback callback) {
if (BiometricsHelper.isFingerprintConfigured(activity, biometricManager)) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
//For newer versions, PIN prompt will handle all unlock
// For Android 11+ (R), use PIN as an alternative unlock method
authenticatePin(activity, biometricManager, callback);
} else {
BiometricPrompt prompt = new BiometricPrompt(activity,
Expand All @@ -74,7 +104,13 @@ public static void authenticateFingerprint(FragmentActivity activity,
}
}


/**
* Checks the status of PIN-based authentication.
*
* @param context The application context.
* @param biometricManager The BiometricManager instance.
* @return The PIN configuration status.
*/
public static ConfigurationStatus checkPinStatus(Context context, BiometricManager biometricManager) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
return checkStatus(context, biometricManager, PinBiometric);
Expand All @@ -88,43 +124,76 @@ public static ConfigurationStatus checkPinStatus(Context context, BiometricManag
}
}

/**
* Determines if PIN authentication is configured on the device.
*
* @param context The application context.
* @param biometricManager The BiometricManager instance.
* @return True if PIN authentication is configured, false otherwise.
*/
public static boolean isPinConfigured(Context context, BiometricManager biometricManager) {
return checkStatus(context, biometricManager, PinBiometric) == ConfigurationStatus.Configured;
}

/**
* Prompts the user to configure PIN-based authentication.
*
* @param activity The current activity.
* @return True if the configuration process starts successfully, false otherwise.
*/
public static boolean configurePin(Activity activity) {
return configureBiometric(activity, PinBiometric);
}

private static BiometricPrompt.AuthenticationCallback biometricPromptCallbackHolder;

/**
* Initiates PIN-based authentication.
*
* @param activity The fragment activity.
* @param biometricManager The BiometricManager instance.
* @param biometricPromptCallback The callback for authentication results.
*/
public static void authenticatePin(FragmentActivity activity, BiometricManager biometricManager,
BiometricPrompt.AuthenticationCallback biometricPromptCallback) {
if (BiometricsHelper.isPinConfigured(activity, biometricManager)) {
biometricPromptCallbackHolder = biometricPromptCallback;
KeyguardManager manager = (KeyguardManager)activity.getSystemService(Context.KEYGUARD_SERVICE);
activity.startActivityForResult(
manager.createConfirmDeviceCredentialIntent(
activity.getString(R.string.connect_unlock_title),
activity.getString(R.string.connect_unlock_message)),
ConnectConstants.CONNECT_UNLOCK_PIN);
biometricPromptCallbackHolder = biometricPromptCallback;
KeyguardManager manager = (KeyguardManager)activity.getSystemService(Context.KEYGUARD_SERVICE);
activity.startActivityForResult(
manager.createConfirmDeviceCredentialIntent(
activity.getString(R.string.connect_unlock_title),
activity.getString(R.string.connect_unlock_message)),
ConnectConstants.CONNECT_UNLOCK_PIN);
}
}

/**
* Handles the result of the PIN authentication activity.
*
* @param requestCode The request code for the authentication intent.
* @param resultCode The result code from the authentication activity.
* @return True if the request was handled, false otherwise.
*/
public static boolean handlePinUnlockActivityResult(int requestCode, int resultCode) {
if (requestCode == ConnectConstants.CONNECT_UNLOCK_PIN) {
if (resultCode == Activity.RESULT_OK) {
biometricPromptCallbackHolder.onAuthenticationSucceeded(null);
} else {
biometricPromptCallbackHolder.onAuthenticationFailed();
}

return true;
}

return false;
}

/**
* Checks the biometric authentication status for a specific authentication method.
*
* @param context The application context.
* @param biometricManager The BiometricManager instance.
* @param authenticator The authenticator type (e.g., fingerprint, PIN).
* @return The biometric configuration status.
*/
public static ConfigurationStatus checkStatus(Context context, BiometricManager biometricManager,
int authenticator) {
int val = canAuthenticate(context, biometricManager, authenticator);
Expand All @@ -136,7 +205,6 @@ public static ConfigurationStatus checkStatus(Context context, BiometricManager
return ConfigurationStatus.NotConfigured;
}
}

return ConfigurationStatus.NotAvailable;
}

Expand All @@ -150,23 +218,17 @@ private static int canAuthenticate(Context context, BiometricManager biometricMa

return isSecure ? BiometricManager.BIOMETRIC_SUCCESS : BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED;
}

return biometricManager.canAuthenticate(authenticator);
}

private static boolean configureBiometric(Activity activity, int authenticator) {
// Prompts the user to create credentials that your app accepts.
Intent enrollIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//Best case, handles both fingerprint and PIN
enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
authenticator);
enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, authenticator);
} else if (authenticator == StrongBiometric && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
//An alternative for fingerprint enroll that might be available
enrollIntent = new Intent(Settings.ACTION_FINGERPRINT_ENROLL);
} else {
//No way to enroll, have to fail
return false;
}

Expand Down
18 changes: 14 additions & 4 deletions app/src/org/commcare/utils/CrashUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import org.commcare.android.logging.ReportingUtils;
import org.commcare.connect.ConnectManager;
import org.commcare.dalvik.BuildConfig;

import com.google.firebase.crashlytics.FirebaseCrashlytics;

/**
* Contains constants and methods used in Crashlytics reporting.
*
* <p>
* Created by shubham on 8/09/17.
*/
public class CrashUtil {
Expand Down Expand Up @@ -56,12 +57,21 @@ public static void log(String message) {
}
}

/**
* Registers the current Connect user with Firebase Crashlytics for error tracking.
* <p>
* If Crashlytics is enabled and a Connect ID is configured, this method retrieves
* the user ID from ConnectManager and sets it as a custom key in Crashlytics.
* <p>
* In case of any exceptions during this process, the exception is recorded in
* Crashlytics to aid debugging.
*/
public static void registerConnectUser() {
if (crashlyticsEnabled && ConnectManager.isConnectIdConfigured()) {
try{
String userId=ConnectManager.getUser(CommCareApplication.instance()).getUserId();
try {
String userId = ConnectManager.getUser(CommCareApplication.instance()).getUserId();
FirebaseCrashlytics.getInstance().setCustomKey(CCC_USER, userId);
}catch (Exception e){
} catch (Exception e) {
FirebaseCrashlytics.getInstance().recordException(e);
}
}
Expand Down
13 changes: 12 additions & 1 deletion app/src/org/commcare/utils/KeyboardHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,27 @@
import android.view.inputmethod.InputMethodManager;

/**
* Helper class (single method) for showing the keyboard on an input
* Utility class for handling keyboard interactions.
* Provides a method to show the keyboard on a given input field.
*
* @author dviggiano
*/
public class KeyboardHelper {

/**
* Displays the soft keyboard for the specified input view.
* This method ensures the view gains focus before attempting to show the keyboard.
* A slight delay is added to ensure the keyboard appears properly.
*
* @param activity The activity context used to retrieve the InputMethodManager.
* @param view The input view that should receive focus and trigger the keyboard.
*/
public static void showKeyboardOnInput(Activity activity, View view) {
view.requestFocus();

InputMethodManager inputMethodManager = (InputMethodManager)activity.getSystemService(
Context.INPUT_METHOD_SERVICE);

view.postDelayed(new Runnable() {
@Override
public void run() {
Expand Down
Loading

0 comments on commit e9fccc0

Please sign in to comment.