When an Android 16 (or higher) device boots, it's put in trade-in mode, which lets you connect to the device using adb and use a command to obtain information about the device. The following preconditions must exist for the device to enter trade-in mode:
- The device must be factory reset.
- The device must not have cellular service.
- The device must not have connectivity or an account established.
- The device must be running a nondebuggable build.
After you navigate through the setup wizard, the device is placed in evaluation mode, which lets you perform a full range of adb commands and run additional diagnostics on the device.
Gather general health information
To gather general health information for your device, such as information about the battery, storage health, and international mobile equipment identity (IMEI) numbers, follow these steps:
Ensure your device meets the preconditions for trade-in mode.
Plug the device into a workstation.
From the workstation, run the following command:
adb shell tradeinmode getstatus
This command returns a JSON object with information about the device. The following is example output from a Pixel 7:
{ "battery": { "cycle_count": 16, "health": 100, "state": 2, "manufacturing_date": 1653004800, "first_usage_date": 0 }, "storage": { "useful_lifetime_remaining": 99, "capacity_bytes": "128000000000" }, "launch_level": 33, "locks": { "factory_reset_protection": false }, "product": { "brand": "google", "device": "panther", "manufacturer": "Google", "model": "Pixel 7", "name": "panther" }, "imeis": [ "353644930127905", "353644930127913" ], "serial": "26061FDH2000AP" }
If
factory_reset_protection
is set totrue
, the device is secure and can't be reset. If the device can't be reset, it can't be evaluated.
Identify Android OS state
To gather information about the state of the Android operating system, such as if it an approved build, follow these steps:
- Plug the device into a workstation.
- Make sure the device has Internet connectivity.
From the workstation, run the following command:
adb shell tradeinmode getstatus --challenge CHALLENGE
The CHALLENGE is a randomly generated alphanumeric string, such as
p4tRsuHjWB
. This command returns JSON including an attestation field containing a base64 attestation record.This command appends an attestation information to the information returned by the
getstatus
command. The attestation information looks like this:"attestation": { "certificates": "AAAC\/DCCAvgwggKeoAMCAQICAQEwCgYIKoZIzj0EAwIwOTEMMAoGA1UEDAwDVEVFMSkwJwYDVQQF\n EyBmOTIyZTZhOWFkZmRjNjU0NmZiOWU1YmNlNzhiMDUzMzAeFw03MDAxMDEwMDAwMDBaFw00ODAx\n MDEwMDAwMDBaMB8xHTAbBgNVBAMTFEFuZHJvaWQgS2V5c3RvcmUgS2V5MFkwEwYHKoZIzj0CAQYI\n KoZIzj0DAQcDQgAEz9un3HpDJQy\/j7l0bWzw6WnRRMjFjvu6rg7+dCzFW93u+otCPK4VjmSjyYw ... }
Devices launching with Android 16 or higher require Internet connectivity to create an attestation record. Attestation should be performed in evaluation mode, after configuring a connection, as it fails if performed in the setup wizard.
Parse the attestation information using one of the following methods:
- Use the
parse_tim_attestation
tool that is built when you build AOSP. - Use an Android key attestation library.
For example, to use the
parse_tim_attestation
tool, run:parse_tim_attestation --challenge CHALLENGE output_file
The CHALLENGE must be the same challenge you used to obtain the attestation information.
If you saved the output of step 2 to an output_file, you can provide that filename. Otherwise, the attestation information is read from stdin.
A JSON object with the Android OS information is returned:
"record": { "keymaster_version": "400", "keymaster_security_level": "TRUSTED_ENVIRONMENT", "attributes": { "imeis": [ "353644930125669", "353644930125677" ], "vendor_patch_level": 20250305, "serial": "26161FDH2000NV", "os_version": 160000, "source": "hardware", "boot_patch_level": 20250305 }, "bootloader_locked": false, "verified_boot": false, "security_level": "TRUSTED_ENVIRONMENT" }, "certificate": "verified", "trustworthy": "verified boot disabled"
If
trustworthy
is equal toyes
, the operating system is considered trusted; the build is signed and the IMEI isn't forged.Note that Internet connectivity is needed to perform attestation, both on the device and on the host.
- Use the
Test trade-in mode
During development, you should test your device to ensure that your device properly enters and exists trade-in mode. Follow these steps to test your device's ability to enter and exit trade-in mode:
Plug the device into a workstation.
From the workstation, reboot the device into trade-in mode:
adb shell tradeinmode testing start
The device is rebooted and enters into trade-in mode. After entering trade-in mode, you can use any
adb shell tradein
command.Ensure trade-in mode is active:
adb shell tradeinmode testing status
The device identifies that trade-in mode testing is active.
Exit trade-in mode and restore full adb access:
adb shell tradeinmode testing stop
Custom setup wizard integration
The evaluate
command won't work on devices with custom setup wizards
unless a broadcast receiver is added. To add a broadcast receiver to the custom
setup wizard app:
Declare a receiver in the apps manifest:
<receiver android:name=".EnterEvaluationModeReceiver" android:exported="true" android:permission="android.permission.ENTER_TRADE_IN_MODE"> <intent-filter> <action android:name="com.google.android.setupwizard.ENTER_TRADE_IN_MODE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
Create a broadcast receiver similar to:
public class EnterEvaluationModeReceiver extends BroadcastReceiver { private static final String TRADE_IN_MODE_PROPERTY = "persist.adb.tradeinmode"; private static final int TIM_EVALUATION_MODE = 2; @Override public void onReceive(Context context, Intent intent) { if (SystemProperties.getInt(TRADE_IN_MODE_PROPERTY, 0) != TIM_EVALUATION_MODE) { return; } // Check if any factory reset protection is enabled. // Provision the device. // End the setup wizard activity. } }
The receiver must perform the following actions in order.
- Check that
persist.adb.tradeinmode
is2
. - Check that there are no factory reset protection or antitheft locks present.
- Provision the device, ensuring that
Settings.Secure.USER_SETUP_COMPLETE
andSettings.Global.DEVICE_PROVISIONED
are1
. - Dismiss the setup wizard activity so the device is at the home screen.
Trade-in-mode reference
This section explains all of the trade-in-mode commands.
evaluate
adb shell tradeinmode evaluate
Enters evaluation mode by skipping the setup wizard as though every setup screen was manually skipped by the user.
After skipping the setup wizard, you can run additional ADB commands or functional tests on the device.
After you leave evaluation mode, a factory reset occurs to ensure that no artifacts from testing are accidentally transferred to any customers.
getstatus
adb shell tradeinmode getstatus [--challenge CHALLENGE]
Returns a JSON string with system information, including battery and storage health information, for the device.
Include the --challenge
parameter followed by a randomly generated
alphanumeric challenge key to return an additional attestation field. Parse
this response to identify key operating system information, such as the
status of the bootloader (locked or unlocked) and validity of
IMEI serial numbers.
poweroff
adb shell tradeinmode poweroff
Powers off the device. Use this command to prevent battery drain while the device isn't being actively tested or evaluated.
reboot
adb shell tradeinmode reboot
Reboots the device.
testing start
adb shell tradeinmode testing start
Reboots the device into trade-in mode. This command works only within the setup wizard. Upon issuing this command, authorization is bypassed and only trade-in mode commands work.
This command works only on devices with userdebug
, eng
, or user
builds. The user
build must have ro=debuggable=1
set.
testing status
adb shell tradeinmode testing status
Identifies if trade-in mode testing is active.
This command works only on devices with userdebug
, eng
, or user
builds. The user
build must have ro=debuggable=1
set.
testing stop
adb shell tradeinmode testing stop
Returns the device to whatever mode it was in before you issued the
adb shell tradeinmode testing start
command.
This command works only on devices with userdebug
, eng
, or user
builds. The user
build must have ro=debuggable=1
set.
testing wipe
adb shell tradeinmode testing wipe
Factory resets the device.
This command works only on devices with userdebug
, eng
, or user
builds. The user
build must have ro=debuggable=1
set.
wait-until-ready
adb shell tradeinmode wait-until-ready
Waits until system services are ready so that trade-in mode can function fully. Use this command within your automation to ensure trade-in mode commands are successful.
You can add wait-until-ready
before other trade-in mode commands. For
example, here is wait-until-ready
chained to getstatus
:
adb shell tradeinmode wait-until-ready getstatus