Implementing Threat-Memory™ in Android Apps

Last updated June 21, 2026 by Appdome

Overview

Threat-Memory™ allows Android applications to retrieve security detection data on demand. Using in-app API calls, the application can access the current threat state, including which threats have been detected, when they occurred, and their current status.

All data is returned as a JSONObject and can be queried at any point during runtime.

Beyond on-demand access to threat data, Threat-Memory™ keeps the application continuously informed as the threat posture evolves. Protected applications can track both threat-state changes and newly detected threats in real time, without the complexity of managing separate listeners for each event.

For a detailed explanation of what Threat-Memory™ is and how it fits into the threat intelligence management framework, see: Understanding Appdome Threat-Memory™

Prerequisites

  • Configure each defense to use Threat-Memory™ mode within In-App Control on the Appdome platform.
    Threatmemory
  • When a defense is configured in Threat-Memory™ mode, any detected threats are stored locally on the device without any enforcement actions.
  • Defenses configured with other intelligence modes (such as In-App Detection, In-App Defense, Failsafe, etc.) are not tracked by Threat-Memory™.
  • The application must be built through the Appdome platform. Threat-Memory™ data is only available at runtime in a protected build.

Integration

Threat-Memory™ offers two ways to access threat-state information in your Android application:

  • State getter APIs: Allow the application to retrieve the current or historical security state on demand, including session-level, installation-level, and threat-specific data.
  • Threat-state callbacks: Threat-Memory™ callbacks that keep the application informed of threat activity. One callback notifies the application when the state of a Threat-Memory™-enabled threat changes, while the other notifies the application when a new threat is detected.

Together, these capabilities enable the application to respond to detections and threat-state changes in real time by querying the device risk level whenever additional context is needed.

Follow these steps to integrate and use Threat-Memory™ in your Android application.

Step 1: Create the Appdome Package

In your Android project, create a package named:

com.appdome

In Android Studio:

  1. Open the app module.
  2. Go to src/main/java or src/main/kotlin.
  3. Right-click your source folder and select New > Package.
  4. Name the package:

com.appdome

This package will contain the Threat-Memory™ API and callback placeholder files.

Step 2: Add the Threat-Memory™ Callback Class File

Add the AppdomeThreatCallbacks file to the newly created com.appdome package.

The onThreatStateChange(threatName) callback is invoked when the state of a Threat-Memory™-enabled threat changes during the application session. The callback receives the name of the threat whose state changed.

The onThreatDetected(threatName) callback is invoked each time a threat is recorded for a Threat-Memory™-enabled defense during the application session. Unlike onThreatStateChange, which is triggered only when the threat risk state transitions (for example, from safe to compromised or from compromised to safe), onThreatDetected is triggered for every detection occurrence, including repeated detections of the same threat. The callback receives the name of the detected threat.

Update the onThreatStateChange(threatName) and onThreatDetected(threatName) implementations with the application’s business logic for handling threat-state changes and individual detection events. For example, the application may query the updated threat state, log detections for telemetry, trigger an immediate in-app response, or send threat data to the backend.

Java

package com.appdome;

import androidx.annotation.Keep;
import android.util.Log;
import org.json.JSONObject;

@Keep
public class AppdomeThreatCallbacks {

    @Keep
    public static void onThreatStateChange(String threatName) {
        // Handle threat state changes here.
        // Use the threatName to query updated state using AppdomeThreatApi.
        // JSONObject threatState = AppdomeThreatApi.getThreatSessionState(threatName);
        
        // Example: print the updated threat state to the log.
        // Log.d("ThreatMemory", "Threat state changed: " + threatName);
        // Log.d("ThreatMemory", "Updated threat state: " + threatState);
    }

    @Keep
    public static void onThreatDetected(String threatName) {
        // Called every time a new threat detection occurs for a ThreatMemory-enabled defense.
        // Use the threatName to query the updated threat state using AppdomeThreatApi.
        // JSONObject threatState = AppdomeThreatApi.getThreatSessionState(threatName);
    
        // Example: print the detected threat to the log.
        // Log.d("ThreatMemory", "Threat detected: " + threatName);
        // Log.d("ThreatMemory", "Updated threat state: " + threatState);
    }

}

Kotlin

package com.appdome

import androidx.annotation.Keep
import android.util.Log
import org.json.JSONObject

@Keep
object AppdomeThreatCallbacks {

    @Keep
    @JvmStatic
    fun onThreatStateChange(threatName: String) {
        // Handle threat state changes here.
        // Use the threatName to query updated state using AppdomeThreatApi.
        // val threatState: JSONObject = AppdomeThreatApi.getThreatSessionState(threatName)

        // Example: print the updated threat state to the log.
        // Log.d("ThreatMemory", "Threat state changed: $threatName")
        // Log.d("ThreatMemory", "Updated threat state: $threatState")
    }

    @Keep
    @JvmStatic
    fun onThreatDetected(threatName: String) {
        // Called every time a new threat detection occurs for a ThreatMemory-enabled defense.
        // Use the threatName to query the updated threat state using AppdomeThreatApi.
        // val threatState: JSONObject = AppdomeThreatApi.getThreatSessionState(threatName)
    
        // Example: print the detected threat to the log.
        // Log.d("ThreatMemory", "Threat detected: $threatName")
        // Log.d("ThreatMemory", "Updated threat state: $threatState")
    }

}

Step 3: Add the Threat-Memory™ API Placeholder Class

Add the AppdomeThreatApi class file to the com.appdome package.
The file below contains placeholder implementations for the Threat-Memory™ API methods.
The implementation in the placeholder class allows the unprotected application to be tested using developer-controlled responses prior to protecting the application with Appdome.
The AppdomeThreatApi methods are replaced in the protected application and return Threat-Memory™ responses at runtime.

Java

package com.appdome;

import androidx.annotation.Keep;
import org.json.JSONException;
import org.json.JSONObject;

@Keep
public class AppdomeThreatApi {

    private static JSONObject stubResponse(String description) {
        JSONObject obj = new JSONObject();
        try {
            obj.put("info", "Return stub response for - " + description);
        } catch (JSONException ignored) {
        }
        return obj;
    }

    @Keep
    public static JSONObject getThreatSessionState(String threatName) {
        return stubResponse("getThreatSessionState(" + threatName + ")");
    }

    @Keep
    public static JSONObject getThreatSessionState(String threatName, String sessionID) {
        return stubResponse("getThreatSessionState(" + threatName + ", " + sessionID + ")");
    }

    @Keep
    public static JSONObject getThreatInstallationState(String threatName) {
        return stubResponse("getThreatInstallationState(" + threatName + ")");
    }

    @Keep
    public static JSONObject getSessionState() {
        return stubResponse("getSessionState()");
    }

    @Keep
    public static JSONObject getSessionState(String sessionID) {
        return stubResponse("getSessionState(" + sessionID + ")");
    }

    @Keep
    public static JSONObject getInstallationState() {
        return stubResponse("getInstallationState()");
    }

    @Keep
    public static JSONObject getState() {
        return stubResponse("getState()");
    }
}

Kotlin

package com.appdome

import androidx.annotation.Keep
import org.json.JSONObject

@Keep
object AppdomeThreatApi {

    private fun stubResponse(description: String): JSONObject {
        return JSONObject().apply {
            put("info", "Return stub response for - $description")
        }
    }

    @Keep
    @JvmStatic
    fun getThreatSessionState(threatName: String): JSONObject {
        return stubResponse("getThreatSessionState($threatName)")
    }

    @Keep
    @JvmStatic
    fun getThreatSessionState(threatName: String, sessionID: String): JSONObject {
        return stubResponse("getThreatSessionState($threatName, $sessionID)")
    }

    @Keep
    @JvmStatic
    fun getThreatInstallationState(threatName: String): JSONObject {
        return stubResponse("getThreatInstallationState($threatName)")
    }

    @Keep
    @JvmStatic
    fun getSessionState(): JSONObject {
        return stubResponse("getSessionState()")
    }

    @Keep
    @JvmStatic
    fun getSessionState(sessionID: String): JSONObject {
        return stubResponse("getSessionState($sessionID)")
    }

    @Keep
    @JvmStatic
    fun getInstallationState(): JSONObject {
        return stubResponse("getInstallationState()")
    }

    @Keep
    @JvmStatic
    fun getState(): JSONObject {
        return stubResponse("getState()")
    }
}

Step 4: Call the Threat-Memory™ API

After adding the AppdomeThreatApi placeholder API file, the Threat-Memory™ getter APIs can be called from any Java or Kotlin file in the application.

Java

import com.appdome.AppdomeThreatApi;
import org.json.JSONObject;
import android.util.Log;

JSONObject sessionState = AppdomeThreatApi.getSessionState();
Log.d("ThreatMemory", "Session state: " + sessionState);

Kotlin

import com.appdome.AppdomeThreatApi
import org.json.JSONObject
import android.util.Log
val sessionState: JSONObject = AppdomeThreatApi.getSessionState()
Log.d("ThreatMemory", "Session state: $sessionState")

 

All methods are exposed as static methods on com.appdome.AppdomeThreatApi.
Each method returns a JSONObject.
Calls are synchronous, use on-device storage, and return immediately without waiting for network requests.

Step 5: Test and Validate the Integration

1. Build the App and Test Without Appdome

At this stage, Threat-Memory™ is not present in the application because the application has not yet been protected by Appdome.

All calls to AppdomeThreatApi return placeholder responses. These responses can be modified during development to invoke and validate different threat scenarios in the application. This simplifies testing of the unprotected version before protecting the application. For example, you can test an end-to-end flow that collects Threat-Memory™ data in the application and sends threat telemetry to the backend.

2. Protect the App with Appdome

Build the protected application on the Appdome platform with Threat-Memory™ enabled for the selected defenses in the defense policy.

Once the application is protected:

  • The placeholder implementations are automatically replaced at runtime.
  • All AppdomeThreatApi methods return threat data collected on the device from defenses monitored by Threat-Memory™.
  • No code changes are required between testing and production builds.
  • The integration does not require changes when the defense policy is updated, for example, when adding a new Threat-Memory™-enabled defense.

API Reference

Glossary

Session
A session represents a single app launch until it is closed by the user or the operating system (OS), identified by a sessionID.

Installation
An installation represents the lifetime of a given app version on the device across sessions, identified by an installationID.

Threat State
Threat State represents the current risk status of a specific threat or the overall security posture of an application session or installation.

Session State
Session State represents the security status of a single application process lifetime, from launch to termination. It is identified by a unique sessionID and includes an overall status of either safe (no active critical threats), compromised (at least one active threat), or evaluating (the defense has not completed the verification logic required to detect the threat).

Installation-Level Data
Installation-level data resets on application upgrades or reinstalls.

Class: AppdomeThreatApi

AppdomeThreatApi exposes class methods for querying Threat-Memory™ data at runtime.

All methods:

  • Return a JSONObject
  • Execute synchronously using on-device data
  • Do not require delegates, callbacks, or network requests

 

Session-Level Methods

getSessionState()

Method Signature

Java

JSONObject getSessionState()

Kotlin

fun getSessionState(): JSONObject

Description

Returns the full Threat-Memory™ state for the current application session.

Parameters

None.

Returns

A JSONObject containing the full threat state for the current session. See the Returned Data section for the expected fields and example response.

 

Usage Examples

Java

import com.appdome.AppdomeThreatApi;
import org.json.JSONObject;
import android.util.Log;

JSONObject sessionState = AppdomeThreatApi.getSessionState();

// Print the entire object
Log.d("ThreatMemory", "Full session state: " + sessionState);

// Access a specific field
JSONObject threats = sessionState.optJSONObject("threats");
if (threats != null) {
    Log.d("ThreatMemory", "Threats: " + threats);
}

Kotlin

import com.appdome.AppdomeThreatApi
import org.json.JSONObject
import android.util.Log

val sessionState: JSONObject = AppdomeThreatApi.getSessionState()

// Print the entire object
Log.d("ThreatMemory", "Full session state: $sessionState")

// Access a specific field
val threats = sessionState.optJSONObject("threats")
if (threats != null) {
    Log.d("ThreatMemory", "Threats: $threats")
}

getSessionState(sessionID)

Method Signature

Java

JSONObject getSessionState(String sessionID)

Kotlin

fun getSessionState(sessionID: String): JSONObject

Description

Returns the full Threat-Memory™ state for a specific session.

Use this method with a session identifier returned from a previous Threat-Memory™ API call. The current session ID can be obtained from the sessionID field returned by getSessionState().

Calling getSessionState(currentSessionID) with the current sessionID is equivalent to calling getSessionState().

Parameters

Name

Type

Description

sessionID String The session identifier to query. You can obtain this value from the sessionID field returned by getSessionState().

Returns

A JSONObject containing the full threat state for the specified session. See Returned Data for the expected fields and example response.

Usage Example

Java

JSONObject sessionState = AppdomeThreatApi.getSessionState("");

Log.d("ThreatMemory", "Full session state: " + sessionState);

JSONObject threats = sessionState.optJSONObject("threats");
if (threats != null) {
    Log.d("ThreatMemory", "Threats: " + threats);
}

Kotlin

val sessionState = AppdomeThreatApi.getSessionState("")

Log.d("ThreatMemory", "Full session state: $sessionState")

val threats = sessionState.optJSONObject("threats")
if (threats != null) {
    Log.d("ThreatMemory", "Threats: $threats")
}

getThreatSessionState(threatName)

Method Signature

Java

JSONObject getThreatSessionState(String threatName)

Kotlin

fun getThreatSessionState(threatName: String): JSONObject

Description

Returns the Threat-Memory™ state for a single threat in the current session.

Use threatName to specify the Threat-Event identifier of the defense being queried. Refer to the Appdome Threat Knowledge Base to find the threat name associated with the specific protection you enabled.

Parameters

Name

Type

Description

threatNAME string The identifier of the threat to query. Use the same value returned in the “threatName” field from ThreatMemory responses (for example, “ActiveVpnDetected”).

Returns

A JSONObject containing the state of the specified threat for the current session. See Returned Data for the expected fields and example response.

Usage Example

Java

JSONObject threatState = AppdomeThreatApi.getThreatSessionState("ActiveVpnDetected");

Log.d("ThreatMemory", "Full threat state: " + threatState);

String state = threatState.optString("state", null);
if (state != null) {
    Log.d("ThreatMemory", "Threat state: " + state);
}

Kotlin

val threatState = AppdomeThreatApi.getThreatSessionState("ActiveVpnDetected")

Log.d("ThreatMemory", "Full threat state: $threatState")

val state = threatState.optString("state", null)
if (state != null) {
    Log.d("ThreatMemory", "Threat state: $state")
}

getThreatSessionState(threatName, sessionID)

Method Signature

Java

JSONObject getThreatSessionState(String threatName, String sessionID)

Kotlin

fun getThreatSessionState(threatName: String, sessionID: String): JSONObject

Description

Returns the Threat-Memory™ state for a single threat in the session identified by sessionID.

Use threatName to specify the identifier of the threat you want to query. This value should match the threatName field returned in Threat-Memory™ responses. Refer to the Appdome Threat Knowledge Base to find the correct threat name for the specific protection you enabled.

Use sessionID to specify the session to query. The sessionID field can be obtained from the getSessionState() response. Note that calling getThreatSessionState(threatName, currentSessionID) with the current sessionID is equivalent to calling getThreatSessionState(threatName).

Parameters

Name

Type

Description

threatNAME string The threat identifier
sessionID string The session identifier

Returns

A JSONObject containing the state of the specified threat for the specified session. See Returned Data for the expected fields and example response.

Usage Example

Java

JSONObject threatState = AppdomeThreatApi.getThreatSessionState(
    "ActiveADBDetected",
    ""
);

Log.d("ThreatMemory", "Full threat state: " + threatState);

String state = threatState.optString("state", null);
if (state != null) {
    Log.d("ThreatMemory", "Threat state: " + state);
}

Kotlin

val threatState = AppdomeThreatApi.getThreatSessionState(
    "ActiveADBDetected",
    ""
)

Log.d("ThreatMemory", "Full threat state: $threatState")

val state = threatState.optString("state", null)
if (state != null) {
    Log.d("ThreatMemory", "Threat state: $state")
}

Installation-Level Methods

getInstallationState()

Method Signature

Java

JSONObject getInstallationState()

Kotlin

fun getInstallationState(): JSONObject

Description

Returns the full Threat-Memory™ state for the current app installation.

Parameters

None.

Returns

A JSONObject containing the aggregated threat state across all sessions in the current installation. See Returned Data for the expected fields and example response.

Usage Example

Java

import com.appdome.AppdomeThreatApi;
import org.json.JSONObject;
import android.util.Log;

JSONObject installationState = AppdomeThreatApi.getInstallationState();

// Print the entire object
Log.d("ThreatMemory", "Full installation state: " + installationState);

// Access a specific field
JSONObject threats = installationState.optJSONObject("threats");
if (threats != null) {
    Log.d("ThreatMemory", "Threats: " + threats);
}

Kotlin

import com.appdome.AppdomeThreatApi
import org.json.JSONObject
import android.util.Log

val installationState: JSONObject = AppdomeThreatApi.getInstallationState()

// Print the entire object
Log.d("ThreatMemory", "Full installation state: $installationState")

// Access a specific field
val threats = installationState.optJSONObject("threats")
if (threats != null) {
    Log.d("ThreatMemory", "Threats: $threats")
}

getThreatInstallationState(threatName)

Method Signature

Java

JSONObject getThreatInstallationState(String threatName)

Kotlin

fun getThreatInstallationState(threatName: String): JSONObject

Description

Returns the aggregated Threat-Memory™ state for a single threat across all sessions in the current installation.

Use threatName to specify the identifier of the threat you want to query. This value should match the threatName field returned in Threat-Memory™ responses. Refer to the Appdome Threat Knowledge Base to find the threat name for the specific protection you enabled.

Parameters

Name

Type

Description

threatNAME string The threat identifier

Returns

A JSONObject containing the installation-level state of the specified threat. See Returned Data for the expected fields and example response.

Usage Example

Java

import com.appdome.AppdomeThreatApi;
import org.json.JSONObject;
import android.util.Log;

JSONObject threatState = AppdomeThreatApi.getThreatInstallationState("ActiveADBDetected");

// Print the entire object
Log.d("ThreatMemory", "Full installation-level threat state: " + threatState);

// Access a specific field
String state = threatState.optString("state", null);
if (state != null) {
    Log.d("ThreatMemory", "Threat state: " + state);
}

Kotlin

import com.appdome.AppdomeThreatApi
import org.json.JSONObject
import android.util.Log

val threatState: JSONObject =
    AppdomeThreatApi.getThreatInstallationState("ActiveADBDetected")

// Print the entire object
Log.d("ThreatMemory", "Full installation-level threat state: $threatState")

// Access a specific field
val state = threatState.optString("state", null)
if (state != null) {
    Log.d("ThreatMemory", "Threat state: $state")
}

Returned Data

All Threat-Memory™ API methods return a JSONObject containing Threat-Memory™ data.

Note

All timestamp fields are formatted as: YYYY-MM-DD HH:MM:SS.mmm

Example: 2026-04-12 14:32:07.412

Session State Response

Returned by:

getSessionState()
getSessionState(String sessionID)

Field

Type

Description 

Expected Values 

sessionID

String

Unique identifier for the session

UUID string

threats

JSONObject

Mapping of threat names to their threat state objects

Object of threat state objects

deviceMetadata

JSONObject

Device information collected at runtime, such as OS version, device model, and manufacturer.

Object of string key-value pairs

registeredThreatCount

Number

Total number of defenses tracked by ThreatMemory

Integer ≥ 0

detectedThreatCount

Number

Total number of detected threats, where each distinct threat is counted once.

Integer ≥ 0

sessionState

String

Overall security state of the session

evaluating, safe, compromised

buildID

String

Unique protected app identifier

Build token string

Device Metadata Object

Returned inside session and installation responses under the deviceMetadata key.

Every field is a JSON array of strings. In a session response, each array contains exactly one value (the value at session start). In an installation response, hardware-constant fields still contain one value, while environment fields that can change between sessions (for example, after an OS update) contain all distinct values observed across sessions, ordered from most recent to oldest.

Field

Type

Description

Expected Values

deviceManufacturer

JSONArray<String>

Device hardware manufacturer

JSON array of strings

deviceModel

JSONArray<String>

Device model identifier

JSON array of strings

deviceBrand

JSONArray<String>

Device brand name

JSON array of strings

deviceBoard

JSONArray<String>

Device board name

JSON array of strings

osVersion

JSONArray<String>

Android OS version

JSON array of strings

kernelInfo

JSONArray<String>

Linux kernel version

JSON array of strings

sdkVersion

JSONArray<String>

Android SDK version

JSON array of strings

buildNumber

JSONArray<String>

OS build number

JSON array of strings

basebandVersion

JSONArray<String>

Baseband/radio firmware version

JSON array of strings

buildUser

JSONArray<String>

OS build user identifier

JSON array of strings

buildHost

JSONArray<String>

OS build host identifier

JSON array of strings

Threat State Object

Represents the state of a single threat.

Returned by:

The threats object in the Session State Response

getThreatSessionState(...)

getThreatInstallationState(...)

Field

Type

Description 

Expected Values 

threatName

String

Unique threat identifier

Example: ActiveADBDetected

transitionType

String

Defines whether the threat persists or returns to a safe state.

resolvable, persistentThreat

buildID

String

Unique protected app identifier

Build token string

threatState

String

Threat lifecycle state

active, detectedInSession, detectedInPreviousSession, notDetected, evaluating

state

String

Current threat risk state.

compromised – active threat.

evaluating – threat evaluation hasn’t completed.
safe– threat is not detected.

evaluating, safe, compromised

detectionCount

Number

Number of recorded threat occurrences

Integer ≥ 0

lastStateChangeTime

String

Last time the threat state changed. Empty string indicates that the threat was not detected.

Timestamp or Empty string

firstDetectionTimestamp

String

Time of first detection. Empty string indicates that the threat was not detected.

Timestamp or Empty string

lastDetectionTimestamp

String

Time of most recent detection. Empty string indicates that the threat was not detected.

Timestamp or Empty string

detectionData

JSONObject

Device identity and environment metadata captured at session start. Each field is an array containing a single value.

See Device Metadata Object.

Detection Data Object

Represents detailed information about a specific detection event.

Field

Type

Description

Expected Values

reasonCode

String

Code representing the detection type

String

threatCode

String

Appdome-specific threat identifier

String

reasonData

String

Description of the detection

String – Free text

occurrenceCount

Integer

Count how many this specific detection has been detected

Integer >=0

detectionReference

String

Reference code to provide to the Appdome Support agent for remediation or inquiries about this detection.

String

params

JSONObject

Additional detection data, which may include more metadata regarding the detection.

Detection data params may include additional fields depending on the specific threat and detection context.

DetectionData Example

When a threat is detected:

[
  {
    "reasonCode": "9999",
    "threatCode": "AAAAA",
    "reasonData": "X was detected by Y...",
    "occurrenceCount": 1,
    "detectionReference": "9999:1234:AAAAA",
    "params": {...}
  }
]

When a threat is not detected:

[]

Installation State Response

Returned by:

getInstallationState()

Field 

Type

Description 

Expected Values

installationID

String

Unique identifier for the app installation

UUID string

registeredThreatCount

Number

Total number of threats registered as ThreatMemory features

Integer ≥ 0

detectedThreatCount

Number

Total number of detected threats, where each distinct threat is counted once.

Integer ≥ 0

installationState

String

Aggregated threat state across all sessions

evaluating, safe, compromised

sessionList

JSONArray

List of session IDs for this installation, ordered from most recent to oldest.

Array of session IDs

deviceMetadata

JSONObject

Device attributes and environment metadata. Each field is an array. Hardware-constant fields contain a single value. Environment fields that can change between sessions contain all distinct values observed across sessions, ordered from most recent to oldest.

See Device Metadata Object.

threats

JSONObject

Mapping of threat names to aggregated threat state objects

Object of threat state objects

Example Output

getSessionState() and getSessionState(sessionID)

{
  "sessionID": "",
  "buildID": "",
  "sessionState": "compromised",
  "registeredThreatCount": 2,
  "detectedThreatCount": 1,
  "deviceMetadata": {
    "deviceManufacturer": ["Samsung"],
    "deviceModel": ["SM-G991B"],
    "deviceBrand": ["samsung"],
    "deviceBoard": ["exynos2100"],
    "osVersion": ["14"],
    "kernelInfo": ["..."],
    "sdkVersion": ["34"],
    "buildNumber": ["..."],
    "basebandVersion": ["..."],
    "buildUser": ["..."],
    "buildHost": ["..."]
  },
  "threats": {
    "ActiveADBDetected": {
      "threatName": "ActiveADBDetected",
      "transitionType": "persistentThreat",
      "buildID": "",
      "threatState": "active",
      "state": "compromised",
      "detectionCount": 1,
      "lastStateChangeTime": "2026-04-12 14:32:05.100",
      "firstDetectionTimestamp": "2026-04-12 14:32:01.230",
      "lastDetectionTimestamp": "2026-04-12 14:32:05.100",
      "detectionData": [
        {
          "reasonCode": "9999",
          "threatCode": "AAAAA",
          "reasonData": "...info..",
          "occurrenceCount": 1,
          "detectionReference": "9999:1234:AAAAA",
          "params": {...}
        }
      ]
    },
    "FridaDetected": {
      "threatName": "FridaDetected",
      "transitionType": "resolvable",
      "threatState": "notDetected",
      "state": "safe",
      "detectionCount": 0,
      "lastStateChangeTime": "",
      "firstDetectionTimestamp": "",
      "lastDetectionTimestamp": "",
      "detectionData": []
    }
  }
}

getThreatSessionState(threatName)and getThreatSessionState(threatName, sessionId)

Returns the state of a single threat within the current session.

{
  "threatName": "RootedDevice",
  "transitionType": "persistentThreat",
  "buildID": "",
  "threatState": "active",
  "state": "compromised",
  "detectionCount": 2,
  "lastStateChangeTime": "2026-04-12 14:32:05.100",
  "firstDetectionTimestamp": "2026-04-12 14:32:01.230",
  "lastDetectionTimestamp": "2026-04-12 14:32:05.100",
  "detectionData": [
    {
      "reasonCode": "AAAA",
      "threatCode": "5ABCDE",
      "reasonData": "...info..",
      "occurrenceCount": 1,
      "detectionReference": "AAAA:1234:5ABCDE",
      "params": {...}
    }
  ]
}

getInstallationState()

Returns the aggregated threat state across all sessions for the current app installation.

{
  "installationID": "",
  "registeredThreatCount": 3,
  "detectedThreatCount": 2,
  "installationState": "compromised",
  "sessionList": [
    "",
    ""
  ],
  "deviceMetadata": {
    "deviceManufacturer": ["Samsung"],
    "deviceModel": ["..."],
    "deviceBrand": ["..."],
    "deviceBoard": ["..."],
    "osVersion": ["14", "13"],
    "kernelInfo": ["..A..", "..B."],
    "sdkVersion": ["34", "33"],
    "buildNumber": ["UP1A.231005.007", "TP1A.220624.014"],
    "basebandVersion": ["G991BXXS9FXA1", "G991BXXS8EWL1"],
    "buildUser": ["..."],
    "buildHost": ["..."]
  },
  "threats": {
    "RootedDevice": {
      "threatName": "RootedDevice",
      "transitionType": "persistentThreat",
      "buildID": "",
      "threatState": "active",
      "state": "compromised",
      "detectionCount": 5,
      "lastStateChangeTime": "2026-04-12 14:32:05.100",
      "firstDetectionTimestamp": "2026-04-10 09:15:22.800",
      "lastDetectionTimestamp": "2026-04-12 14:32:05.100",
      "detectionData": [
        {
          "reasonCode": "AAAA",
          "threatCode": "5ABCDE",
          "reasonData": "...info...",
          "occurrenceCount": 5,
          "detectionReference": "AAAA:1234:5ABCDE",
          "params": {...}
        }
      ],
      "detectedSessions": {
        "": 2,
        "": 3
      }
    },
    "FridaDetected": {
      "threatName": "FridaDetected",
      "transitionType": "resolvable",
      "buildID": "",
      "threatState": "notDetected",
      "state": "safe",
      "detectionCount": 0,
      "lastStateChangeTime": "",
      "firstDetectionTimestamp": "",
      "lastDetectionTimestamp": "",
      "detectionData": []
    },
    "AppIsDebuggable": {
      "threatName": "AppIsDebuggable",
      "transitionType": "resolvable",
      "buildID": "",
      "threatState": "detectedInPreviousSession",
      "state": "safe",
      "detectionCount": 1,
      "lastStateChangeTime": "2026-04-10 09:16:10.300",
      "firstDetectionTimestamp": "2026-04-10 09:16:10.300",
      "lastDetectionTimestamp": "2026-04-10 09:16:10.300",
      "detectionData": [
        {
          "reasonCode": "BBBB",
          "threatCode": "1ABCDE",
          "reasonData": "...info..",
          "occurrenceCount": 1,
          "detectionReference": "BBBB:1234:1ABCDE",
          "params": {....}
        }
      ],
      "detectedSessions": {
        "": 1
      }
    }
  }
}

getThreatInstallationState(threatName)

Returns the aggregated state of a single threat across all sessions.

{
  "threatName": "RootedDevice",
  "transitionType": "persistentThreat",
  "buildID": "",
  "threatState": "active",
  "state": "compromised",
  "detectionCount": 5,
  "lastStateChangeTime": "2026-04-12 14:32:05.100",
  "firstDetectionTimestamp": "2026-04-10 09:15:22.800",
  "lastDetectionTimestamp": "2026-04-12 14:32:05.100",
  "detectionData": [
    {
      "reasonCode": "AAAA",
      "threatCode": "BBBBBB",
      "reasonData": "...",
      "occurrenceCount": 5,
      "params": {...}
    }
  ],
  "detectedSessions": {
    "": 2,
    "": 3
  }
}

Retention Policy

Threat-Memory™ stores threat detection data locally on the device to enable both real-time and historical analysis.

Session data remains available during app runtime and is cleared when the app closes.

Historical data (cross-session threat data) is preserved in persistent storage on the device.

Installation-level data is reset when the app is updated or reinstalled.

Threat-Memory™ retains threat data using a rolling history of sessions and detections, discarding older entries as new data arrives once the number of sessions containing threat data exceeds the configured window size. Both the rolling session window size and the volume of unique threat data retained are governed by the retention policy defined in the defense policy.

How to Interpret the Response

Threat-Memory™ responses provide an overall risk state as well as detailed per-threat information.

Overall State vs. Per-Threat State

sessionState / installationState

Represents the overall risk status of the session or installation.

Value

Meaning 

safe

No active threats detected

evaluating

There are no active threats, but at least one threat has not yet completed its initial evaluation.

compromised

At least one threat is currently active

state per threat

Indicates whether a specific threat is currently active.

Value

Meaning 

evaluating

The defense hasn’t not yet completed the initial threat evaluation.

safe

No threat is currently impacting the app

compromised

Active threat is actively impacting the app

Threat Lifecycle: threatState

The threatState field describes the lifecycle state of a threat.

Value

Meaning 

active

Threat is currently active and affecting the app

detectedInSession

Threat was detected earlier in the current session, but is not currently active

detectedInPreviousSession

Threat was detected in a previous session

notDetected

Threat has never been detected

evaluating

The defense has not completed the initial threat evaluation.

 

Persistent vs. Resolvable Threats

The transitionType field indicates how a threat behaves over time.

Value

Meaning 

persistentThreat

The threat is considered active once detected, such as a rooted or jailbroken device

resolvable

The threat can be resolved and return to a safe state, such as vpn or proxy

Detection Count and History

These fields provide insight into threat frequency and timing base on the scope of the query – session vs installation.

Value

Meaning 

detectionCount

Total number of threat detection occurrences

firstDetectionTimestamp

First time the threat was detected

lastDetectionTimestamp

Most recent detection

lastStateChangeTime

Last time the threat state changed

Detection Data

The detectionData field provides additional context about a detected threat.

When a threat is detected, detectionData is an array of objects with these fields:

reasonCode
threatCode
reasonData
occurrenceCount
detectionReference
params

When a threat is not detected, detectionData is an empty array.

Session and Installation Scope

A session represents a single app launch.

An installation aggregates threat data across multiple sessions for the current app installation.

Installation-level data:

  • Is tied to the current app installation.
  • Does not persist between app reinstalls.

Use installation-level data to evaluate long-term risk patterns, such as fraud or staged attacks carried out across multiple sessions.

Example Interpretation

The following examples show how to check whether the current session is compromised and identify which threats are active.

Java

import android.util.Log;
import org.json.JSONObject;
import java.util.Iterator;

JSONObject sessionState = AppdomeThreatApi.getSessionState();

String overallState = sessionState.optString("sessionState", "");

if ("compromised".equals(overallState)) {
    Log.d("ThreatMemory", "The session is compromised");

    JSONObject threats = sessionState.optJSONObject("threats");
    if (threats != null) {
        Iterator threatNames = threats.keys();

        while (threatNames.hasNext()) {
            String threatName = threatNames.next();
            JSONObject threat = threats.optJSONObject(threatName);

            if (threat != null && "compromised".equals(threat.optString("state", ""))) {
                Log.d("ThreatMemory", "Active threat: " + threatName);
            }
        }
    }
}

Kotlin

import android.util.Log
import org.json.JSONObject

val sessionState: JSONObject = AppdomeThreatApi.getSessionState()

val overallState = sessionState.optString("sessionState", "")

if (overallState == "compromised") {
    Log.d("ThreatMemory", "The session is compromised")

    val threats = sessionState.optJSONObject("threats")
    if (threats != null) {
        val threatNames = threats.keys()

        while (threatNames.hasNext()) {
            val threatName = threatNames.next()
            val threat = threats.optJSONObject(threatName)

            if (threat?.optString("state", "") == "compromised") {
                Log.d("ThreatMemory", "Active threat: $threatName")
            }
        }
    }
}

This example:

  • Checks whether the session is compromised.

  • Iterates over all threats in the threats object.

  • Identifies which threats are currently active.

Related Articles

How Do I Learn More?

If you have any questions, please send them our way at support.appdome.com or via the chat window on the Appdome platform.

Thank you!

Thanks for visiting Appdome! Our mission is to secure every app on the planet by making mobile app security easy. We hope we’re living up to the mission with your project.

Appdome

Want a Demo?

Threat-Events™ UX/UI Control

GilWe're here to help
We'll get back to you in 24 hours to schedule your demo.