Динамически доступные 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() после отбрасывания ссылки, чтобы гарантировать, что драйвер связывателя уведомлен о связанном счетчике ссылок. изменения.