Updates to the HID Approve SDK for Google Android
This page details the design changes made in the new HID® Approve™ SDK for Google® Android®.
Please refer to the code examples provided below that illustrate the code changes, as well as Add the SDK to Your App.
SDK Updates
-
Support for Weak (Class 2) biometric authenticators
-
Sequential passwords are prohibited unless explicitly authorized with password policy parameters
SDK Additions and New Features
What's New in Version 5.1 from 4.0
SDK Updates
ContainerInitialization
DEPRECATED field "initialPassword" (use EventListener)
Device
NEW method "createContainer"
public Container createContainer(ContainerInitialization config, char[] sessionPassword, EventListener listener) throws UnsupportedDeviceException, InternalException, AuthenticationException, InvalidPasswordException, RemoteException, UnsafeDeviceException, ServerProtocolException, FingerprintAuthenticationRequiredException, FingerprintNotEnrolledException, GooglePlayServicesObsoleteException, PasswordCancelledException, ServerOperationFailedException;
DEPRECATED method "createContainer" (use new method)
public Container createContainer(ContainerInitialization config, EventListener listener) throws UnsupportedDeviceException, InternalException, AuthenticationException, InvalidPasswordException, RemoteException, UnsafeDeviceException, ServerProtocolException, FingerprintAuthenticationRequiredException, FingerprintNotEnrolledException, GooglePlayServicesObsoleteException, PasswordCancelledException, ServerOperationFailedException;
DEPRECATED method "retrieveTransaction" (use TransactionInfo.getTransaction)
public Transaction retrieveTransaction(char[] transactionId, char[] sessionPassword, Parameter[] params) throws AuthenticationException, RemoteException, UnsupportedDeviceException, PasswordExpiredException, LostCredentialsException, InternalException, InvalidPasswordException, TransactionContainerInvalidException, TransactionExpiredException, ServerOperationFailedException;
DEPRECATED method "reset" (use DeviceFactory.reset)
public boolean reset(Parameter[] params) throws InternalException;
DEPRECATED method "getDefaultInitializationPolicy" (use EventListener)
public ProtectionPolicy getDefaultInitializationPolicy() throws InternalException;
Transaction
UPDATE method "setStatus" throws new exception ServerOperationFailedException
public boolean setStatus(String status, char[] signingPassword, char[] sessionPassword, Parameter[] param) throws AuthenticationException, PasswordExpiredException, TransactionExpiredException, ServerVersionException, RemoteException, LostCredentialsException, InternalException, PasswordRequiredException, FingerprintAuthenticationRequiredException, ServerAuthenticationException, ServerOperationFailedException;
TransactionInfo
UPDATE class declaration as interface
NEW method "getTransaction"
public Transaction getTransaction( char[] sessionPassword, Parameter[] params) throws AuthenticationException, RemoteException, UnsupportedDeviceException, PasswordExpiredException, LostCredentialsException, InternalException, InvalidPasswordException, TransactionContainerInvalidException, TransactionExpiredException, ServerOperationFailedException;
ProgressListener
REMOVED class and replaced with "EventListener"
NEW class "PasswordPromptResult"
NEW class "PasswordPromptEvent"
NEW class "EventResult"
NEW class "EventListener"
NEW class "Event"
DeviceFactory
NEW method "getDevice"
public static Device getDevice(Context context, ConnectionConfiguration config, char[] sessionPassword) throws UnsupportedDeviceException, LostCredentialsException, UnsupportedDeviceException, InternalException;
NEW method "reset"
public static boolean reset(Context ctx) throws InternalException
DEPRECATED method "getDevice" (use new method)
public static Device getDevice(Context context, ConnectionConfiguration config) throws UnsupportedDeviceException, LostCredentialsException, UnsupportedDeviceException, InternalException;
SDK Additions and New Features
Container
NEW method "getCreationDate"
public Date getCreationDate();
NEW method "getExpiryDate"
public Date getExpiryDate();
NEW method "getRenewalDate"
public Date getRenewalDate();
NEW method "isRenewable"
public Date isRenewable(char[] password);
NEW method "renew"
public void renew(ContainerRenewal config, char[] sessionPassword, EventListener eventListener) throws PasswordExpiredException , UnsupportedDeviceException, InternalException, AuthenticationException, InvalidPasswordException, RemoteException, UnsafeDeviceException, ServerProtocolException, FingerprintAuthenticationRequiredException, FingerprintNotEnrolledException, LostCredentialsException, PasswordRequiredException, CredentialsExpiredException, ServerUnsupportedOperationException, GooglePlayServicesObsoleteException, PasswordCancelledException, ServerOperationFailedException;
NEW class "ContainerRenewal"
BioPasswordPolicy
DEPRECATED method "getCancellationSignal"
public Object getCancellationSignal() throws InternalException;
DEPRECATED method "enableFingerprintManager" (use setBiometricPrompt)
public void enableFingerprintManager(Object authenticationCallback, Object cancellationSignal) throws InternalException;
NEW method "setBiometricPrompt"
void setBiometricPrompt(Object object, Object authenticationCallback, Object promptInfo);
NEW method "resetBiometricPrompt"
void resetBiometricPrompt();
NEW method "disableBioAuthentication"
void disableBioAuthentication() throws UnsupportedDeviceException, FingerprintNotEnrolledException, FingerprintAuthenticationRequiredException, InternalException, LostCredentialsException, AuthenticationException, PasswordExpiredException;
ErrorCode
NEW enumeration value "PasswordCancelled"
NEW enumeration value "GooglePlayServicesObsolete"
NEW enumeration value "ServerUnsupportedOperation"
NEW enumeration value "ServerOperationFailed"
NEW exception class "ServerUnsupportedOperationException"
NEW exception class "ServerOperationFailedException"
NEW exception class "PasswordCancelledException"
NEW exception class "GooglePlayServicesObsoleteException"
What's New in Version 4.0 from 3.0
SDK Addition
Container
NEW method "IsFIPSModeEnabled" – Reserved for Future Use.
Code Examples
Transaction Retrieval
Context ctx = this.getBaseContext();
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(ctx, connectionConfig);
// get transaction
TransactionInfo txInfo = device.retrieveTransactionInfo(myTransactionId);
Transaction tx = device.retrieveTransaction(myTransactionId, mySessionPwd, new Parameter[0]);
Context ctx = this.getBaseContext();
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(ctx, connectionConfig, mySessionPwd);
// get transaction
TransactionInfo txInfo = device.retrieveTransactionInfo(myTransactionId);
Transaction tx = txInfo.getTransaction(mySessionPwd, new Parameter[0]);
Context ctx = this.getBaseContext();
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(ctx, connectionConfig);
// get transaction
TransactionInfo txInfo = device.retrieveTransactionInfo(myTransactionId);
Transaction tx = txInfo.getTransaction(mySessionPwd, new Parameter[0]);
Provisioning / Container Creation
// progress listener
@Override
public void onEventReceived(ProgressEvent event) {
Parameter[] params = event.getParameters();
char[] message = null; char[] percent = null;
for (int i = 0; i < params.length; i++) {
if (SDKConstants.PARAM_SYNCEVENT_MESSAGE.equalsIgnoreCase(params[i].getId()))
message = params[i].getValue();
if (SDKConstants.PARAM_SYNCEVENT_PERCENT.equalsIgnoreCase(params[i].getId()))
percent = params[i].getValue();
}
String text = new String(message) + " (" + new String(percent) + ")";
Log.d(LOG_TAG, "Event Received: " + text);
}
// provisioning
public void doProvisioning() {
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(this.getBaseContext(), connectionConfig);
// new container
ContainerInitialization config = new ContainerInitialization();
config.activationCode = myActivationCode;
config.initialPassword = myInitialPassword;
config.pushId = myPushId;
config.containerFriendlyName = myContainerName;
Container container = device.createContainer(config, this);
}
// progress listener
@Override
public EventResult onEventReceived(Event event) {
if (event instanceof PasswordPromptEvent) {
// Continue: operation can continue
// Cancel: operation is cancelled by the user.
// Abort: operation is aborted by the app
PasswordPromptResult result = new PasswordPromptResult(EventResult.Code.Continue);
result.setPassword(myInitialPassword);
return result;
} else {// progress message
Parameter[] params = event.getParameters();
char[] message = null; char[] percent = null;
for (int i = 0; i < params.length; i++) {
if (SDKConstants.PARAM_SYNCEVENT_MESSAGE.equalsIgnoreCase(params[i].getId()))
message = params[i].getValue();
if (SDKConstants.PARAM_SYNCEVENT_PERCENT.equalsIgnoreCase(params[i].getId()))
percent = params[i].getValue();
}
String text = new String(message) + " (" + new String(percent) + ")";
Log.d(LOG_TAG, "Event Received: " + text);
}
return null;
}
// provisioning
public void doProvisioning() {
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(this.getBaseContext(), connectionConfig, mySessionPwd);
// new container
ContainerInitialization config = new ContainerInitialization();
config.activationCode = myActivationCode;
// NOTE: “config.initialPassword” is not supported; use listener
config.pushId = myPushId;
config.containerFriendlyName = myContainerName;
Container container = device.createContainer(config, mySessionPwd, this);
}
// progress listener
@Override
public EventResult onEventReceived(Event event) {
if (event instanceof PasswordPromptEvent) {
// Continue: operation can continue
// Cancel: operation is cancelled by the user.
// Abort: operation is aborted by the app
PasswordPromptResult result = new PasswordPromptResult(EventResult.Code.Continue);
result.setPassword(myInitialPassword);
return result;
} else {// progress message
Parameter[] params = event.getParameters();
char[] message = null; char[] percent = null;
for (int i = 0; i < params.length; i++) {
if (SDKConstants.PARAM_SYNCEVENT_MESSAGE.equalsIgnoreCase(params[i].getId()))
message = params[i].getValue();
if (SDKConstants.PARAM_SYNCEVENT_PERCENT.equalsIgnoreCase(params[i].getId()))
percent = params[i].getValue();
}
String text = new String(message) + " (" + new String(percent) + ")";
Log.d(LOG_TAG, "Event Received: " + text);
}
return null;
}
// provisioning
public void doProvisioning() {
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(this.getBaseContext(), connectionConfig);
// new container
ContainerInitialization config = new ContainerInitialization();
config.activationCode = myActivationCode;
// NOTE: “config.initialPassword” is not supported; use listener
config.pushId = myPushId;
config.containerFriendlyName = myContainerName;
Container container = device.createContainer(config, mySessionPwd, this);
}
Biometric Authentication
// Custom AuthenticationCallback implementation that receives sensor events
class CustomAuthenticationCallback extends FingerprintManager.AuthenticationCallback {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
// Display error
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
// Give feedback to user
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
// Fingerprint matched, let’s proceed with the operation requested
otp = otpGenerator.getOTP(null);
// Display OTP
}
public void onAuthenticationFailed() {
// Dismiss UI / display user that fingerprint didn’t match
// A usual behavior is to prompt the user for his/her password
}
}
// Method invoked when button to generate OTP is clicked
public void onGenerateOTPClick(View v) {
// Pass an AuthenticationCallback instance and a CancellationSignal instance to the SDK
bioPasswordPolicy.enableFingerprintManager(customAuthenticationCallback, cancellationSignal);
// Perform the requested operation, for example getOTP
try {
otp = otpGenerator.getOTP(null);
// Display OTP
} catch (FingerprintAuthenticationRequiredException e) {
// Display UI to show user that he/she must put his/her finger on sensor
}
}
// Custom BiometricPrompt.AuthenticationCallback implementation that receives sensor events
class CustomAuthenticationCallback extends BiometricPrompt.AuthenticationCallback {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
// Display error
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
// Fingerprint matched, let’s proceed with the operation requested
otp = otpGenerator.getOTP(null);
// Display OTP
}
public void onAuthenticationFailed() {
// Dismiss UI / display user that fingerprint didn’t match
// A usual behavior is to prompt the user for his/her password
}
}
// Method invoked when button to generate OTP is clicked
public void onGenerateOTPClick(View v) {
// Construct PromptInfo dialog
BiometricPrompt.PromptInfo prompt =
new BiometricPrompt.PromptInfo.Builder()
.setTitle(activity.getString("Confirm fingerprint"))
.setNegativeButtonText(activity.getString("Cancel"))
.build();
// Pass Activity/Fragment, AuthenticationCallback and PromptInfo instances to the SDK
bioPasswordPolicy.setBiometricPrompt(getActivity(),customAuthenticationCallback,prompt);
// Perform the requested operation, for example getOTP
otp = otpGenerator.getOTP(null);
// Display OTP
}
ProtectionPolicy containerPolicy = pContainer.getProtectionPolicy();
if (containerPolicy.getType().equals(ProtectionPolicy.PolicyType.BIOPASSWORD.toString())
{
BioPasswordPolicy bioPasswordPolicy = (BioPasswordPolicy)containerPolicy;
if (bioPasswordPolicy.getBioAuthenticationState() == BioAuthenticationState.NOT_ENABLED)
{
// Prompt user for his/her password
// Then enable authentication with fingerprint
bioPasswordPolicy.enableBioAuthentication(password);
}
}