Динамически доступные HAL

Android 9 поддерживает динамическое отключение аппаратных подсистем Android, когда они не используются или не нужны. Например, когда пользователь не использует Wi-Fi, подсистемы Wi-Fi не должны использовать память, питание или другие системные ресурсы. В более ранних версиях Android HAL/драйверы оставались открытыми на устройствах Android в течение всего времени загрузки телефона Android.

Реализация динамического завершения работы включает в себя подключение потоков данных и выполнение динамических процессов, как подробно описано в следующих разделах.

Изменения в определениях HAL

Для динамического завершения работы требуется информация о том, какие процессы обслуживают какие интерфейсы HAL (эта информация также может быть полезна позже в других контекстах), а также не запускать процессы при загрузке и не перезапускать их (до тех пор, пока не будет запрошено снова) при их выходе.

# some init.rc script associated with the HAL
service vendor.some-service-name /vendor/bin/hw/some-binary-service
    # init language extension, provides information of what service is served
    # if multiple interfaces are served, they can be specified one on each line
    interface android.hardware.light@2.0::ILight default
    # restarted if hwservicemanager dies
    # would also cause the hal to start early during boot if disabled wasn't set
    class hal
    # will not be restarted if it exits until it is requested to be restarted
    oneshot
    # will only be started when requested
    disabled
    # ... other properties

Изменения в init и hwservicemanager

Для динамического завершения работы также требуется, чтобы hwservicemanager сообщил init о запуске запрошенных служб. В Android 9 init включает три дополнительных управляющих сообщения (например, ctl.start ): ctl.interface_start , ctl.interface_stop и ctl.interface_restart . Эти сообщения могут использоваться для подачи сигнала init о включении и выключении определенных аппаратных интерфейсов. Когда служба запрошена, но не зарегистрирована, hwservicemanager запрашивает запуск службы. Однако динамические HAL не требуют использования каких-либо из них.

Определить выход HAL

В Android 9 выход HAL необходимо определять вручную. Для Android 10 и выше его также можно определить с помощью автоматических жизненных циклов .

Для динамического завершения работы требуется несколько политик для принятия решения о том, когда запускать HAL, а когда выключать HAL. Если HAL решит выйти по какой-либо причине, он будет автоматически перезапущен, когда он снова понадобится, используя информацию, предоставленную в определении HAL, и инфраструктуру, предоставленную изменениями в init и hwservicemanager . Это может включать в себя несколько различных стратегий, в том числе:

  • HAL может выбрать вызов выхода для себя, если кто-то вызывает для него близкий или аналогичный API. Это поведение должно быть указано в соответствующем интерфейсе HAL.
  • HAL могут завершить работу после завершения своей задачи (описано в файле HAL).

Автоматические жизненные циклы

В Android 10 добавлена ​​дополнительная поддержка ядра и hwservicemanager , что позволяет HAL автоматически завершать работу, когда у них нет клиентов. Чтобы использовать эту функцию, выполните все шаги, описанные в разделе «Изменения определений HAL», а также:

  • Зарегистрируйте службу на C++ с помощью LazyServiceRegistrar вместо функции-члена registerAsService , например:
    // only one instance of LazyServiceRegistrar per process
    LazyServiceRegistrar registrar;
    registrar.registerAsService(myHidlService /* , "default" */);
  • Убедитесь, что клиент HAL сохраняет ссылку на HAL верхнего уровня (интерфейс, зарегистрированный с помощью hwservicemanager ), только когда он используется. Чтобы избежать задержек, если эта ссылка удаляется в потоке hwbinder, который продолжает выполняться, клиент также должен вызвать IPCThreadState::self()->flushCommands() после удаления ссылки, чтобы гарантировать, что драйвер связывателя уведомлен о связанном счетчике ссылок. изменения.