システムの健全性に関する情報を取得する

Android 16(またはそれ以降)のデバイスは、起動時に「下取りモード」に移行し、adb を使用してデバイスに接続したり、コマンドを使用してデバイスに関する情報を取得したりできるようになります。デバイスが下取りモードに移行するのは、以下の前提条件を満たしている場合のみです。

  • デバイスが出荷時の設定にリセットされていること。
  • デバイスがモバイル通信サービスに接続されていないこと。
  • デバイスに接続性がないか、開設されているアカウントがないこと。
  • デバイスがデバッグ不可のビルドを実行していること。

設定ウィザードを完了すると、デバイスが「評価モード」に移行し、デバイス上ですべての adb コマンドと追加の診断を実行できるようになります。

健全性に関する一般情報を収集する

バッテリーに関する情報、ストレージの健全性、国際移動体装置識別(IMEI)番号など、デバイスの健全性に関する一般情報を収集する手順は次のとおりです。

  1. デバイスが、下取りモードの前提条件を満たしていることを確認します。

  2. デバイスをワークステーションに接続します。

  3. ワークステーションから次のコマンドを実行します。

    adb shell tradeinmode getstatus

    このコマンドを実行すると、デバイスに関する情報を含む JSON オブジェクトが返されます。次に Google 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"
    }
    

    factory_reset_protectiontrue に設定されていると、デバイスが保護されるためリセットできません。リセットできないデバイスは評価できません。

Android OS の状態を特定する

Android オペレーティング システムの状態に関する情報(ビルドが承認済みかどうかなど)を収集する手順は次のとおりです。

  1. デバイスをワークステーションに接続します。
  2. デバイスがインターネットに接続されていることを確認します。
  3. ワークステーションから次のコマンドを実行します。

    adb shell tradeinmode getstatus --challenge CHALLENGE

    CHALLENGE は、ランダムに生成される英数字の文字列です(例: p4tRsuHjWB)。このコマンドを実行すると、base64 構成証明レコードが格納された構成証明フィールドを含む JSON が返されます。

    このコマンドにより、getstatus コマンドで返された情報に構成証明情報が追加されます。次に構成証明情報の例を示します。

    "attestation": {
      "certificates": "AAAC\/DCCAvgwggKeoAMCAQICAQEwCgYIKoZIzj0EAwIwOTEMMAoGA1UEDAwDVEVFMSkwJwYDVQQF\n
        EyBmOTIyZTZhOWFkZmRjNjU0NmZiOWU1YmNlNzhiMDUzMzAeFw03MDAxMDEwMDAwMDBaFw00ODAx\n
        MDEwMDAwMDBaMB8xHTAbBgNVBAMTFEFuZHJvaWQgS2V5c3RvcmUgS2V5MFkwEwYHKoZIzj0CAQYI\n
        KoZIzj0DAQcDQgAEz9un3HpDJQy\/j7l0bWzw6WnRRMjFjvu6rg7+dCzFW93u+otCPK4VjmSjyYw
        ...
    }
    

    Android 16 以降を搭載してリリースされるデバイスでは、構成証明レコードの作成時にインターネット接続が必要となります。構成証明は、設定ウィザードで実行すると失敗するため、接続を設定した後に評価モードで実行する必要があります。

  4. 次のいずれかのメソッドを使用して構成証明情報を解析します。

    たとえば、parse_tim_attestation ツールを使用するには次のコマンドを実行します。

    parse_tim_attestation --challenge CHALLENGE output_file

    CHALLENGE には、構成証明情報の取得に使用したのと同じチャレンジを指定する必要があります。

    ステップ 2 の出力を output_file に保存した場合は、そのファイル名を指定できます。保存していない場合は、構成証明情報が stdin から読み込まれます。

    Android OS の情報が格納された JSON オブジェクトが返されます。

    "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"
    

    trustworthyyes の場合、オペレーティング システムは信頼できる(ビルドは署名付きで IMEI は偽造されていない)と判断されます。

    なお、構成証明を実行するには、デバイスとホストの両方でインターネット接続が必要となります。

下取りモードをテストする

開発中に下取りモードをテストして、デバイスでのモードの開始と終了が正しく行われることを確認する必要があります。デバイスで、下取りモードの開始と終了をテストする手順は次のとおりです。

  1. デバイスをワークステーションに接続します。

  2. ワークステーションから、下取りモードでデバイスを再起動します。

    adb shell tradeinmode testing start

    デバイスが再起動し、下取りモードに移行します。下取りモードに移行した後は、すべての adb shell tradein コマンドを使用できます。

  3. 下取りモードが有効になっていることを確認します。

    adb shell tradeinmode testing status

    デバイスで下取りモードのテストが有効になっていることがわかります。

  4. 下取りモードを終了し、adb にフルアクセスできる状態に戻します。

    adb shell tradeinmode testing stop

カスタム設定ウィザードの統合

ブロードキャスト レシーバが追加されていない限り、evaluate コマンドはカスタム設定ウィザードを備えたデバイスでは機能しません。カスタム設定ウィザード アプリにブロードキャスト レシーバを追加するには:

  1. アプリ マニフェストでレシーバーを宣言します。

    <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>
    
  2. 次のようなブロードキャスト レシーバを作成します。

    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.
     }
    }
    

受信側は、次の操作を順番に行う必要があります。

  1. persist.adb.tradeinmode2 であることを確認します。
  2. 出荷時設定へのリセット保護機能や盗難防止ロックが設定されていないことを確認します。
  3. デバイスをプロビジョニングし、Settings.Secure.USER_SETUP_COMPLETESettings.Global.DEVICE_PROVISIONED1 であることを確認します。
  4. セットアップ ウィザードのアクティビティを閉じて、デバイスをホーム画面に移動します。

下取りモードのリファレンス

このセクションでは、下取りモードのすべてのコマンドについて説明します。

evaluate

adb shell tradeinmode evaluate

設定ウィザードをスキップして評価モードに移行します。ユーザーが手動ですべてのセットアップ画面をスキップしたかのような動作を再現できます。

設定ウィザードをスキップした後は、追加の ADB コマンドやデバイスでの機能テストを実行できます。

評価モードを終了すると、出荷時の設定へのリセットが発生します。これにより、テストのアーティファクトが誤って購入者に転送されるのを防ぎます。

getstatus

adb shell tradeinmode getstatus [--challenge CHALLENGE]

デバイスのシステム情報(バッテリーやストレージの健全性に関する情報など)を含む JSON 文字列を返します。

--challenge パラメータを追加し、その後にランダムに生成された英数字のチャレンジ キーを指定すると、追加の構成証明フィールドが返されます。このレスポンスを解析することで、ブートローダーのステータス(ロックまたはロック解除)や IMEI シリアル番号の有効性など、主要なオペレーティング システム情報を特定できます。

poweroff

adb shell tradeinmode poweroff

デバイスの電源をオフにします。このコマンドは、デバイスのテストや評価を実行していないときに、バッテリーの消耗を防ぐために使用します。

reboot

adb shell tradeinmode reboot

デバイスを再起動します。

testing start

adb shell tradeinmode testing start

デバイスを下取りモードで再起動します。このコマンドは、設定ウィザード内でのみ機能します。このコマンドの発行時には認証がバイパスされ、下取りモードのコマンドのみ使用できる状態になります。

このコマンドは、userdebugeng、または user ビルドのデバイスでのみ機能します。user ビルドの場合は ro=debuggable=1 が設定されている必要があります。

testing status

adb shell tradeinmode testing status

下取りモードのテストが有効かどうかを特定します。

このコマンドは、userdebugeng、または user ビルドのデバイスでのみ機能します。user ビルドの場合は ro=debuggable=1 が設定されている必要があります。

testing stop

adb shell tradeinmode testing stop

デバイスのモードを、adb shell tradeinmode testing start コマンドを発行する前の状態に戻します。

このコマンドは、userdebugeng、または user ビルドのデバイスでのみ機能します。user ビルドの場合は ro=debuggable=1 が設定されている必要があります。

testing wipe

adb shell tradeinmode testing wipe

デバイスを出荷時の設定にリセットします。

このコマンドは、userdebugeng、または user ビルドのデバイスでのみ機能します。user ビルドの場合は ro=debuggable=1 が設定されている必要があります。

wait-until-ready

adb shell tradeinmode wait-until-ready

システム サービスの準備が整うまで待機して、下取りモードが完全に機能するようにします。このコマンドを自動化内で使用することで、下取りモードのコマンドを確実に実行できます。

wait-until-ready を他の下取りモード コマンドの前に追加できます。次に、wait-until-readygetstatus にチェーンした例を示します。

adb shell tradeinmode wait-until-ready getstatus