リモート アクセスを設定する

Android 14 では、新しいリモート アクセス機能が導入され、パートナーが車両の Android をリモートで復帰させ特定のタスクを実行できるようになります。たとえば、ソフトウェアをアップデートするために一晩ガレージモードを実行できます。エンドツーエンドのワークフローでは、非 Android コンポーネントが複数必要です。Android は非 Android コンポーネントの実装を定義、または提供しません(ユーザーの責任となります)。

詳しくは、次のセクションをご覧ください。

アーキテクチャ

次のコンテンツは以下のサンプル アーキテクチャを使用することを前提としていますが、仮定的なものであり実際のアーキテクチャが反映されていない可能性があります。OEM は、車両やサーバーのアーキテクチャに実際の実装を合わせる必要があります。

画像

図 1. サンプル アーキテクチャ。

サンプル アーキテクチャは次のハードウェア コンポーネントで構成されます。

ハードウェア コンポーネント 説明
アプリ プロセッサ Android を実行するプロセッサ。Android は、このプロセッサの仮想メモリ(VM)上で(実際のハードウェア上ではなく)動作する場合があります。
車両プロセッサ アプリ プロセッサの電源を制御するプロセッサ。
テレマティクス コントロール ユニット(TCU) クラウドからのリモート メッセージを常時受信できる車載プロセッサ。TCU は常に電源が入っているか、低電力モードになっていると想定されます。リモート メッセージを使って TCU を起動します。
ウェイクアップ サーバー クラウド上で稼働するリモート サーバー。車両の TCU と通信し、ウェイクアップ コマンドを実行します。
リモートタスク サーバー クラウド上で稼働するリモートタスク サーバー。ユーザーと通信しリモートタスクを管理します。

サンプル アーキテクチャは次のソフトウェア コンポーネントで構成されます。これらのコンポーネントはすべて Android で動作します。

Android のソフトウェア コンポーネント 説明
カーサービス リモート アクセス API を提供する AAOS フレームワーク サービス。
リモートタスク クライアント リモートタスクを実行するベンダー作成 Service クラス。1 つの Android システムで複数のリモートタスク クライアントを実行できます。
リモート アクセス HAL リモート アクセスを利用するために実装する必要があります。
AAOS と非 Android コンポーネント(TCU など)間のコミュニケーションのための抽象化レイヤ。

非 Android ソフトウェア コンポーネントは次のとおりです。

非 Android ソフトウェア コンポーネント 説明
ウェイクアップ クライアント ウェイクアップ サーバーと長時間接続を維持する TCU で実行されるソフトウェア。また、リモート アクセス HAL との接続も維持し、カーサービスにリモートタスクを配信します。
ウェイクアップ サーバー実装 TCU で実行されるウェイクアップ クライアントと通信するサーバー。ウェイクアップ クライアントにウェイクアップ リクエストを送信できます。
リモートタスク サーバー実装 リモートタスクを管理するサーバー。ユーザーはこのサーバーと通信し、リモートタスクを発行、モニタリングします。

ワークフロー

このセクションでは、サンプル ワークフローでの手順を示します。

サンプル ワークフロー

詳細なワークフローは次のようになります。

  1. ユーザーが車両をガレージに停めます。

  2. パートナーは、車両が操作される可能性が低い夜間に車両のアップデートを試みます。

  3. パートナー クラウド サーバーがアップデート システムのリモートタスクを車両に送信します。具体的にはテレマティック コントロール ユニット(TCU)です。

  4. 車両の TCU が Android の電子制御ユニット(ECU)を復帰させ、OEM サービスがガレージモードをトリガーします。

  5. Android がガレージモードを実行し、Google Play を通じてアップデートをダウンロード、インストールします。

  6. アップデートが適用されると Android はタスクを完了としてマークし、接続を終了するか、指定のタイムアウトに達します。

詳細なワークフロー

リモート アクセスには重要なステップが 2 つあります。1 つはクライアントの登録です。特定の車両上で動作する特定のリモートタスク クライアントに特定のユーザーをリンクします。もう 1 つはタスクの配信です。特定の車両上で動作する特定のリモートタスク クライアントに特定のユーザーのリモートタスクを配信します。

クライアントを登録する

リモート アクセス機能を使用するには、ユーザーは少なくとも一度リモートタスク クライアント アプリを開き、クライアント登録プロセスを完了する必要があります(太字テキストは AAOS が実装するタスクを示します)。

  1. 起動時に、カーサービスはリモート アクセス HAL から車両情報を取得します。

  2. 起動時に、カーサービスはインテント フィルタと権限に基づいてすべてのリモートタスク クライアントを起動します。

  3. リモートタスク クライアントは、起動すると自身をカーサービスに登録します。

  4. カーサービスは、リモートタスク クライアントに車両 ID とクライアント ID を含む登録情報を通知します。クライアント ID は一意であり、カーサービスによってクライアントに割り当てられます。同じ車両のすべてのリモートタスク クライアント間で一意であることが保証されています。

  5. ユーザーはリモートタスク クライアントを介してリモートタスク サーバーにログインし、この車両のリモート アクセス機能を有効にします。このステップでは通常、リモートタスク サーバーを介した認証が行われます。

  6. リモートタスク クライアントは、ユーザー情報と車両 ID およびクライアント ID をリモートタスク サーバーにアップロードし、ユーザーと特定のクライアントおよび車両とをリンクするようサーバーにリクエストします。

    オプションとして、このステップではユーザーによる追加の 2 要素認証が含まれる場合があります。

    リモートタスク サーバーは、リクエストで提供された車両 ID が送信者の車両 ID と一致することを認証する必要があります。認証は車両証明書を通じて行えます。

出荷時の設定にリセットされない限り、クライアント登録プロセスは 1 ユーザー 1 車両につき 1 回必要です。クライアント ID はカーサービスのローカルに保存されます。同じクライアントのクライアント ID は変わりません。

画像

図 2. クライアントを登録する。

クライアントの登録を解除する

ユーザーは、車両またはリモートタスク サーバーを通じて、自分のアカウントから車両をリンク解除できます。

  • 車両では、リモートタスク クライアント アプリを開き、リンク解除リクエストを発行することで、以前にリンクされたユーザー アカウントからこの車両をリンク解除できます。

  • リモートタスク サーバーでは、自分のアカウントにログインし、以前にリンクされた車両をアカウントからリンク解除できます。

ユーザーがアカウントから車両をリンク解除した場合、リモートタスク サーバーは、特定のユーザーの保存されたマッピングを削除する必要があります。

タスクを配信する

クラウド内:

  1. ユーザーは、リモートタスク サーバーを使用して特定の車両にリモートタスクを送信します。

  2. リモートタスク サーバーはユーザー ID を車両 ID およびクライアント ID にマッピングします。タスクデータ、車両 ID、クライアント ID がウェイクアップ サーバーに送信されます。

  3. ウェイクアップ サーバーは(TCU はすでに登録されていると想定して)車両 ID に対応する特定の TCU を見つけ、タスクデータとクライアント ID を TCU に送信します。

車両上(太字テキストは AAOS が実行するタスクを示します):

  1. TCU はリモート サーバーからリモートタスクを受け取ります。

  2. AAOS を実行しているアプリ プロセッサ(AP)がオフの場合、TCU は車両プロセッサ(VP)を使用して AP を復帰させます。

  3. カーサービスは TCU からタスクを受け取ります。

  4. カーサービスは対応するリモートタスク クライアントにタスクを配信します。

  5. リモートタスク クライアントはタスクを受け取り実行します。

    (任意)リモートタスク クライアントはタスクの詳細をタスクサーバーに問い合わせ、タスクを実行します。

  6. (任意)リモートタスク クライアント サービスはタスクの結果をタスクサーバーに報告します。

  7. タスクが完了すると、リモートタスク クライアントはカーサービスに通知します。

  8. 必要に応じてカーサービスは車両の電源状態を復元します。

画像

図 3. タスクを配信する。

リモートタスク クライアントを作成する

CarRemoteAccessManager はリモート アクセス機能のための API を提供します。詳しくは、CarRemoteAccessManager をご覧ください。リモートタスク クライアントは、リモートタスクを実行し CarRemoteAccessManager を使用する Android サービスです。これには PERMISSION_USE_REMOTE_ACCESSPERMISSION_CONTROL_REMOTE_ACCESS が必要であり、以下のような RemoteTaskClientService のインテント・フィルタを宣言する必要があります。

<service android:name=".remoteaccess.RemoteTaskClientService"
         android:directBootAware="true"
         android:exported="true">
    <intent-filter>
       <action android:name="android.car.remoteaccess.RemoteTaskClientService" />
    </intent-filter>
</service>

リモートタスク クライアントは、作成時に自身をカーサービスに登録する必要があります。

public final class RemoteTaskClientService extends Service {
    @Override
    public void onCreate() {
        // mCar = Car.createCar()...
        mRemoteAccessManager = (CarRemoteAccessManager)
            mcar.getCarManager(Car.CAR_REMOTE_ACCESS_SERVICE);
        if (mRemoteAccessManager == null) {
            // Remote access feature is not supported.
            return;
        }
        mRemoteAccessManager.setRemoteTaskClient(executor, mRemoteTaskClient);
    }
}

onBind 関数をオーバーライドして null を返す必要があります。

@Override
public IBinder onBind(Intent intent) {
    return null;
}

カーサービスは自身のライフサイクルを管理します。カーサービスは、起動時とリモートタスクの到着時にこのサービスにバインドします。タスクが完了すると、カーサービスはこのサービスへのバインドを解除します。詳しくは、サービスのライフサイクルを管理するをご覧ください。

リモートタスク クライアントはシステム ユーザーとして動作するため、ユーザー固有のデータにはアクセスできません。

次の例は、登録されたコールバックを処理する方法を示しています。

private final class RemoteTaskClient
    implements CarRemoteAccessManager.RemoteTaskClientCallback {
    @Override
    public void onRegistrationUpdated(
        RemoteTaskClientRegistrationInfo info) {
        // Register to remote task server using info.
    }
    @Override
    public void onRemoteTaskRequested(String taskId,
        byte[] data, int remainingTimeSec) {
        // Parses the data and execute the task.
        // Report task result to remote task server.
        mRemoteAccessManager.reportRemoteTaskDone(taskId);
    }
    @Override
    public void onShutdownStarting(CompleteableRemoteTaskFuture future) {
        // Stop the executing task.
        // Clear the pending task queue.
        future.complete();
    }
}

ベンダー実装

リモート アクセス機能は任意であり、デフォルトでは無効です。有効にするには、次のように RRO を追加します。

// res/xml/overlays.xml
<?xml version="1.0" encoding="utf-8"?>
<overlay>
    <item target="array/config_allowed_optional_car_features" value="@array/config_allowed_optional_car_features" />
</overlay>

// res/values/config.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string-array translatable="false" name="config_allowed_optional_car_features">
        <item>car_remote_access_service</item>
    </string-array>
</resources>

// Android.bp
runtime_resource_overlay {
    name: "RemoteAccessOverlay",
    resource_dirs: ["res"],
    manifest: "AndroidManifest.xml",
    sdk_version: "current",
    product_specific: true
}

または、userdebug ビルドと eng ビルドで次の adb コマンドを使用します。

adb shell cmd car_service enable-feature car_remote_access_service

Android での要件

リモート アクセス HAL

リモート アクセス Hardware Abstraction Layer(HAL)は、AAOS と他の ECU(たとえば TCU)との通信のためにベンダーが実装する抽象化レイヤです。リモート アクセス機能をサポートする場合は必須です。リモート アクセス機能を実装しない場合は、実装する必要はありません。

インターフェースは IRemoteAccess.aidl で定義され、次のメソッドを含みます。

クラス 説明
String getVehicleId() ウェイクアップ サーバーが認識できる一意の車両 ID を取得します。
String getWakeupServiceName() リモート ウェイクアップ サーバーの名前を取得します。
String getProcessorId() クライアントを復帰させることで認識できる一意のプロセッサ ID を取得します。
void setRemoteTaskCallback(IRemoteTaskCallback callback)

リモートタスクがリクエストされたときに呼び出されるコールバックを設定します。

void clearRemoteTaskCallback() 以前設定したリモートタスクのコールバックを消去します。
void notifyApStateChange(in ApState state)

アプリ プロセッサがリモートタスクを受け取る準備ができているかどうかを検出します。

コールバック インターフェースは IRemoteTaskCallback.aid で定義されます。

クラス 説明
oneway void onRemoteTaskRequested(String clientId, in byte[] data)

リモートタスクがリクエストされたときに呼び出されるコールバック。

外部 TCU を使用したリファレンス実装をご覧ください。実装では、長時間の読み取りストリームを使用してリモートタスクを受け取り、次の debug コマンドをサポートする必要があります。

dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default

車両 HAL

リモート アクセス機能をサポートする場合、VHAL は次のプロパティをサポートする必要があります。

クラス 説明
SHUTDOWN_REQUEST ヘッドユニットにシャットダウンをリクエストします。
VEHICLE_IN_USE
  • 車両が使用中かどうかを検出します。
  • ユーザーが車両をロック解除した後、あるいはユーザーが車両に近づいたとき。true である必要があります。
  • ユーザーが車両をオフにした後の特定の期間、あるいはユーザーが車両をロックしたとき。false である必要があります。
  • true の場合、AAOS はリモートタスク完了時に車両をシャットダウンしようとしません。

詳しくは、サポートされているシステム プロパティをご覧ください。

マナーモード

リモート アクセス機能では、マナーモードをサポートする必要があります。これにより、ユーザーがいないときに車両をマナーモードで起動しリモートタスクを実行できます。マナーモードでは、AAOS デバイスはディスプレイとオーディオをオフにした状態で起動します。

マナーモードは 2 つの Linux カーネル sysfs ファイルを通じて制御されます。

クラス 説明
/sys/kernel/silent_boot/pm_silentmode_kernel_state

現在のマナーモードを表します。

/sys/kernel/silent_boot/pm_silentmode_hw_state

新しいマナーモードを設定するハードウェア シグナルを表します。

車両プロセッサは Android SoC に HW シグナルを送信してマナーモードをオンまたはオフにします。シグナル(0 または 1)は /sys/kernel/silent_boot/pm_silentmode_hw_state に書き込まれます。その後、AAOS フレームワークは、現在のマナーモードを表す /sys/kernel/silent_boot/pm_silentmode_kernel_state を適宜更新します。AAOS モジュールは /sys/kernel/silent_boot/pm_silentmode_kernel_state を確認し、システムがマナーモードかどうかを把握します。

リモートタスクが受け取られ AAOS が起動すると、車両プロセッサはマナーモードを設定し AAOS を開始します。これによりシステムはディスプレイとオーディオがオフの状態で起動します。

車両の非 Android コンポーネント

車両プロセッサ

車両プロセッサは、Android を実行するアプリ プロセッサの電源を制御できる車両のプロセッサです。アーキテクチャ例では、TCU が車両プロセッサにシグナルを送信することでアプリ プロセッサを復帰させます。

車両の非 Android コンポーネント

車両 TCU は常にリモート メッセージを受信できます。

ウェイクアップ クライアントは TCU で動作し、リモート ウェイクアップ サーバーとの長時間接続を保証します。

AP で動作する AAOS は、リモート アクセス HAL を通じ、TCU で動作するウェイクアップ クライアントと通信できます。

画像

図 4. TCU(ウェイクアップ クライアント)。

クラウド コンポーネント

ウェイクアップ サーバー

ウェイクアップ サーバーは、次の目的で TCU のウェイクアップ クライアントと通信します。

  • 車両の TCU との長時間接続を維持するため。
  • 車両 ID に基づく特定の TCU を見つけるため。
  • 車両のステータスを報告するため。たとえば、オンラインかオフラインか、あるいは直近のオンライン日時をリモートタスク サーバーに報告します。

実際の実装では、ウェイクアップ サーバーはリモートタスク サーバーに統合できます。

リモートタスク サーバー

リモートタスク サーバーは次のリモートタスクを管理します。

  • ユーザーはサーバーとやり取りをして、新しいリモートタスクを開始したり、リモートタスクをモニタリングしたりします。

  • リモート ウェイクアップ サーバーを使用して車両のアプリ プロセッサを復帰させます。

  • 車両で動作しているリモートタスク クライアントと通信します。

  • クライアント登録情報を保存します。特定の車両上の特定のリモートタスク クライアントに特定のユーザーを関連付けます。

通常、リモートタスク サーバーからウェイクアップ サーバー、車両の TCU、そして最終的にリモートタスク クライアントに送信される「タスクデータ」は、タスク ID です。リモートタスク クライアントは、このタスク ID を使ってリモートタスク サーバーから詳細情報を取得します。

プライバシーとセキュリティ要件

タスク 条件 要件
TCU(ウェイクアップ クライアント) しなければならない
  • ウェイクアップ サーバーを認証します。
  • コードを信頼します。
ウェイクアップ サーバー しなければならない
  • 許可リストに登録されているリモートタスク サーバーのみ接続を許可します。
  • ウェイクアップ クライアントを認証します。
  • ウェイクアップ メッセージを対象車両のみに送信します。
リモートタスク クライアント しなければならない
  • 登録時にユーザーを認証します。
  • リモートタスク サーバーを認証します。
  • Android サービスのすべてのセキュリティ要件を満たします(制限付きの権限など)。
リモートタスク サーバー しなければならない
  • ウェイクアップ サーバーを認証する必要があります。
  • 車両証明書を提供します。つまり、リクエストで提供された車両 ID が送信者の車両 ID と一致することを認証します。車両証明ができない場合は、ユーザーが現在その車両を所有していることを他の手段で証明する必要があります。
  • ユーザーを認証します。
  • ユーザー情報を処理するサーバーのすべてのセキュリティ要件を満たします。

出荷時設定へのリセットと所有権の移転

ユーザーが出荷時設定へのリセットを実行した場合、カーサービスに保存されたクライアント ID はワイプされます。しかし、サーバー(リモートタスク サーバーとリモート ウェイクアップ サーバー)には知らされません。サーバーは、期限が切れたクライアント ID から車両へのマッピングを保持します。そのため、ユーザーが車両の新しいリモートタスクを開始した場合、期限が切れたクライアント ID が使用されます。車両は起動しますが、リモートタスク クライアントのクライアント ID が一致しないため、リモートタスクは実行できません。

出荷時設定へのリセットの実装の一例を次に示します。

ユーザーが出荷時設定へのリセットを発行すると、ベンダーはユーザーに、リモートタスク サーバーにログインし、ユーザーが以前に車両をリンクしていた場合はアカウントから車両のリンクを解除するように促します。出荷時設定へのリセットの間、デバイスによるネットワークへのアクセスは保証されません。そのため、出荷時設定へのリセット時にデバイスからリンク解除リクエストを発行することはできない可能性があります。

車両の所有権が移転された場合、前所有者がその車両に対してリモートタスクを発行できないようにするための操作を必ず行う必要があります。たとえば、新しい所有者は次の操作を求められる場合があります。

  • 出荷時の設定にリセットします。これによりクライアント ID が再生成されます。このステップが完了すると、前所有者はまだ車両を復帰できますが、リモートタスクは実行できなくなります。

  • リモートタスク クライアント アプリを開き、クライアントの登録を解除するのプロセスに沿って前所有者のアカウントから車両をリンク解除します。新しい所有者は、クライアント登録プロセスに沿って車両を自分のアカウントにリンクし、以前にリンクされたアカウントを置き換えられます。

  • 新しい所有者は、クライアントを登録するのプロセスに沿って車両を自分のアカウントにリンクし、以前にリンクされたアカウントを置き換えられます。

リモートタスク クライアントをテストする

リファレンス リモート アクセス HAL default ディレクトリをテスト リモートタスク クライアントに提供します。次の debug コマンドを使用してダミーのリモートタスクを HAL に挿入できます。正しいクライアント ID を提供すると、タスクはリモートタスク クライアントに転送されます。クライアント ID は、リモートタスク クライアント実装の登録情報をログに記録することで取得できます。

adb root && adb shell dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --inject-task [clientID] [taskData]