# Android Device State & Security Snippets

Below is a quick-reference guide for the most commonly requested Android device property and security checks.

#### 1. Active USB Connection

If you want to know if a USB device (like a flash drive, keyboard) is plugged *into* the Android device (Android as Host), or if the Android device is plugged into a specific piece of hardware designed for it (Android as Accessory), you use the official `UsbManager` API.

```kotlin
val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager

// 1. Android as Host: Checks if external USB devices are plugged INTO the phone
val isUsbDeviceConnected = usbManager.deviceList.isNotEmpty()

// 2. Android as Accessory: Checks if the phone is plugged into a USB accessory (like a car dock)
val isUsbAccessoryConnected = usbManager.accessoryList?.isNotEmpty() == true
```

#### 2. Work Profile Detection

Checks if the application executing the code is running inside a managed Work Profile.

> Note: Checking if the device *has* a work profile from a personal profile generally requires elevated permissions, so checking the *current* profile's state is the standard approach.

```kotlin
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
// Returns true if the app is currently running inside a managed profile
val isRunningInWorkProfile = userManager.isManagedProfile
```

#### 3. Device Encryption Status

Checks if the device storage is currently encrypted. Modern Android devices (Android 10+) are encrypted by default out-of-the-box.

```kotlin
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val status = dpm.storageEncryptionStatus

val isEncrypted = status == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE || 
                  status == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER
```

#### 4. Unknown Sources Enabled

Checks if the user has allowed the installation of apps from outside the Google Play Store. The method changed significantly in Android 8.0 (API 26) from a global setting to a per-app permission.

```kotlin
fun canInstallFromUnknownSources(packageInfo: PackageInfo): Boolean {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        return false
    }
    val uid = packageInfo.applicationInfo?.uid ?: return false
    val mode = appOpsManager?.checkOpNoThrow(
        AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES,
        uid,
        packageInfo.packageName
    )
    return mode == AppOpsManager.MODE_ALLOWED
}
```

#### 5. Bootloader Unlock Status

The simplest way to check this without setting up complex cryptographic attestation is by reading system properties via the command line.

> Warning: This method is simple but can be spoofed by tools like Magisk on rooted devices. For strict enterprise security, you must use hardware-backed KeyStore Attestation (SafetyNet / Play Integrity API).

```kotlin
fun isBootloaderUnlocked(): Boolean {
    return try {
        val process = Runtime.getRuntime().exec("getprop ro.boot.flash.locked")
        val reader = java.io.BufferedReader(java.io.InputStreamReader(process.inputStream))
        val lockedState = reader.readLine()
        // "0" typically means unlocked, "1" means locked
        lockedState == "0"
    } catch (e: Exception) {
        false // Default to false if unable to read
    }
}
```

#### 6. Last Security Patch Date

Retrieves the date of the last installed Android security patch. This is returned as a highly readable string in a `YYYY-MM-DD` format.

```kotlin
val securityPatchDate = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    Build.VERSION.SECURITY_PATCH
} else {
    "N/A" // Security patch dates were not standardized before Android 6.0 (API 23)
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.talsec.app/appsec-articles/glossary/android-device-state-and-security-snippets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
