Creating the native Android part of the plug-in
All the files for the Android native part need to be placed in the src/android folder. The Android native part will consist of the following files:
- Java source code
- Risk Management SDK (JAR file and native libraries)
- gradle build file
Java source code
The Java source code needed in the plug-in will be divided into two classes:
src/android/GahPlugin.java which is the main entry point in the Android native part.
package com.gemalto.plugin.gah;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
/**
* GAH plugin wrapping the GAH SDK.
*/
public class GahPlugin extends CordovaPlugin {
private GAHRiskEngineIntegration mEngineIntegration;
/**
* {@inheritDoc}
*/
@Override
protected void pluginInitialize() {
super.pluginInitialize();
mEngineIntegration = new GAHRiskEngineIntegration(cordova.getActivity().getApplicationContext());
}
/**
* {@inheritDoc}
*/
@Override
public boolean execute(final String action, final JSONArray data, final CallbackContext callbackContext)
throws JSONException {
if (action.equals("initialize")) {
final String gahUrl = data.getString(0);
final String tmxOrgId = data.getString(1);
final String tmxFpServerUrl = data.getString(2);
if (gahUrl == null || gahUrl.isEmpty()) {
callbackContext.error("Missing mandatory parameter: GAH URL");
return false;
}
mEngineIntegration.initializeGAH(gahUrl, tmxOrgId, tmxFpServerUrl);
callbackContext.success("initialization ok");
} else if (action.equals("visitId")) {
mEngineIntegration.requestVisitId(callbackContext);
} else if (action.equals("startPrefetch")) {
mEngineIntegration.startPrefetchCollection();
} else if (action.equals("stopPrefetch")) {
mEngineIntegration.stopPrefetchCollection();
return true;
} else if (action.equals("clearTransaction")) {
mEngineIntegration.clearTransactionData();
return true;
} else if (action.equals("isSignalCollectionCompleted")) {
mEngineIntegration.isSignalCollectionCompleted(callbackContext);
return true;
} else if (action.equals("setTransactionAsCritical")) {
mEngineIntegration.setTransactionAsCritical();
} else {
callbackContext.error("undefined action");
return false;
}
return true;
}
}
src/android/GAHRiskEngineIntegration.java which is a helper class
package com.gemalto.plugin.gah;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.Log;
import com.gemalto.riskengine.GAHBSecConfig;
import com.gemalto.riskengine.GAHCore;
import com.gemalto.riskengine.GAHCoreConfig;
import com.gemalto.riskengine.GAHGemaltoSignalConfig;
import com.gemalto.riskengine.GAHPrefetchStatusCallback;
import com.gemalto.riskengine.GAHResponseCallback;
import com.gemalto.riskengine.GAHSignalGroupConstants;
import com.gemalto.riskengine.GAHTMXConfig;
import org.apache.cordova.CallbackContext;
/**
* This class is holding business logic to communicate with GAHRiskEngine
* It initiates the App backend server call post getting response from GAHRiskEngine
*/
public class GAHRiskEngineIntegration {
private static final String TAG = GAHRiskEngineIntegration.class.getSimpleName();
private final Context mContext;
public GAHRiskEngineIntegration(@NonNull final Context context) {
mContext = context;
}
/**
* Initializes the GAH SDK.
*
* @param url
* GAH back end url.
* @param tmxOrgId
* Thread Matrix SDK organization id.
* @param tmxFpServerUrl
* Thread Matrix SDK server url.
*/
public void initializeGAH(@NonNull final String url,
@Nullable final String tmxOrgId,
@Nullable final String tmxFpServerUrl) {
final GAHCoreConfig coreConfig = new GAHCoreConfig.Builder(mContext, url).build();
final GAHGemaltoSignalConfig signalConfig = new GAHGemaltoSignalConfig.Builder().build();
final GAHBSecConfig gahbSecConfig = new GAHBSecConfig.Builder().build();
if ((tmxOrgId != null && !tmxOrgId.isEmpty()) && (tmxFpServerUrl != null && !tmxFpServerUrl.isEmpty())) {
final GAHTMXConfig threatMetrixConfig = new GAHTMXConfig.Builder(mContext, tmxOrgId, tmxFpServerUrl)
.build();
GAHCore.initialize(coreConfig, signalConfig, threatMetrixConfig);
} else {
GAHCore.initialize(coreConfig, signalConfig);
}
}
/**
* Initiates pre-fetching of signals from all providers before the actual signal collection
* This enhances the signal collection time during the actual login
*/
public void startPrefetchCollection() {
GAHCore.startPrefetchSignals();
}
/**
* Requests the Visit ID value from GAHRiskEngine.
*
* @param callbackContext
* Callback back to javascript.
*/
public void requestVisitId(@NonNull final CallbackContext callbackContext) {
GAHCore.requestVisitID(new GAHResponseCallback() {
@Override
public void success(final String visitId) {
Log.d("******1", "Success Callback from RESDK after getting visitID, visit id:" + visitId);
callbackContext.success(visitId);
}
@Override
public void error(final int errorCode, final String errorMessage) {
clearTransactionData();
callbackContext.error("Error message: " + errorMessage + " error code: " + errorCode);
}
});
}
/**
* Checks if signal collection is completed.
*
* @param callbackContext
* Callback back to javascript.
*/
public void isSignalCollectionCompleted(@NonNull final CallbackContext callbackContext) {
GAHCore.requestPrefetchStatus(new GAHPrefetchStatusCallback() {
@Override
public void onPrefetchCompleted(final int statusCode, final String message) {
if (statusCode == 2100) {
callbackContext.success(message);
} else {
callbackContext.error(message);
}
}
});
}
/**
* Clears transaction data after every transaction
*/
public void clearTransactionData() {
GAHCore.clearTransactionResources();
}
/**
* Stops pre-fetching of signals
*/
public void stopPrefetchCollection() {
GAHCore.stopPrefetchSignals();
}
/**
* Sets the transaction as critical.
*/
public void setTransactionAsCritical() {
GAHCore.setTransactionAsCritical();
}
}
Add Risk Management SDK
- Copy the debug and release libraries into src/android/libs
- Copythe 3pty folder in the release package into src/android/libs
Create the Gradle file
Create the gradle file, which will then be merged into the main build.gradle file of the generated Android Studio project.
src/android/gahBuild.gradle
android {
defaultConfig {
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
sourceSets {
main {
debug {
jniLibs.srcDirs += "src/main/libs/debug"
}
release {
jniLibs.srcDirs += "src/main/libs/release"
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation "androidx.appcompat:appcompat:1.3.0"
// FPP SDK
debugImplementation files("src/main/libs/debug/GAHRiskEngine.jar")
releaseImplementation files("src/main/libs/release/GAHRiskEngine.jar")
implementation files("src/main/libs/3pty/TMXProfilingConnections-6.2-97.aar")
// 3rd party dependencies
implementation "net.java.dev.jna:jna:5.5.0@aar"
//region Extra dependency for BehavioSec
// Play Services for Activity Recognition
implementation "com.google.android.gms:play-services-location:18.0.0"
// SafetyNet for list of harmful apps
implementation "com.google.android.gms:play-services-safetynet:17.0.0"
// RootBeer lib for root detection
implementation "com.scottyab:rootbeer-lib:0.0.8"
//endregion
}
Updating the main plugin.xml file
After we have added all the necessary files for the Android platform, we need to update the plugin.xml file
<?xml version='1.0' encoding='utf-8'?>
<plugin id="com.gemalto.plugin.gah" version="0.2" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>GahPlugin</name>
<js-module name="GahPlugin" src="www/GahPlugin.js">
<clobbers target="GahPlugin" />
</js-module>
<!-- ios -->
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="GahPlugin">
<param name="ios-package" value="GahPlugin"/>
</feature>
</config-file>
<config-file parent="NSLocationWhenInUseUsageDescription" target="*-Info.plist">
<string>required this permission</string>
</config-file>
<!-- Objective-C source code -->
<header-file src="src/ios/GahPlugin.h"/>
<source-file src="src/ios/GahPlugin.m"/>
<header-file src="src/ios/GAHRiskEngineIntegration.h"/>
<source-file src="src/ios/GAHRiskEngineIntegration.m"/>
<!-- FPP SDK libraries -->
<framework src="src/ios/libs/debug/GAHRiskEngine.framework" embed="false" custom="true"/>
<framework src="src/ios/libs/debug/ZDetection.framework" embed="true" custom="true"/>
<framework src="src/ios/libs/debug/TrustDefender.framework" embed="true" custom="true"/>
<!-- <framework src="src/ios/libs/release/GAHRiskEngine.framework" embed="false" custom="true"/> -->
</platform>
<!-- android -->
<platform name="android">
<!-- android permissions -->
<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--Required in Android 9 and above-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
</config-file>
<config-file target="res/xml/config.xml" parent="/*">
<feature name="GahPlugin" >
<param name="android-package" value="com.gemalto.plugin.gah.GahPlugin"/>
</feature>
</config-file>
<!-- java source code -->
<source-file src="src/android/GahPlugin.java" target-dir="src/com/gemalto/plugin/gah" />
<source-file src="src/android/GAHRiskEngineIntegration.java" target-dir="src/com/gemalto/plugin/gah" />
<!-- gradle file -->
<framework src="src/android/gahBuild.gradle" custom="true" type="gradleReference" />
<!-- FPP SDK files -->
<resource-file src="src/android/libs/debug/GAHRiskEngine.jar" target="libs/debug/GAHRiskEngine.jar" />
<resource-file src="src/android/libs/release/GAHRiskEngine.jar" target="libs/release/GAHRiskEngine.jar" />
<resource-file src="src/android/libs/3pty/TMXProfilingConnections-6.2-97.aar" target="libs/3pty/TMXProfilingConnections-6.2-97.aar" />
<!-- FPP SDK native libraries -->
<resource-file src="src/android/libs/debug/arm64-v8a/libmedlc_shared.so" target="libs/debug/arm64-v8a/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/arm64-v8a/libmedlc_shared.so" target="libs/release/arm64-v8a/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/arm64-v8a/libTMXProfiling-6.2-97-jni.so" target="libs/debug/arm64-v8a/libTMXProfiling-6.2-97-jni.so" />
<resource-file src="src/android/libs/release/arm64-v8a/libTMXProfiling-6.2-97-jni.so" target="libs/release/arm64-v8a/libTMXProfiling-6.2-97-jni.so" />
<resource-file src="src/android/libs/debug/armeabi-v7a/libmedlc_shared.so" target="libs/debug/armeabi-v7a/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/armeabi-v7a/libmedlc_shared.so" target="libs/release/armeabi-v7a/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/armeabi-v7a/libTMXProfiling-6.2-97-jni.so" target="libs/debug/armeabi-v7a/libTMXProfiling-6.2-97-jni.so" />
<resource-file src="src/android/libs/release/armeabi-v7a/libTMXProfiling-6.2-97-jni.so" target="libs/release/armeabi-v7a/libTMXProfiling-6.2-97-jni.so" />
<resource-file src="src/android/libs/debug/x86/libmedlc_shared.so" target="libs/debug/x86/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/x86/libmedlc_shared.so" target="libs/release/x86/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/x86/libTMXProfiling-6.2-97-jni.so" target="libs/debug/x86/libTMXProfiling-6.2-97-jni.so" />
<resource-file src="src/android/libs/release/x86/libTMXProfiling-6.2-97-jni.so" target="libs/release/x86/libTMXProfiling-6.2-97-jni.so" />
<resource-file src="src/android/libs/debug/x86_64/libmedlc_shared.so" target="libs/debug/x86_64/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/x86_64/libmedlc_shared.so" target="libs/release/x86_64/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/x86_64/libTMXProfiling-6.2-97-jni.so" target="libs/debug/x86_64/libTMXProfiling-6.2-97-jni.so" />
<resource-file src="src/android/libs/release/x86_64/libTMXProfiling-6.2-97-jni.so" target="libs/release/x86_64/libTMXProfiling-6.2-97-jni.so" />
</platform>
</plugin>