Otomotiv görüntülü reklam proxy hizmeti

Bu basit çerçeve hizmeti, tedarikçinin işlemleri, HAL uygulamalarında SurfaceFlinger/EGL'yi kullanırken, bağlantı oluşturmaksızın libgui'yi seçin. AOSP, bu hizmetin varsayılan uygulamasını sağlar. Bu uygulama, çalışır. Ancak, tedarikçinin bu hizmeti sağlamak için API'ler de uygulaması gerekir. tercih edebilirsiniz.

package android.frameworks.automotive.display@1.0;

import android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer;

interface IAutomotiveDisplayProxyService {
    /**
     * Gets an IGraphicBufferProducer instance from the service.
     *
     * @param  id   Target's stable display identifier
     *
     * @return igbp Returns an IGraphicBufferProducer object, that can be
     *              converted to an ANativeWindow object.
     */
    getIGraphicBufferProducer(uint64_t id) generates (IGraphicBufferProducer igbp);

    /**
     * Sets the ANativeWindow, which is associated with the
     * IGraphicBufferProducer, to be visible and to take over the display.
     *
     * @param  id      Target display ID
     *
     * @return success Returns true on success.
     */
    showWindow(uint64_t id) generates (bool success);

    /**
     * Sets the ANativeWindow, which is associated with the
     * IGraphicBufferProducer, to be invisible and to release the control
     * over display.
     *
     * @param  id      Target display ID
     *
     * @return success Returns true on success.
     */
    hideWindow(uint64_t id) generates (bool success);

    /**
     * Returns the stable identifiers of all available displays.
     *
     * @return ids A list of stable display identifiers.
     */
    getDisplayIdList() generates (vec<uint64_t> ids);

    /**
     * Returns the descriptor of the target display.
     *
     * @param  id    Stable ID of a target display.
     * @return cfg   DisplayConfig of the active display.
     * @return state Current state of the active display.
     */
    getDisplayInfo(uint64_t id) generates (HwDisplayConfig cfg, HwDisplayState state);
}

Bu hizmeti kullanmak için:

  1. IAutomotiveDisplayProxyService üyesi olun.
    android::sp<IAutomotiveDisplayProxyService> windowProxyService =
        IAutomotiveDisplayProxyService::getService("default");
    if (windowProxyService == nullptr) {
        LOG(ERROR) << "Cannot use AutomotiveDisplayProxyService. Exiting.";
        return 1;
    }
    
  2. Çözünürlüğü belirlemek için hizmetten etkin görüntüleme bilgilerini alın.
    // We use the first display in the list as the primary.
    pWindowProxy->getDisplayInfo(displayId, [this](auto dpyConfig, auto dpyState) {
        DisplayConfig *pConfig = (DisplayConfig*)dpyConfig.data();
        mWidth = pConfig->resolution.getWidth();
        mHeight = pConfig->resolution.getHeight();
    
        ui::DisplayState* pState = (ui::DisplayState*)dpyState.data();
        if (pState->orientation != ui::ROTATION_0 &&
            pState->orientation != ui::ROTATION_180) {
            // rotate
            std::swap(mWidth, mHeight);
        }
    
        LOG(DEBUG) << "Display resolution is " << mWidth << " x " << mHeight;
    });
    
  3. Bir donanım IGraphicBufferProducer (veya IAutomotiveDisplayProxyService adlı yayıncıdan HIDL GraphicBufferProducer (HGBP):
    mGfxBufferProducer = pWindowProxy->getIGraphicBufferProducer(displayId);
    if (mGfxBufferProducer == nullptr) {
        LOG(ERROR) << "Failed to get IGraphicBufferProducer from "
                   << "IAutomotiveDisplayProxyService.";
        return false;
    }
    
  4. API'yi kullanarak, alınan HGBP'den SurfaceHolder alın libbufferqueueconverter:
    mSurfaceHolder = getSurfaceFromHGBP(mGfxBufferProducer);
    if (mSurfaceHolder == nullptr) {
        LOG(ERROR) << "Failed to get a Surface from HGBP.";
        return false;
    }
    
  5. Şu komutu kullanarak SurfaceHolder öğesini yerel pencereye dönüştürün: API libbufferqueueconverter:
    mWindow = getNativeWindow(mSurfaceHolder.get());
    if (mWindow == nullptr) {
        LOG(ERROR) << "Failed to get a native window from Surface.";
        return false;
    }
    
  6. Yerel pencereyle EGL pencere yüzeyi oluşturma ve ardından şu işlemi yapma:
    // Set up our OpenGL ES context associated with the default display
    mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (mDisplay == EGL_NO_DISPLAY) {
        LOG(ERROR) << "Failed to get egl display";
        return false;
    }
    ...
    
    // Create the EGL render target surface
    mSurface = eglCreateWindowSurface(mDisplay, egl_config, mWindow, nullptr);
    if (mSurface == EGL_NO_SURFACE) {
        LOG(ERROR) << "eglCreateWindowSurface failed.";
        return false;
    }
    ...
    
    .
  7. IAutomotiveDisplayProxyService::showWindow() numaralı telefonu arayın: oluşturulan görünümü ekranda gösterin. Bu hizmet en yüksek önceliğe sahiptir ve Bu nedenle, ekranın kontrolünü her zaman mevcut sahibinden alır:
    mAutomotiveDisplayProxyService->showWindow();
    
    .

Bkz. service.cpp ve GlWrapper.cpp $ANDROID_BUILD_TOP/packages/services/Car/evs/sampleDriver/ bölgesinde şunun için: daha fazla bilgi edineceksiniz.

EVS HAL uygulaması, şurada gösterilen ek kitaplıkların kullanılmasını gerektirir: kalın yazı tipine ekleyin.

cc_binary {
    name: "android.hardware.automotive.evs@1.1-sample",

    vendor: true,

    srcs: [
        ...
    ],

    shared_libs: [
        ...
        "libbufferqueueconverter",
        "android.hidl.token@1.0-utils",
        "android.frameworks.automotive.display@1.0",
        "android.hardware.graphics.bufferqueue@1.0",
        "android.hardware.graphics.bufferqueue@2.0",
    ],

Çoklu ekran desteği

Cihaz numaralandırmasını görüntüleme ve ekran bilgilerini alma

Kamera cihazı numaralandırması gibi, EVS çerçevesi de en iyi uygulamaları paylaşacağız. statik görüntülü reklam tanımlayıcısı, tür uzunluğundaki bir tanımlayıcıyı kodlar. bağlantı noktası bilgilerini alt baytta, Extended Display IDentification Data ise büyük bitlerde yer alır. IAutomotiveDisplayProxyService::getDisplayIdList() bir liste döndürür EVS hizmeti için kullanılabilen fiziksel yerel ekranların ekran kimliklerinin ekran kimliği, ve IEvsEnumerator::getDisplayIdList(), bir görüntülü reklam ağı listesi döndürür. bağlantı noktalarından birini seçin. Listedeki ilk kimlik her zaman birincil ekran.

interface IEvsEnumerator extends @1.0::IEvsEnumerator {
    ...
    /**
     * Returns a list of all EVS displays available to the system
     *
     * @return displayIds Identifiers of available displays.
     */
    getDisplayIdList() generates (vec<uint8_t> displayIds);
};

Hedef görüntülü reklam cihazını açın

EVS uygulaması, bir hedef ekranla IEvsEnumerator::openDisplay_1_1() çağrısında bulunur bağlantı noktası numarası:

android::sp<IEvsDisplay> pDisplay = pEvs->openDisplay_1_1(displayId);
if (pDisplay.get() == nullptr) {
    LOG(ERROR) << "EVS Display unavailable. Exiting.";
    return 1;
}

Not: Aynı anda yalnızca bir ekran kullanılabilir. Bu durum, mevcut EVS istemcisinin başka bir EVS müşterisi olduğunda ekranını kaybedeceği anlamına gelir. (aynı olmasalar bile) ekranı açma istekleri alır.