Проверка обратной совместимости HIDL Framework

HIDL HAL гарантируют, что базовая система Android (она же system.img или фреймворк) обратно совместима. В то время как тесты Vendor Test Suite (VTS) гарантируют, что HAL работают должным образом (например, тесты HAL 1.1 выполняются во всех реализациях 1.2), тестирование инфраструктуры необходимо, чтобы гарантировать, что при предоставлении поддерживаемого HAL (1.0, 1.1 или 1.2) framework правильно работает с этим HAL.

Дополнительные сведения о языке определения интерфейса HAL (HIDL) см. в разделах HIDL , Управление версиями HIDL и Устаревание HIDL HAL .

Об обновлениях HAL

Существует два типа обновлений HAL: основные и второстепенные . Большинство систем включают только одну реализацию HAL, но поддерживаются несколько реализаций. Например:

android.hardware.teleport@1.0 # initial interface
android.hardware.teleport@1.1 # minor version upgrade
android.hardware.teleport@1.2 # another minor version upgrade
...
android.hardware.teleport@2.0 # major version upgrade
...

Системный раздел обычно включает в себя демон фреймворка (например, teleportd ), который управляет связью с определенной группой реализаций HAL. В качестве альтернативы системы могут вместо этого включать системную библиотеку (например, android.hardware.configstore-utils ), которая реализует удобное поведение клиента. В приведенном выше примере teleportd должен работать независимо от того, какая версия HAL установлена ​​на устройстве.

Версии, поддерживаемые Google

Если существуют обновления основных версий (1.0, 2.0, 3.0 и т. д.), по крайней мере на одном поддерживаемом Google устройстве должна поддерживаться реализация каждой основной версии до тех пор, пока эта версия не станет устаревшей. Если ни одно поддерживаемое Google устройство не поставляется с определенной основной версией, Google продолжает поддерживать старую реализацию этой основной версии.

Такое сопровождение добавляет незначительные дополнительные накладные расходы, поскольку старую реализацию (например, 1.2) можно сохранить и не использовать по умолчанию при создании новой реализации (например, 2.0).

Тестирование минорных обновлений версии

Для тестирования обратной совместимости младших версий в фреймворке требуется способ автоматического создания реализаций младших версий. Учитывая ограничения, связанные с поддерживаемыми Google версиями, hidl-gen будет (и может только) генерировать адаптеры, которые принимают реализацию 1.(x+n) и предоставляют реализацию 1.x; он не может создать реализацию 1.0 из реализации 2.0 (по определению основной версии).

Например, чтобы запустить тесты версии 1.1 в реализации версии 1.2, вы должны иметь возможность имитировать реализацию версии 1.1. Интерфейсы 1.2 могут автоматически использоваться как реализация 1.1 с некоторыми небольшими отличиями в поведении (например, фреймворк вручную проверяет версию чего-либо или вызывает для него castFrom ).

Основная идея такова:

  1. Установите интерфейс x.(y+n) на мобильное устройство Android.
  2. Установите и активируйте адаптер xy-target.
  3. Протестируйте устройство, чтобы убедиться, что оно работает должным образом при запуске более старой дополнительной версии.

Эти адаптеры полностью скрывают тот факт, что реализация на самом деле поддерживается интерфейсом 1.2 и предоставляет только интерфейс 1.1 (адаптер берет интерфейс 1.2 и делает его похожим на интерфейс 1.1).

Пример рабочего процесса

В этом примере на устройстве Android работает android.hardware.foo@1.1::IFoo/default . Чтобы клиент правильно работал с android.hardware.foo@1.0::IFoo/default :

  1. В терминале выполните следующее:
    $ PACKAGE=android.hidl.allocator@1.0-adapter
    $ INTERFACE=IAllocator
    $ INSTANCE=ashmem
    $ THREAD_COUNT=1 # can see current thread use on `lshal -i -e`
    $ m -j $PACKAGE
    $ /data/nativetest64/$PACKAGE/$PACKAGE $INTERFACE $INSTANCE $THREAD_COUNT
    Trying to adapt down android.hidl.allocator@1.0-adapter/default
    Press any key to disassociate adapter.
  2. Перезапустите клиент с помощью adb shell stop (или start ) или просто завершите процесс.
  3. После завершения теста отключите адаптер.
  4. Восстановите состояние системы, перезапустив устройство ИЛИ перезапустив клиент.

Дополнительные цели

hidl-gen автоматически добавляет дополнительные цели сборки для адаптеров для каждого интерфейса, указанного с помощью hidl_interface в системе сборки. Для пакета abc@xy существует дополнительная цель C++ abc@xy-adapter .

Адаптер для abc@xy принимает на вход некоторую реализацию abc@x.(y+n)::ISomething/instance-name и должен зарегистрировать abc@xy::ISomething/instance-name , который также должен отменить регистрацию y+n . y+n реализация.

Учитывая следующий пример интерфейса:

// IFoo.hal
package a.b.c@1.0;
interface IFoo {
    doFoo(int32_t a) generates (int64_t b);
    doSubInterface() generates (IFoo a);
};

Код, предоставленный abc@1.0-adapter , аналогичен приведенному ниже образцу:

// autogenerated code
// in namespace a::b::c::V1_0::IFoo
struct MockFoo {
    // takes some subclass of V1_0. May be V1_1, V1_2, etc...
    MockFoo(V1_0::IFoo impl) mImpl(impl) {}

    Return<int64_t> doFoo(int32_t a) {
        return this->mImpl->doFoo(a);
    }

    Return<V1_0::ICallback> doSubInterface() {
        // getMockForBinder returns MockCallback instance
        // that corresponds to a particular binder object
        // It can't return a new object every time or
        // clients using interfacesSame will have
        // divergent behavior when using the mock.
        auto _hidl_out = this->mImpl->doSubInterface();
        return getMockForBinder(_hidl_out);
    }
};

Значения данных пересылаются точно в автоматически сгенерированный фиктивный класс и из него, за исключением субинтерфейсов, которые возвращаются. Эти интерфейсы должны быть заключены в соответствующий самый последний объект обратного вызова.