diff --git a/app/src/org/commcare/utils/BiometricsHelper.java b/app/src/org/commcare/utils/BiometricsHelper.java index 6a2ba47b0..4c4b73a05 100644 --- a/app/src/org/commcare/utils/BiometricsHelper.java +++ b/app/src/org/commcare/utils/BiometricsHelper.java @@ -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, @@ -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); @@ -88,29 +124,56 @@ 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) { @@ -118,13 +181,19 @@ public static boolean handlePinUnlockActivityResult(int requestCode, int resultC } 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); @@ -136,7 +205,6 @@ public static ConfigurationStatus checkStatus(Context context, BiometricManager return ConfigurationStatus.NotConfigured; } } - return ConfigurationStatus.NotAvailable; } @@ -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; } diff --git a/app/src/org/commcare/utils/CrashUtil.java b/app/src/org/commcare/utils/CrashUtil.java index bbe8cf0a1..2ffadf65d 100644 --- a/app/src/org/commcare/utils/CrashUtil.java +++ b/app/src/org/commcare/utils/CrashUtil.java @@ -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. - * + *
* Created by shubham on 8/09/17. */ public class CrashUtil { @@ -56,12 +57,21 @@ public static void log(String message) { } } + /** + * Registers the current Connect user with Firebase Crashlytics for error tracking. + *
+ * 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. + *
+ * 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); } } diff --git a/app/src/org/commcare/utils/KeyboardHelper.java b/app/src/org/commcare/utils/KeyboardHelper.java index ba0e1f343..a44e9666b 100644 --- a/app/src/org/commcare/utils/KeyboardHelper.java +++ b/app/src/org/commcare/utils/KeyboardHelper.java @@ -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() { diff --git a/app/src/org/commcare/utils/PhoneNumberHelper.java b/app/src/org/commcare/utils/PhoneNumberHelper.java index 9e3a70d74..a178c0d2b 100644 --- a/app/src/org/commcare/utils/PhoneNumberHelper.java +++ b/app/src/org/commcare/utils/PhoneNumberHelper.java @@ -21,8 +21,12 @@ import io.michaelrocks.libphonenumber.android.Phonenumber; /** - * Helper class for functionality related to phone numbers - * Includes frequent usage of PhoneNumberUtil + * Utility class for handling phone number-related operations. + * Provides functions for phone number validation, formatting, + * country code retrieval, and requesting phone number hints. + *
+ * This class leverages the PhoneNumberUtil library for number parsing
+ * and validation, and Google Identity API for phone number hint retrieval.
*
* @author dviggiano
*/
@@ -30,24 +34,27 @@ public class PhoneNumberHelper {
private static final ThreadLocal