Add a method to support multi-display usages

- Add getDisplayIdList() and openDisplay_1_1() to IEvsEnumerator.
- Add getDisplayInfo_1_1() to IEvsDisplay.
- Update CameraToDisplayRountTrip test case to use new methods.
- Update default implementation.

Bug: 141886260
Bug: 146567078
Bug: 147553536
Test: VtsHalEvsV1_1TargetTest
Change-Id: I3c17aecc482770074159f7ccaf8e00cadf711e76
Signed-off-by: Changyeon Jo <changyeon@google.com>
This commit is contained in:
Changyeon Jo
2020-01-02 17:55:55 -08:00
parent 9d51774201
commit 043a7a027f
12 changed files with 201 additions and 20 deletions

View File

@@ -10,9 +10,11 @@ hidl_interface {
"types.hal",
"IEvsCamera.hal",
"IEvsCameraStream.hal",
"IEvsDisplay.hal",
"IEvsEnumerator.hal",
],
interfaces: [
"android.frameworks.automotive.display@1.0",
"android.hardware.automotive.evs@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.graphics.common@1.0",

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.automotive.evs@1.1;
import @1.0::IEvsDisplay;
import @1.0::EvsResult;
import android.frameworks.automotive.display@1.0::HwDisplayConfig;
import android.frameworks.automotive.display@1.0::HwDisplayState;
/**
* Represents a single display.
*/
interface IEvsDisplay extends @1.0::IEvsDisplay {
/**
* Returns the description of this display.
*
* @return cfg Current configuration of this display.
* @return state Current state of this display.
*/
getDisplayInfo_1_1() generates (HwDisplayConfig cfg, HwDisplayState state);
};

View File

@@ -17,6 +17,7 @@
package android.hardware.automotive.evs@1.1;
import IEvsCamera;
import IEvsDisplay;
import @1.0::IEvsEnumerator;
import @1.0::EvsResult;
import android.hardware.camera.device@3.2::Stream;
@@ -54,4 +55,25 @@ interface IEvsEnumerator extends @1.0::IEvsEnumerator {
* @return result False for EVS manager implementations and true for all others.
*/
isHardware() generates (bool result);
/**
* Returns a list of all EVS displays available to the system
*
* @return displayIds Identifiers of available displays.
*/
getDisplayIdList() generates (vec<uint8_t> displayIds);
/**
* Get exclusive access to IEvsDisplay for the system
*
* There can be more than one EVS display objects for the system and this function
* requests access to the display identified by a given ID. If the target EVS display
* is not available or is already in use the old instance shall be closed and give
* the new caller exclusive access.
* When done using the display, the caller may release it by calling closeDisplay().
*
* @param id Target display identifier.
* @return display EvsDisplay object to be used.
*/
openDisplay_1_1(uint8_t id) generates (IEvsDisplay display);
};

View File

@@ -27,6 +27,10 @@ cc_binary {
"libutils",
"libcamera_metadata",
"libtinyxml2",
"android.hidl.token@1.0-utils",
"android.frameworks.automotive.display@1.0",
"android.hardware.graphics.bufferqueue@1.0",
"android.hardware.graphics.bufferqueue@2.0",
],
cflags: [

View File

@@ -280,7 +280,7 @@ Return<EvsResult> EvsCamera::setMaster() {
return EvsResult::OK;
}
Return<EvsResult> EvsCamera::forceMaster(const sp<IEvsDisplay>& ) {
Return<EvsResult> EvsCamera::forceMaster(const sp<IEvsDisplay_1_0>& ) {
// Default implementation does not expect multiple subscribers and therefore
// return a success code always.
return EvsResult::OK;

View File

@@ -20,7 +20,7 @@
#include <android/hardware/automotive/evs/1.1/types.h>
#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
#include <android/hardware/automotive/evs/1.1/IEvsCameraStream.h>
#include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
#include <ui/GraphicBuffer.h>
#include <thread>
@@ -33,7 +33,8 @@ using IEvsCameraStream_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCam
using IEvsCameraStream_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCameraStream;
using ::android::hardware::automotive::evs::V1_0::EvsResult;
using ::android::hardware::automotive::evs::V1_0::CameraDesc;
using ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
using IEvsDisplay_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
using IEvsDisplay_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsDisplay;
namespace android {
@@ -68,7 +69,7 @@ public:
Return<EvsResult> resumeVideoStream() override;
Return<EvsResult> doneWithFrame_1_1(const hidl_vec<BufferDesc_1_1>& buffer) override;
Return<EvsResult> setMaster() override;
Return<EvsResult> forceMaster(const sp<IEvsDisplay>& display) override;
Return<EvsResult> forceMaster(const sp<IEvsDisplay_1_0>& display) override;
Return<EvsResult> unsetMaster() override;
Return<void> getParameterList(getParameterList_cb _hidl_cb) override;
Return<void> getIntParameterRange(CameraParam id,

View File

@@ -21,6 +21,8 @@
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
using ::android::frameworks::automotive::display::V1_0::HwDisplayConfig;
using ::android::frameworks::automotive::display::V1_0::HwDisplayState;
namespace android {
namespace hardware {
@@ -31,6 +33,13 @@ namespace implementation {
EvsDisplay::EvsDisplay() {
EvsDisplay(nullptr, 0);
}
EvsDisplay::EvsDisplay(sp<IAutomotiveDisplayProxyService> pDisplayProxy, uint64_t displayId)
: mDisplayProxy(pDisplayProxy),
mDisplayId(displayId) {
ALOGD("EvsDisplay instantiated");
// Set up our self description
@@ -327,6 +336,18 @@ Return<EvsResult> EvsDisplay::returnTargetBufferForDisplay(const BufferDesc_1_0&
}
Return<void> EvsDisplay::getDisplayInfo_1_1(getDisplayInfo_1_1_cb _info_cb) {
if (mDisplayProxy != nullptr) {
return mDisplayProxy->getDisplayInfo(mDisplayId, _info_cb);
} else {
HwDisplayConfig nullConfig;
HwDisplayState nullState;
_info_cb(nullConfig, nullState);
return Void();
}
}
} // namespace implementation
} // namespace V1_1
} // namespace evs

View File

@@ -17,14 +17,16 @@
#ifndef ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EVSDISPLAY_H
#define ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EVSDISPLAY_H
#include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
#include <android/frameworks/automotive/display/1.0/IAutomotiveDisplayProxyService.h>
#include <ui/GraphicBuffer.h>
using ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
using ::android::hardware::automotive::evs::V1_1::IEvsDisplay;
using ::android::hardware::automotive::evs::V1_0::DisplayDesc;
using ::android::hardware::automotive::evs::V1_0::DisplayState;
using ::android::hardware::automotive::evs::V1_0::EvsResult;
using BufferDesc_1_0 = ::android::hardware::automotive::evs::V1_0::BufferDesc;
using android::frameworks::automotive::display::V1_0::IAutomotiveDisplayProxyService;
namespace android {
namespace hardware {
@@ -43,9 +45,12 @@ public:
Return<void> getTargetBuffer(getTargetBuffer_cb _hidl_cb) override;
Return<EvsResult> returnTargetBufferForDisplay(const BufferDesc_1_0& buffer) override;
// Methods from ::android::hardware::automotive::evs::V1_1::IEvsDisplay follow.
Return<void> getDisplayInfo_1_1(getDisplayInfo_1_1_cb _info_cb) override;
// Implementation details
EvsDisplay();
EvsDisplay(sp<IAutomotiveDisplayProxyService> pDisplayProxy, uint64_t displayId);
virtual ~EvsDisplay() override;
void forceShutdown(); // This gets called if another caller "steals" ownership of the display
@@ -60,6 +65,9 @@ private:
DisplayState mRequestedState = DisplayState::NOT_VISIBLE;
std::mutex mAccessLock;
sp<IAutomotiveDisplayProxyService> mDisplayProxy;
uint64_t mDisplayId;
};
} // namespace implementation

View File

@@ -34,18 +34,38 @@ namespace implementation {
std::list<EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
wp<EvsDisplay> EvsEnumerator::sActiveDisplay;
unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
sp<IAutomotiveDisplayProxyService> EvsEnumerator::sDisplayProxyService;
std::unordered_map<uint8_t, uint64_t> EvsEnumerator::sDisplayPortList;
EvsEnumerator::EvsEnumerator() {
EvsEnumerator::EvsEnumerator(sp<IAutomotiveDisplayProxyService> windowService) {
ALOGD("EvsEnumerator created");
// Add sample camera data to our list of cameras
// In a real driver, this would be expected to can the available hardware
sConfigManager =
ConfigManager::Create("/vendor/etc/automotive/evs/evs_default_configuration.xml");
// Add available cameras
for (auto v : sConfigManager->getCameraList()) {
sCameraList.emplace_back(v.c_str());
}
if (sDisplayProxyService == nullptr) {
/* sets a car-window service handle */
sDisplayProxyService = windowService;
}
// Add available displays
if (sDisplayProxyService != nullptr) {
// Get a display ID list.
sDisplayProxyService->getDisplayIdList([](const auto& displayIds) {
for (const auto& id : displayIds) {
const auto port = id & 0xF;
sDisplayPortList.insert_or_assign(port, id);
}
});
}
}
@@ -165,7 +185,7 @@ Return<void> EvsEnumerator::closeCamera(const ::android::sp<IEvsCamera_1_0>& pCa
}
Return<sp<IEvsDisplay>> EvsEnumerator::openDisplay() {
Return<sp<IEvsDisplay_1_0>> EvsEnumerator::openDisplay() {
ALOGD("openDisplay");
// If we already have a display active, then we need to shut it down so we can
@@ -185,7 +205,42 @@ Return<sp<IEvsDisplay>> EvsEnumerator::openDisplay() {
}
Return<void> EvsEnumerator::closeDisplay(const ::android::sp<IEvsDisplay>& pDisplay) {
Return<void> EvsEnumerator::getDisplayIdList(getDisplayIdList_cb _list_cb) {
hidl_vec<uint8_t> ids;
ids.resize(sDisplayPortList.size());
unsigned i = 0;
for (const auto& [port, id] : sDisplayPortList) {
ids[i++] = port;
}
_list_cb(ids);
return Void();
}
Return<sp<IEvsDisplay>> EvsEnumerator::openDisplay_1_1(uint8_t port) {
ALOGD("%s", __FUNCTION__);
// If we already have a display active, then we need to shut it down so we can
// give exclusive access to the new caller.
sp<EvsDisplay> pActiveDisplay = sActiveDisplay.promote();
if (pActiveDisplay != nullptr) {
ALOGW("Killing previous display because of new caller");
closeDisplay(pActiveDisplay);
}
// Create a new display interface and return it
pActiveDisplay = new EvsDisplay(sDisplayProxyService, sDisplayPortList[port]);
sActiveDisplay = pActiveDisplay;
ALOGD("Returning new EvsDisplay object %p", pActiveDisplay.get());
return pActiveDisplay;
}
Return<void> EvsEnumerator::closeDisplay(const ::android::sp<IEvsDisplay_1_0>& pDisplay) {
ALOGD("closeDisplay");
// Do we still have a display object we think should be active?

View File

@@ -19,19 +19,22 @@
#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
#include <android/frameworks/automotive/display/1.0/IAutomotiveDisplayProxyService.h>
#include <list>
#include "ConfigManager.h"
using ::android::hardware::automotive::evs::V1_0::EvsResult;
using ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
using ::android::hardware::automotive::evs::V1_0::DisplayState;
using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera;
using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera;
using CameraDesc_1_0 = ::android::hardware::automotive::evs::V1_0::CameraDesc;
using CameraDesc_1_1 = ::android::hardware::automotive::evs::V1_1::CameraDesc;
using IEvsDisplay_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
using IEvsDisplay_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsDisplay;
using android::frameworks::automotive::display::V1_0::IAutomotiveDisplayProxyService;
namespace android {
namespace hardware {
@@ -51,8 +54,8 @@ public:
Return<void> getCameraList(getCameraList_cb _hidl_cb) override;
Return<sp<IEvsCamera_1_0>> openCamera(const hidl_string& cameraId) override;
Return<void> closeCamera(const ::android::sp<IEvsCamera_1_0>& carCamera) override;
Return<sp<IEvsDisplay>> openDisplay() override;
Return<void> closeDisplay(const ::android::sp<IEvsDisplay>& display) override;
Return<sp<IEvsDisplay_1_0>> openDisplay() override;
Return<void> closeDisplay(const ::android::sp<IEvsDisplay_1_0>& display) override;
Return<DisplayState> getDisplayState() override;
// Methods from ::android::hardware::automotive::evs::V1_1::IEvsEnumerator follow.
@@ -60,9 +63,11 @@ public:
Return<sp<IEvsCamera_1_1>> openCamera_1_1(const hidl_string& cameraId,
const Stream& streamCfg) override;
Return<bool> isHardware() override { return true; }
Return<void> getDisplayIdList(getDisplayIdList_cb _list_cb) override;
Return<sp<IEvsDisplay_1_1>> openDisplay_1_1(uint8_t port) override;
// Implementation details
EvsEnumerator();
EvsEnumerator(sp<IAutomotiveDisplayProxyService> windowService = nullptr);
private:
// NOTE: All members values are static so that all clients operate on the same state
@@ -83,6 +88,10 @@ private:
static wp<EvsDisplay> sActiveDisplay;
static unique_ptr<ConfigManager> sConfigManager;
static sp<IAutomotiveDisplayProxyService> sDisplayProxyService;
static std::unordered_map<uint8_t,
uint64_t> sDisplayPortList;
};
} // namespace implementation

View File

@@ -34,7 +34,6 @@ using android::hardware::joinRpcThreadpool;
// Generated HIDL files
using android::hardware::automotive::evs::V1_1::IEvsEnumerator;
using android::hardware::automotive::evs::V1_0::IEvsDisplay;
// The namespace in which all our implementation code lives
using namespace android::hardware::automotive::evs::V1_1::implementation;

View File

@@ -54,9 +54,11 @@ static const float kNanoToSeconds = 0.000000001f;
#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
#include <android/hardware/automotive/evs/1.1/IEvsCameraStream.h>
#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
#include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
#include <system/camera_metadata.h>
#include <ui/DisplayConfig.h>
#include <ui/DisplayState.h>
#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>
@@ -76,6 +78,8 @@ using ::android::hardware::automotive::evs::V1_0::DisplayState;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera;
using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera;
using IEvsDisplay_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
using IEvsDisplay_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsDisplay;
/*
* Plese note that this is different from what is defined in
@@ -567,9 +571,30 @@ TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) {
// output format.
Stream nullCfg = {};
// Request exclusive access to the EVS display
sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
// Request available display IDs
uint8_t targetDisplayId = 0;
pEnumerator->getDisplayIdList([&targetDisplayId](auto ids) {
ASSERT_GT(ids.size(), 0);
targetDisplayId = ids[0];
});
// Request exclusive access to the first EVS display
sp<IEvsDisplay_1_1> pDisplay = pEnumerator->openDisplay_1_1(targetDisplayId);
ASSERT_NE(pDisplay, nullptr);
ALOGI("Display %d is in use.", targetDisplayId);
// Get the display descriptor
pDisplay->getDisplayInfo_1_1([](const auto& config, const auto& state) {
android::DisplayConfig* pConfig = (android::DisplayConfig*)config.data();
const auto width = pConfig->resolution.getWidth();
const auto height = pConfig->resolution.getHeight();
ALOGI(" Resolution: %dx%d", width, height);
ASSERT_GT(width, 0);
ASSERT_GT(height, 0);
android::ui::DisplayState* pState = (android::ui::DisplayState*)state.data();
ASSERT_NE(pState->layerStack, -1);
});
// Test each reported camera
for (auto&& cam: cameraInfo) {
@@ -1556,7 +1581,7 @@ TEST_F(EvsHidlTest, HighPriorityCameraClient) {
Stream nullCfg = {};
// Request exclusive access to the EVS display
sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
sp<IEvsDisplay_1_0> pDisplay = pEnumerator->openDisplay();
ASSERT_NE(pDisplay, nullptr);
// Test each reported camera
@@ -1920,7 +1945,7 @@ TEST_F(EvsHidlTest, CameraUseStreamConfigToDisplay) {
loadCameraList();
// Request exclusive access to the EVS display
sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
sp<IEvsDisplay_1_0> pDisplay = pEnumerator->openDisplay();
ASSERT_NE(pDisplay, nullptr);
// Test each reported camera