Merge "Change the VHAL service name."
diff --git a/bluetooth/audio/2.2/Android.bp b/bluetooth/audio/2.2/Android.bp
index 6449c08..8d52ce9 100644
--- a/bluetooth/audio/2.2/Android.bp
+++ b/bluetooth/audio/2.2/Android.bp
@@ -14,6 +14,7 @@
root: "android.hardware",
srcs: [
"types.hal",
+ "IBluetoothAudioPort.hal",
"IBluetoothAudioProvider.hal",
"IBluetoothAudioProvidersFactory.hal",
],
diff --git a/bluetooth/audio/2.2/IBluetoothAudioPort.hal b/bluetooth/audio/2.2/IBluetoothAudioPort.hal
new file mode 100644
index 0000000..344899c
--- /dev/null
+++ b/bluetooth/audio/2.2/IBluetoothAudioPort.hal
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 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.bluetooth.audio@2.2;
+
+import @2.0::IBluetoothAudioPort;
+import android.hardware.audio.common@5.0::SinkMetadata;
+
+interface IBluetoothAudioPort extends @2.0::IBluetoothAudioPort {
+ /**
+ * Called when the metadata of the stream's sink has been changed.
+ *
+ * @param sinkMetadata Description of the audio that is recorded by the
+ * clients.
+ */
+ updateSinkMetadata(SinkMetadata sinkMetadata);
+};
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index ad8c839..bc16b01 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -17,7 +17,7 @@
package android.hardware.bluetooth.audio@2.2;
import @2.1::IBluetoothAudioProvider;
-import @2.0::IBluetoothAudioPort;
+import @2.2::IBluetoothAudioPort;
import @2.0::Status;
/**
diff --git a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
index 126bc9e..2a6d93a 100644
--- a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
@@ -54,7 +54,7 @@
}
Return<void> A2dpOffloadAudioProvider::startSession(
- const sp<IBluetoothAudioPort>& hostIf,
+ const sp<V2_0::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
/**
* Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
index 0d918e1..ba31d39 100644
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
@@ -70,7 +70,7 @@
}
Return<void> A2dpSoftwareAudioProvider::startSession(
- const sp<IBluetoothAudioPort>& hostIf,
+ const sp<V2_0::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
/**
* Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
index 3d4f0cc..ac3aece 100644
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
+++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
@@ -40,7 +40,7 @@
bool isValid(const V2_1::SessionType& sessionType) override;
bool isValid(const V2_0::SessionType& sessionType) override;
- Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+ Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
const V2_0::AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
diff --git a/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
new file mode 100644
index 0000000..c5613fb
--- /dev/null
+++ b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.2/types.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_2 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::audio::common::V5_0::SinkMetadata;
+using ::android::hardware::audio::common::V5_0::SourceMetadata;
+using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
+
+class AudioPort_2_0_to_2_2_Wrapper : public V2_2::IBluetoothAudioPort {
+ public:
+ AudioPort_2_0_to_2_2_Wrapper(const sp<V2_0::IBluetoothAudioPort>& port) {
+ this->port = port;
+ }
+
+ Return<void> startStream() override { return port->startStream(); }
+ Return<void> suspendStream() override { return port->suspendStream(); }
+ Return<void> stopStream() override { return port->stopStream(); }
+ Return<void> getPresentationPosition(
+ getPresentationPosition_cb _hidl_cb) override {
+ return port->getPresentationPosition(_hidl_cb);
+ }
+ Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
+ return port->updateMetadata(sourceMetadata);
+ }
+ Return<void> updateSinkMetadata(const SinkMetadata&) override {
+ // DO NOTHING, 2.0 AudioPort doesn't support sink metadata updates
+ return Void();
+ }
+
+ sp<V2_0::IBluetoothAudioPort> port;
+};
+
+} // namespace implementation
+} // namespace V2_2
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 3655bc0..3c0ff42 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
#include "BluetoothAudioSessionReport_2_2.h"
#include "BluetoothAudioSupportedCodecsDB_2_1.h"
@@ -51,7 +52,7 @@
audio_config_({}) {}
Return<void> BluetoothAudioProvider::startSession(
- const sp<IBluetoothAudioPort>& hostIf,
+ const sp<V2_0::IBluetoothAudioPort>& hostIf,
const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
AudioConfiguration audioConfig_2_2;
@@ -67,11 +68,13 @@
audioConfig_2_2.codecConfig(audioConfig.codecConfig());
}
- return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+ sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+ new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+ return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
}
Return<void> BluetoothAudioProvider::startSession_2_1(
- const sp<IBluetoothAudioPort>& hostIf,
+ const sp<V2_0::IBluetoothAudioPort>& hostIf,
const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
AudioConfiguration audioConfig_2_2;
if (audioConfig.getDiscriminator() ==
@@ -92,11 +95,13 @@
audioConfig_2_2.codecConfig(audioConfig.codecConfig());
}
- return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+ sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+ new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+ return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
}
Return<void> BluetoothAudioProvider::startSession_2_2(
- const sp<IBluetoothAudioPort>& hostIf,
+ const sp<V2_2::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
if (hostIf == nullptr) {
_hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
index b7581ba..0f1f3c6 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -26,7 +26,7 @@
namespace implementation {
using ::android::sp;
-using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
+using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
using BluetoothAudioStatus =
::android::hardware::bluetooth::audio::V2_0::Status;
@@ -41,13 +41,13 @@
virtual bool isValid(const V2_1::SessionType& sessionType) = 0;
virtual bool isValid(const V2_0::SessionType& sessionType) = 0;
- Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+ Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
const V2_0::AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
- Return<void> startSession_2_1(const sp<IBluetoothAudioPort>& hostIf,
+ Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
const V2_1::AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
- Return<void> startSession_2_2(const sp<IBluetoothAudioPort>& hostIf,
+ Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
Return<void> streamStarted(BluetoothAudioStatus status) override;
@@ -59,7 +59,7 @@
V2_1::SessionType session_type_;
AudioConfiguration audio_config_;
- sp<V2_0::IBluetoothAudioPort> stack_iface_;
+ sp<V2_2::IBluetoothAudioPort> stack_iface_;
virtual Return<void> onSessionReady(startSession_cb _hidl_cb) = 0;
};
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
index c79b910..9b3294f 100644
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
@@ -66,7 +66,7 @@
}
Return<void> HearingAidAudioProvider::startSession(
- const sp<IBluetoothAudioPort>& hostIf,
+ const sp<V2_0::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
/**
* Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
index 426c443..63290b5 100644
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
+++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
@@ -40,7 +40,7 @@
bool isValid(const V2_1::SessionType& sessionType) override;
bool isValid(const V2_0::SessionType& sessionType) override;
- Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+ Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
const V2_0::AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
index af6ec99..9ec1776 100644
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
#include "BluetoothAudioSessionReport_2_2.h"
#include "BluetoothAudioSupportedCodecsDB_2_1.h"
@@ -83,11 +84,13 @@
.bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
.dataIntervalUs = 0});
- return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+ sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+ new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+ return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
}
Return<void> LeAudioAudioProvider::startSession_2_2(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ const sp<V2_2::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
/**
* Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
index 40c26e0..3de1724 100644
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
+++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
@@ -45,7 +45,7 @@
const V2_1::AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
- Return<void> startSession_2_2(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
index 7b70654..e3da267 100644
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
#include "BluetoothAudioSessionReport_2_2.h"
#include "BluetoothAudioSupportedCodecsDB_2_1.h"
#include "BluetoothAudioSupportedCodecsDB_2_2.h"
@@ -91,11 +92,13 @@
.peerDelay = 0,
.lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
- return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+ sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+ new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+ return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
}
Return<void> LeAudioOffloadAudioProvider::startSession_2_2(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ const sp<V2_2::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
/**
* Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
index 5620295..fe58de5 100644
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
@@ -38,7 +38,7 @@
const V2_1::AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
- Return<void> startSession_2_2(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
const AudioConfiguration& audioConfig,
startSession_cb _hidl_cb) override;
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index 60da877..12eed55 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
aidl_interface {
name: "android.hardware.bluetooth.audio",
vendor_available: true,
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index e389ef3..9a1557a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -38,5 +38,6 @@
void startStream();
void stopStream();
void suspendStream();
- void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+ void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+ void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 50e3197..827f57d 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -16,6 +16,7 @@
package android.hardware.bluetooth.audio;
+import android.hardware.audio.common.SinkMetadata;
import android.hardware.audio.common.SourceMetadata;
import android.hardware.bluetooth.audio.PresentationPosition;
@@ -69,5 +70,12 @@
* @param sourceMetadata Description of the audio that is played by the
* clients.
*/
- void updateMetadata(in SourceMetadata sourceMetadata);
+ void updateSourceMetadata(in SourceMetadata sourceMetadata);
+
+ /**
+ * Called when the metadata of the stream's sink has been changed.
+ *
+ * @param sinkMetadata as passed from Audio Framework
+ */
+ void updateSinkMetadata(in SinkMetadata sinkMetadata);
}
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 19d2d92..4f712bf 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -22,6 +22,7 @@
export_include_dirs: ["session/"],
header_libs: ["libhardware_headers"],
shared_libs: [
+ "android.hardware.audio.common@5.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
"android.hardware.bluetooth.audio@2.2",
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
index 95f7408..4d7be21 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
@@ -35,7 +35,7 @@
std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
- return session_ptr->IsSessionReady();
+ return session_ptr->GetAudioSession()->IsSessionReady();
}
return false;
}
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
index e20914e..b4ba8cf 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
@@ -132,6 +132,15 @@
}
}
+ static void UpdateSinkMetadata(const SessionType_2_1& session_type,
+ const struct sink_metadata* sink_metadata) {
+ std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+ BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->UpdateSinkMetadata(sink_metadata);
+ }
+ }
+
// The control API writes stream to FMQ
static size_t OutWritePcmData(const SessionType_2_1& session_type,
const void* buffer, size_t bytes) {
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
index c250ef1..646e225 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -60,16 +60,6 @@
}
}
-bool BluetoothAudioSession_2_1::IsSessionReady() {
- if (session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
- return audio_session->IsSessionReady();
- }
-
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- return audio_session->stack_iface_ != nullptr;
-}
-
std::shared_ptr<BluetoothAudioSession>
BluetoothAudioSession_2_1::GetAudioSession() {
return audio_session;
@@ -80,7 +70,7 @@
const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
BluetoothAudioSession_2_1::GetAudioConfig() {
std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (IsSessionReady()) {
+ if (audio_session->IsSessionReady()) {
// If session is unknown it means it should be 2.0 type
if (session_type_2_1_ != SessionType_2_1::UNKNOWN)
return audio_config_2_1_;
@@ -122,9 +112,6 @@
SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
bool is_offload_a2dp_session =
(session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- bool is_offload_le_audio_session =
- (session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
auto audio_config_discriminator = audio_config.getDiscriminator();
bool is_software_audio_config =
(is_software_session &&
@@ -136,13 +123,7 @@
audio_config_discriminator ==
::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
hidl_discriminator::codecConfig);
- bool is_le_audio_offload_audio_config =
- (is_offload_le_audio_session &&
- audio_config_discriminator ==
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
- hidl_discriminator::leAudioCodecConfig);
- if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
- !is_le_audio_offload_audio_config) {
+ if (!is_software_audio_config && !is_a2dp_offload_audio_config) {
return false;
}
audio_config_2_1_ = audio_config;
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
index db82c73..5a35153 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
@@ -50,10 +50,6 @@
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
session_type);
- // The function helps to check if this session is ready or not
- // @return: true if the Bluetooth stack has started the specified session
- bool IsSessionReady();
-
std::shared_ptr<BluetoothAudioSession> GetAudioSession();
// The report function is used to report that the Bluetooth stack has started
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index 5a6b2e7..80df5d9 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -20,10 +20,16 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioPort.h>
namespace android {
namespace bluetooth {
namespace audio {
+
+using ::android::hardware::audio::common::V5_0::AudioSource;
+using ::android::hardware::audio::common::V5_0::RecordTrackMetadata;
+using ::android::hardware::audio::common::V5_0::SinkMetadata;
+
using SessionType_2_1 =
::android::hardware::bluetooth::audio::V2_1::SessionType;
using SessionType_2_0 =
@@ -37,6 +43,9 @@
::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
BluetoothAudioSession_2_2::invalidOffloadAudioConfiguration = {};
+using IBluetoothAudioPort_2_2 =
+ ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
+
namespace {
bool is_2_0_session_type(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -84,6 +93,54 @@
return audio_session_2_1;
}
+void BluetoothAudioSession_2_2::UpdateSinkMetadata(
+ const struct sink_metadata* sink_metadata) {
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ if (!IsSessionReady()) {
+ LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " has NO session";
+ return;
+ }
+
+ ssize_t track_count = sink_metadata->track_count;
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << ", " << track_count << " track(s)";
+ if (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ return;
+ }
+
+ struct record_track_metadata* track = sink_metadata->tracks;
+ SinkMetadata sinkMetadata;
+ RecordTrackMetadata* halMetadata;
+
+ sinkMetadata.tracks.resize(track_count);
+ halMetadata = sinkMetadata.tracks.data();
+ while (track_count && track) {
+ halMetadata->source = static_cast<AudioSource>(track->source);
+ halMetadata->gain = track->gain;
+ // halMetadata->destination leave unspecified
+ LOG(INFO) << __func__
+ << " - SessionType=" << toString(GetAudioSession()->session_type_)
+ << ", source=" << track->source
+ << ", dest_device=" << track->dest_device
+ << ", gain=" << track->gain
+ << ", dest_device_address=" << track->dest_device_address;
+ --track_count;
+ ++track;
+ ++halMetadata;
+ }
+
+ /* This is called just for 2.2 sessions, so it's safe to do this casting*/
+ IBluetoothAudioPort_2_2* stack_iface_2_2_ =
+ static_cast<IBluetoothAudioPort_2_2*>(audio_session->stack_iface_.get());
+ auto hal_retval = stack_iface_2_2_->updateSinkMetadata(sinkMetadata);
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_2_1_) << " failed";
+ }
+}
+
// The control function is for the bluetooth_audio module to get the current
// AudioConfiguration
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index 7213ede..d6ae3d7 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -74,6 +74,8 @@
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
GetAudioConfig();
+ void UpdateSinkMetadata(const struct sink_metadata* sink_metadata);
+
static constexpr ::android::hardware::bluetooth::audio::V2_2::
AudioConfiguration& kInvalidSoftwareAudioConfiguration =
invalidSoftwareAudioConfiguration;
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index a781b35..9dc6fae 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -332,6 +332,13 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.net.nlinterceptor</name>
+ <interface>
+ <name>IInterceptor</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.oemlock</name>
<version>1</version>
<interface>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 2aa4bb2..720a767 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -56,6 +56,7 @@
"android.hardware.common",
"android.hardware.common.fmq",
"android.hardware.graphics.common",
+ "android.hardware.graphics.composer3.command",
"android.hardware.keymaster",
"android.hardware.radio",
"android.hardware.uwb.fira_android",
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
similarity index 71%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
rename to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
index a522d53..f02e08c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * Copyright (C) 2021 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
+ * 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,
@@ -31,11 +31,19 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
- INVALID = 0,
- NONE = 1,
- PREMULTIPLIED = 2,
- COVERAGE = 3,
+package android.hardware.gnss;
+@VintfStability
+interface IAGnss {
+ void setCallback(in android.hardware.gnss.IAGnssCallback callback);
+ void dataConnClosed();
+ void dataConnFailed();
+ void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in String hostname, in int port);
+ void dataConnOpen(in long networkHandle, in String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
+ @Backing(type="int") @VintfStability
+ enum ApnIpType {
+ INVALID = 0,
+ IPV4 = 1,
+ IPV6 = 2,
+ IPV4V6 = 3,
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
similarity index 70%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
index 41a1afe..2a46f61 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * Copyright (C) 2021 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
+ * 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,
@@ -31,10 +31,23 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.gnss;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+interface IAGnssCallback {
+ void agnssStatusCb(in android.hardware.gnss.IAGnssCallback.AGnssType type, in android.hardware.gnss.IAGnssCallback.AGnssStatusValue status);
+ @Backing(type="int") @VintfStability
+ enum AGnssType {
+ SUPL = 1,
+ C2K = 2,
+ SUPL_EIMS = 3,
+ SUPL_IMS = 4,
+ }
+ @Backing(type="int") @VintfStability
+ enum AGnssStatusValue {
+ REQUEST_AGNSS_DATA_CONN = 1,
+ RELEASE_AGNSS_DATA_CONN = 2,
+ AGNSS_DATA_CONNECTED = 3,
+ AGNSS_DATA_CONN_DONE = 4,
+ AGNSS_DATA_CONN_FAILED = 5,
+ }
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 9bd04a0..ea98030 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -43,6 +43,7 @@
@nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
@nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
@nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
+ android.hardware.gnss.IAGnss getExtensionAGnss();
const int ERROR_INVALID_ARGUMENT = 1;
const int ERROR_ALREADY_INIT = 2;
const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
new file mode 100644
index 0000000..3e256e2
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 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.gnss;
+
+import android.hardware.gnss.IAGnssCallback;
+import android.hardware.gnss.IAGnssCallback.AGnssType;
+
+/** Extended interface for Assisted GNSS support. */
+@VintfStability
+interface IAGnss {
+ /** Access point name IP type */
+ @VintfStability
+ @Backing(type="int")
+ enum ApnIpType {
+ INVALID = 0,
+ IPV4 = 1,
+ IPV6 = 2,
+ IPV4V6 = 3,
+ }
+
+ /**
+ * Opens the AGNSS interface and provides the callback routines to the
+ * implementation of this interface.
+ *
+ * If setCallback is not called, this interface will not respond to any
+ * other method calls.
+ *
+ * @param callback Handle to the AGNSS status callback interface.
+ */
+ void setCallback(in IAGnssCallback callback);
+
+ /**
+ * Notifies that the AGNSS data connection has been closed.
+ */
+ void dataConnClosed();
+
+ /**
+ * Notifies that a data connection is not available for AGNSS.
+ */
+ void dataConnFailed();
+
+ /**
+ * Sets the hostname and port for the AGNSS server.
+ *
+ * @param type Specifies if SUPL or C2K.
+ * @param hostname Hostname of the AGNSS server.
+ * @param port Port number associated with the server.
+ */
+ void setServer(in AGnssType type, in String hostname, in int port);
+
+ /**
+ * Notifies GNSS that a data connection is available and sets the network handle,
+ * name of the APN, and its IP type to be used for SUPL connections.
+ *
+ * The HAL implementation must use the network handle to set the network for the
+ * SUPL connection sockets using the android_setsocknetwork function. This will ensure
+ * that there is a network path to the SUPL server. The network handle can also be used
+ * to get the IP address of SUPL FQDN using the android_getaddrinfofornetwork() function.
+ *
+ * @param networkHandle Handle representing the network for use with the NDK API.
+ * @param apn Access Point Name (follows regular APN naming convention).
+ * @param apnIpType Specifies IP type of APN.
+ */
+ void dataConnOpen(in long networkHandle, in String apn, in ApnIpType apnIpType);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl
new file mode 100644
index 0000000..7c25937
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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.gnss;
+
+/** Callback structure for the AGNSS interface. */
+@VintfStability
+interface IAGnssCallback {
+ /** AGNSS service type */
+ @VintfStability
+ @Backing(type="int")
+ enum AGnssType {
+ SUPL = 1,
+ C2K = 2,
+ SUPL_EIMS = 3,
+ SUPL_IMS = 4,
+ }
+
+ /** AGNSS status value */
+ @VintfStability
+ @Backing(type="int")
+ enum AGnssStatusValue {
+ /** GNSS requests data connection for AGNSS. */
+ REQUEST_AGNSS_DATA_CONN = 1,
+
+ /** GNSS releases the AGNSS data connection. */
+ RELEASE_AGNSS_DATA_CONN = 2,
+
+ /** AGNSS data connection initiated */
+ AGNSS_DATA_CONNECTED = 3,
+
+ /** AGNSS data connection completed */
+ AGNSS_DATA_CONN_DONE = 4,
+
+ /** AGNSS data connection failed */
+ AGNSS_DATA_CONN_FAILED = 5,
+ }
+
+ /**
+ * Callback with AGNSS status information.
+ *
+ * The GNSS HAL implementation must use this method to request the framework to setup
+ * network connection for the specified AGNSS service and to update the connection
+ * status so that the framework can release the resources.
+ *
+ * @param type Type of AGNSS service.
+ * @parama status Status of the data connection.
+ */
+ void agnssStatusCb(in AGnssType type, in AGnssStatusValue status);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 42cc496..91403ca 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,6 +16,7 @@
package android.hardware.gnss;
+import android.hardware.gnss.IAGnss;
import android.hardware.gnss.IGnssBatching;
import android.hardware.gnss.IGnssCallback;
import android.hardware.gnss.IGnssConfiguration;
@@ -75,7 +76,7 @@
/**
* This method returns the IGnssPsds interface.
*
- * @return Handle to the IGnssPsds interface.
+ * @return The IGnssPsds interface.
*/
@nullable IGnssPsds getExtensionPsds();
@@ -84,7 +85,7 @@
*
* This method must return non-null.
*
- * @return Handle to the IGnssConfiguration interface.
+ * @return The IGnssConfiguration interface.
*/
IGnssConfiguration getExtensionGnssConfiguration();
@@ -93,7 +94,7 @@
*
* This method must return non-null.
*
- * @return Handle to the IGnssMeasurementInterface interface.
+ * @return The IGnssMeasurementInterface interface.
*/
IGnssMeasurementInterface getExtensionGnssMeasurement();
@@ -102,28 +103,35 @@
*
* This method must return non-null.
*
- * @return Handle to the IGnssPowerIndication interface.
+ * @return The IGnssPowerIndication interface.
*/
IGnssPowerIndication getExtensionGnssPowerIndication();
/**
* This method returns the IGnssBatching interface.
*
- * @return Handle to the IGnssBatching interface.
+ * @return The IGnssBatching interface.
*/
@nullable IGnssBatching getExtensionGnssBatching();
/**
* This method returns the IGnssGeofence interface.
*
- * @return Handle to the IGnssGeofence interface.
+ * @return The IGnssGeofence interface.
*/
@nullable IGnssGeofence getExtensionGnssGeofence();
/**
* This method returns the IGnssNavigationMessageInterface.
*
- * @return Handle to the IGnssNavigationMessageInterface.
+ * @return The IGnssNavigationMessageInterface.
*/
@nullable IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
+
+ /**
+ * This method returns the IAGnss interface.
+ *
+ * @return The IAGnss interface.
+ */
+ IAGnss getExtensionAGnss();
}
diff --git a/gnss/aidl/default/AGnss.cpp b/gnss/aidl/default/AGnss.cpp
new file mode 100644
index 0000000..e8d5ef7
--- /dev/null
+++ b/gnss/aidl/default/AGnss.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "AGnssAidl"
+
+#include "AGnss.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+std::shared_ptr<IAGnssCallback> AGnss::sCallback = nullptr;
+
+ndk::ScopedAStatus AGnss::setCallback(const std::shared_ptr<IAGnssCallback>& callback) {
+ ALOGD("AGnss::setCallback");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AGnss::setServer(AGnssType type, const std::string& hostname, int port) {
+ ALOGD("AGnss::setServer: type: %s, hostname: %s, port: %d", toString(type).c_str(),
+ hostname.c_str(), port);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AGnss::dataConnOpen(int64_t networkHandle, const std::string& apn,
+ ApnIpType apnIpType) {
+ ALOGD("AGnss::dataConnOpen: networkHandle:%" PRId64 ", apn: %s, apnIpType %s", networkHandle,
+ apn.c_str(), toString(apnIpType).c_str());
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/AGnss.h b/gnss/aidl/default/AGnss.h
new file mode 100644
index 0000000..cd973e1
--- /dev/null
+++ b/gnss/aidl/default/AGnss.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnAGnss.h>
+
+namespace aidl::android::hardware::gnss {
+
+using AGnssType = IAGnssCallback::AGnssType;
+
+struct AGnss : public BnAGnss {
+ public:
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IAGnssCallback>& callback) override;
+ ndk::ScopedAStatus dataConnClosed() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus dataConnFailed() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus setServer(AGnssType type, const std::string& hostname, int port) override;
+ ndk::ScopedAStatus dataConnOpen(int64_t networkHandle, const std::string& apn,
+ ApnIpType apnIpType) override;
+
+ private:
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+ // Guarded by mMutex
+ static std::shared_ptr<IAGnssCallback> sCallback;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index b6df895..1236714 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -55,6 +55,7 @@
"android.hardware.gnss-V2-ndk",
],
srcs: [
+ "AGnss.cpp",
"Gnss.cpp",
"GnssBatching.cpp",
"GnssGeofence.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 8d58a20..0e3cdd3 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -18,6 +18,7 @@
#include "Gnss.h"
#include <log/log.h>
+#include "AGnss.h"
#include "GnssBatching.h"
#include "GnssConfiguration.h"
#include "GnssGeofence.h"
@@ -56,6 +57,12 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
+ ALOGD("Gnss::getExtensionAGnss");
+ *iAGnss = SharedRefBase::make<AGnss>();
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
ALOGD("Gnss::getExtensionPsds");
*iGnssPsds = SharedRefBase::make<GnssPsds>();
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 128a6c1..4feb781 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -16,6 +16,7 @@
#pragma once
+#include <aidl/android/hardware/gnss/BnAGnss.h>
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <aidl/android/hardware/gnss/BnGnssBatching.h>
#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
@@ -44,6 +45,7 @@
std::shared_ptr<IGnssGeofence>* iGnssGeofence) override;
ndk::ScopedAStatus getExtensionGnssNavigationMessage(
std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) override;
+ ndk::ScopedAStatus getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/vts/AGnssCallbackAidl.cpp b/gnss/aidl/vts/AGnssCallbackAidl.cpp
new file mode 100644
index 0000000..3327835
--- /dev/null
+++ b/gnss/aidl/vts/AGnssCallbackAidl.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "AGnssCallbackAidl.h"
+#include <log/log.h>
+
+android::binder::Status AGnssCallbackAidl::agnssStatusCb(const AGnssType type,
+ const AGnssStatusValue status) {
+ ALOGI("agnssStatusCb type %d status %d", type, status);
+ return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/AGnssCallbackAidl.h b/gnss/aidl/vts/AGnssCallbackAidl.h
new file mode 100644
index 0000000..6173e85
--- /dev/null
+++ b/gnss/aidl/vts/AGnssCallbackAidl.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnAGnssCallback.h>
+
+using AGnssType = android::hardware::gnss::IAGnssCallback::AGnssType;
+using AGnssStatusValue = android::hardware::gnss::IAGnssCallback::AGnssStatusValue;
+
+/** Implementation for IAGnssCallback. */
+class AGnssCallbackAidl : public android::hardware::gnss::BnAGnssCallback {
+ public:
+ AGnssCallbackAidl(){};
+ ~AGnssCallbackAidl(){};
+ android::binder::Status agnssStatusCb(const AGnssType type,
+ const AGnssStatusValue status) override;
+};
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 4d81519..041d579 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -30,6 +30,7 @@
srcs: [
"gnss_hal_test.cpp",
"gnss_hal_test_cases.cpp",
+ "AGnssCallbackAidl.cpp",
"GnssBatchingCallback.cpp",
"GnssCallbackAidl.cpp",
"GnssGeofenceCallback.cpp",
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 830922c..aac59db 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -16,12 +16,14 @@
#define LOG_TAG "GnssHalTestCases"
+#include <android/hardware/gnss/IAGnss.h>
#include <android/hardware/gnss/IGnss.h>
#include <android/hardware/gnss/IGnssBatching.h>
#include <android/hardware/gnss/IGnssMeasurementCallback.h>
#include <android/hardware/gnss/IGnssMeasurementInterface.h>
#include <android/hardware/gnss/IGnssPowerIndication.h>
#include <android/hardware/gnss/IGnssPsds.h>
+#include "AGnssCallbackAidl.h"
#include "GnssBatchingCallback.h"
#include "GnssGeofenceCallback.h"
#include "GnssMeasurementCallbackAidl.h"
@@ -36,6 +38,7 @@
using android::hardware::gnss::GnssData;
using android::hardware::gnss::GnssMeasurement;
using android::hardware::gnss::GnssPowerStats;
+using android::hardware::gnss::IAGnss;
using android::hardware::gnss::IGnss;
using android::hardware::gnss::IGnssBatching;
using android::hardware::gnss::IGnssBatchingCallback;
@@ -793,3 +796,27 @@
ASSERT_TRUE(status.isOk());
}
}
+
+/*
+ * TestAGnssExtension:
+ * 1. Gets the IAGnss extension.
+ * 2. Sets AGnssCallback.
+ * 3. Sets SUPL server host/port.
+ */
+TEST_P(GnssHalTest, TestAGnssExtension) {
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ return;
+ }
+ sp<IAGnss> iAGnss;
+ auto status = aidl_gnss_hal_->getExtensionAGnss(&iAGnss);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iAGnss != nullptr);
+
+ auto agnssCallback = sp<AGnssCallbackAidl>::make();
+ status = iAGnss->setCallback(agnssCallback);
+ ASSERT_TRUE(status.isOk());
+
+ // Set SUPL server host/port
+ status = iAGnss->setServer(AGnssType::SUPL, String16("supl.google.com"), 7275);
+ ASSERT_TRUE(status.isOk());
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
index 04a863b..512fecb 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
@@ -63,4 +63,5 @@
STENCIL_8 = 53,
YCBCR_P010 = 54,
HSV_888 = 55,
+ R_8 = 56,
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
similarity index 92%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
index cfafc50..3722803 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
@@ -31,8 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
- CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.common;
+@VintfStability
+parcelable Point {
+ int x;
+ int y;
}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
index eb87f8d..4e891f6 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
@@ -498,4 +498,11 @@
* interpretation is defined by the dataspace.
*/
HSV_888 = 0x37,
+
+ /**
+ * 8 bit format with a single 8-bit component.
+ *
+ * The component values are unsigned normalized to the range [0, 1].
+ */
+ R_8 = 0x38,
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/common/aidl/android/hardware/graphics/common/Point.aidl
index 10de558..b3ede44 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
@@ -14,18 +14,14 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.common;
/**
- * Layer requests returned from getDisplayRequests.
+ * General purpose definition of a point.
*/
+
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
- /**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
- */
- CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable Point {
+ int x;
+ int y;
}
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index e33c653..9034138 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -31,12 +31,14 @@
enabled: true,
support_system_process: true,
},
- srcs: ["android/hardware/graphics/composer3/*.aidl"],
+ srcs: [
+ "android/hardware/graphics/composer3/*.aidl",
+ "android/hardware/graphics/composer3/command/*.aidl",
+ ],
stability: "vintf",
imports: [
"android.hardware.graphics.common-V3",
"android.hardware.common-V2",
- "android.hardware.common.fmq-V1",
],
backend: {
cpp: {
@@ -73,6 +75,7 @@
vendor_available: true,
shared_libs: [
"android.hardware.graphics.composer3-V1-ndk",
+ "android.hardware.common-V2-ndk",
"libbase",
"libfmq",
"libsync",
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index e19105d..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Copyright (c) 2021, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum Command {
- LENGTH_MASK = 65535,
- OPCODE_SHIFT = 16,
- OPCODE_MASK = -65536,
- SELECT_DISPLAY = 0,
- SELECT_LAYER = 65536,
- SET_ERROR = 16777216,
- SET_CHANGED_COMPOSITION_TYPES = 16842752,
- SET_DISPLAY_REQUESTS = 16908288,
- SET_PRESENT_FENCE = 16973824,
- SET_RELEASE_FENCES = 17039360,
- SET_COLOR_TRANSFORM = 33554432,
- SET_CLIENT_TARGET = 33619968,
- SET_OUTPUT_BUFFER = 33685504,
- VALIDATE_DISPLAY = 33751040,
- ACCEPT_DISPLAY_CHANGES = 33816576,
- PRESENT_DISPLAY = 33882112,
- PRESENT_OR_VALIDATE_DISPLAY = 33947648,
- SET_LAYER_CURSOR_POSITION = 50331648,
- SET_LAYER_BUFFER = 50397184,
- SET_LAYER_SURFACE_DAMAGE = 50462720,
- SET_LAYER_BLEND_MODE = 67108864,
- SET_LAYER_COLOR = 67174400,
- SET_LAYER_COMPOSITION_TYPE = 67239936,
- SET_LAYER_DATASPACE = 67305472,
- SET_LAYER_DISPLAY_FRAME = 67371008,
- SET_LAYER_PLANE_ALPHA = 67436544,
- SET_LAYER_SIDEBAND_STREAM = 67502080,
- SET_LAYER_SOURCE_CROP = 67567616,
- SET_LAYER_TRANSFORM = 67633152,
- SET_LAYER_VISIBLE_REGION = 67698688,
- SET_LAYER_Z_ORDER = 67764224,
- SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 67829760,
- SET_LAYER_PER_FRAME_METADATA = 50528256,
- SET_LAYER_FLOAT_COLOR = 67895296,
- SET_LAYER_COLOR_TRANSFORM = 67960832,
- SET_LAYER_PER_FRAME_METADATA_BLOBS = 50593792,
- SET_CLIENT_TARGET_PROPERTY = 17104896,
- SET_LAYER_GENERIC_METADATA = 68026368,
- SET_LAYER_WHITE_POINT_NITS = 50659328,
-}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index d7cab2b..65cf86c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -38,7 +38,7 @@
android.hardware.graphics.composer3.VirtualDisplay createVirtualDisplay(int width, int height, android.hardware.graphics.common.PixelFormat formatHint, int outputBufferSlotCount);
void destroyLayer(long display, long layer);
void destroyVirtualDisplay(long display);
- android.hardware.graphics.composer3.ExecuteCommandsStatus executeCommands(int inLength, in android.hardware.common.NativeHandle[] inHandles);
+ android.hardware.graphics.composer3.command.CommandResultPayload[] executeCommands(in android.hardware.graphics.composer3.command.CommandPayload[] commands);
int getActiveConfig(long display);
android.hardware.graphics.composer3.ColorMode[] getColorModes(long display);
float[] getDataspaceSaturationMatrix(android.hardware.graphics.common.Dataspace dataspace);
@@ -56,7 +56,6 @@
android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display);
android.hardware.graphics.composer3.LayerGenericMetadataKey[] getLayerGenericMetadataKeys();
int getMaxVirtualDisplayCount();
- android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> getOutputCommandQueue();
android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display);
android.hardware.graphics.composer3.ReadbackBufferAttributes getReadbackBufferAttributes(long display);
ParcelFileDescriptor getReadbackBufferFence(long display);
@@ -71,7 +70,6 @@
void setContentType(long display, android.hardware.graphics.composer3.ContentType type);
void setDisplayBrightness(long display, float brightness);
void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames);
- void setInputCommandQueue(in android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> descriptor);
void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in ParcelFileDescriptor releaseFence);
void setVsyncEnabled(long display, boolean enabled);
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
similarity index 89%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
index 26e7d97..cead848 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
@@ -31,9 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable Buffer {
+ int slot;
+ @nullable android.hardware.common.NativeHandle handle;
+ @nullable ParcelFileDescriptor fence;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
index 26e7d97..1377c6c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
@@ -31,9 +31,14 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ChangedCompositionTypes {
+ long display;
+ android.hardware.graphics.composer3.command.ChangedCompositionTypes.Layer[] layers;
+ @VintfStability
+ parcelable Layer {
+ long layer;
+ android.hardware.graphics.composer3.Composition composition;
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
index 26e7d97..c3f4700 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
@@ -31,9 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ClientTarget {
+ android.hardware.graphics.composer3.command.Buffer buffer;
+ android.hardware.graphics.common.Dataspace dataspace;
+ android.hardware.graphics.common.Rect[] damage;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
index 41a1afe..b690a57 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
@@ -31,10 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+parcelable ClientTargetPropertyWithNits {
+ long display;
+ android.hardware.graphics.composer3.ClientTargetProperty clientTargetProperty;
+ float whitePointNits;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
index 41a1afe..0b3071c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
@@ -31,10 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+parcelable ColorTransformPayload {
+ float[] matrix;
+ android.hardware.graphics.common.ColorTransform hint;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
index 26e7d97..9848306 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
@@ -31,9 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+union CommandPayload {
+ android.hardware.graphics.composer3.command.DisplayCommand displayCommand;
+ android.hardware.graphics.composer3.command.LayerCommand layerCommand;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
similarity index 72%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
index 41a1afe..1b3cae8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
@@ -31,10 +31,14 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+union CommandResultPayload {
+ android.hardware.graphics.composer3.command.Error error;
+ android.hardware.graphics.composer3.command.ChangedCompositionTypes changedCompositionType;
+ android.hardware.graphics.composer3.command.DisplayRequest displayRequest;
+ android.hardware.graphics.composer3.command.PresentFence presentFence;
+ android.hardware.graphics.composer3.command.ReleaseFences releaseFences;
+ android.hardware.graphics.composer3.command.PresentOrValidate presentOrValidateResult;
+ android.hardware.graphics.composer3.command.ClientTargetPropertyWithNits clientTargetProperty;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
similarity index 77%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
index 41a1afe..7446db0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
@@ -31,10 +31,15 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+parcelable DisplayCommand {
+ long display;
+ @nullable android.hardware.graphics.composer3.command.ColorTransformPayload colorTransform;
+ @nullable android.hardware.graphics.composer3.command.ClientTarget clientTarget;
+ @nullable android.hardware.graphics.composer3.command.Buffer virtualDisplayOutputBuffer;
+ boolean validateDisplay;
+ boolean acceptDisplayChanges;
+ boolean presentDisplay;
+ boolean presentOrValidateDisplay;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
similarity index 80%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
index 26e7d97..7f413a9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
@@ -31,9 +31,18 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable DisplayRequest {
+ long display;
+ int mask;
+ android.hardware.graphics.composer3.command.DisplayRequest.LayerRequest[] layerRequests;
+ const int FLIP_CLIENT_TARGET = 1;
+ const int WRITE_CLIENT_TARGET_TO_OUTPUT = 2;
+ @VintfStability
+ parcelable LayerRequest {
+ long layer;
+ int mask;
+ const int CLEAR_CLIENT_TARGET = 1;
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
index cfafc50..1726ea5 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
@@ -31,8 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
- CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable Error {
+ int commandIndex;
+ int errorCode;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
similarity index 90%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
index 41a1afe..be889d8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
@@ -31,10 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+parcelable GenericMetadata {
+ android.hardware.graphics.composer3.LayerGenericMetadataKey key;
+ byte[] value;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl
new file mode 100644
index 0000000..b5adbc3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2021, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable LayerCommand {
+ long display;
+ long layer;
+ @nullable android.hardware.graphics.common.Point cursorPosition;
+ @nullable android.hardware.graphics.composer3.command.Buffer buffer;
+ @nullable android.hardware.graphics.common.Rect[] damage;
+ @nullable android.hardware.graphics.composer3.command.ParcelableBlendMode blendMode;
+ @nullable android.hardware.graphics.composer3.Color color;
+ @nullable android.hardware.graphics.composer3.FloatColor floatColor;
+ @nullable android.hardware.graphics.composer3.command.ParcelableComposition composition;
+ @nullable android.hardware.graphics.composer3.command.ParcelableDataspace dataspace;
+ @nullable android.hardware.graphics.common.Rect displayFrame;
+ @nullable android.hardware.graphics.composer3.command.PlaneAlpha planeAlpha;
+ @nullable android.hardware.common.NativeHandle sidebandStream;
+ @nullable android.hardware.graphics.common.FRect sourceCrop;
+ @nullable android.hardware.graphics.composer3.command.ParcelableTransform transform;
+ @nullable android.hardware.graphics.common.Rect[] visibleRegion;
+ @nullable android.hardware.graphics.composer3.command.ZOrder z;
+ @nullable float[] colorTransform;
+ @nullable android.hardware.graphics.composer3.command.WhitePointNits whitePointNits;
+ @nullable android.hardware.graphics.composer3.command.GenericMetadata genericMetadata;
+ @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
+ @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
index 26e7d97..5e6d212 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
@@ -31,9 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableBlendMode {
+ android.hardware.graphics.common.BlendMode blendMode;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
index 26e7d97..40637a9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
@@ -31,9 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableComposition {
+ android.hardware.graphics.composer3.Composition composition;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
similarity index 90%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
index 26e7d97..8f06079 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
@@ -31,9 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableDataspace {
+ android.hardware.graphics.common.Dataspace dataspace;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
index 26e7d97..6d6fe5b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
@@ -31,9 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
- FLIP_CLIENT_TARGET = 1,
- WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableTransform {
+ android.hardware.graphics.common.Transform transform;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
index cfafc50..97f5329 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
@@ -31,8 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
- CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable PlaneAlpha {
+ float alpha;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
similarity index 91%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
index cfafc50..906f20c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
@@ -31,8 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
- CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable PresentFence {
+ long display;
+ ParcelFileDescriptor fence;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
index 41a1afe..66f1c03 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
@@ -31,10 +31,14 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+parcelable PresentOrValidate {
+ long display;
+ android.hardware.graphics.composer3.command.PresentOrValidate.Result result;
+ @VintfStability
+ enum Result {
+ Presented = 0,
+ Validated = 1,
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
index 41a1afe..b7d2586 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
@@ -31,10 +31,14 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+parcelable ReleaseFences {
+ long display;
+ android.hardware.graphics.composer3.command.ReleaseFences.Layer[] layers;
+ @VintfStability
+ parcelable Layer {
+ long layer;
+ ParcelFileDescriptor fence;
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
index cfafc50..2b25167 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
@@ -31,8 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
- CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable WhitePointNits {
+ float nits;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
index cfafc50..69b68c4 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
@@ -31,8 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
- CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ZOrder {
+ int z;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index 95c07ac..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,763 +0,0 @@
-/**
- * Copyright (c) 2021, 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.graphics.composer3;
-
-import android.hardware.graphics.composer3.Command;
-
-/**
- * The command interface allows composer3 to reduce binder overhead by sending
- * atomic command stream in a command message queue. These commands are usually
- * sent on a per frame basic and contains the information that describes how the
- * display is composited. @see IComposerClient.executeCommands.
- */
-@VintfStability
-@Backing(type="int")
-enum Command {
- LENGTH_MASK = 0xffff,
- OPCODE_SHIFT = 16,
- OPCODE_MASK = 0xffff << OPCODE_SHIFT,
-
- // special commands
-
- /**
- * SELECT_DISPLAY has this pseudo prototype
- *
- * selectDisplay(long display);
- *
- * Selects the current display implied by all other commands.
- *
- * @param display is the newly selected display.
- */
- SELECT_DISPLAY = 0x000 << OPCODE_SHIFT,
-
- /**
- * SELECT_LAYER has this pseudo prototype
- *
- * selectLayer(long layer);
- *
- * Selects the current layer implied by all implicit layer commands.
- *
- * @param layer is the newly selected layer.
- */
- SELECT_LAYER = 0x001 << OPCODE_SHIFT,
-
- // value commands (for return values)
-
- /**
- * SET_ERROR has this pseudo prototype
- *
- * setError(uint32_t location, int error);
- *
- * Indicates an error generated by a command.
- *
- * @param location is the offset of the command in the input command
- * message queue.
- * @param error is the error generated by the command.
- */
- SET_ERROR = 0x100 << OPCODE_SHIFT,
-
- /**
- * SET_CHANGED_COMPOSITION_TYPES has this pseudo prototype
- *
- * setChangedCompositionTypes(long[] layers,
- * Composition[] types);
- *
- * Sets the layers for which the device requires a different composition
- * type than had been set prior to the last call to VALIDATE_DISPLAY. The
- * client must either update its state with these types and call
- * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
- * the display again.
- *
- * @param layers is an array of layer handles.
- * @param types is an array of composition types, each corresponding to
- * an element of layers.
- */
- SET_CHANGED_COMPOSITION_TYPES = 0x101 << OPCODE_SHIFT,
-
- /**
- * SET_DISPLAY_REQUESTS has this pseudo prototype
- *
- * setDisplayRequests(int displayRequestMask,
- * long[] layers,
- * int[] layerRequestMasks);
- *
- * Sets the display requests and the layer requests required for the last
- * validated configuration.
- *
- * Display requests provide information about how the client must handle
- * the client target. Layer requests provide information about how the
- * client must handle an individual layer.
- *
- * @param displayRequestMask is the display requests for the current
- * validated state.
- * @param layers is an array of layers which all have at least one
- * request.
- * @param layerRequestMasks is the requests corresponding to each element
- * of layers.
- */
- SET_DISPLAY_REQUESTS = 0x102 << OPCODE_SHIFT,
-
- /**
- * SET_PRESENT_FENCE has this pseudo prototype
- *
- * setPresentFence(int presentFenceIndex);
- *
- * Sets the present fence as a result of PRESENT_DISPLAY. For physical
- * displays, this fence must be signaled at the vsync when the result
- * of composition of this frame starts to appear (for video-mode panels)
- * or starts to transfer to panel memory (for command-mode panels). For
- * virtual displays, this fence must be signaled when writes to the output
- * buffer have completed and it is safe to read from it.
- *
- * @param presentFenceIndex is an index into outHandles array.
- */
- SET_PRESENT_FENCE = 0x103 << OPCODE_SHIFT,
-
- /**
- * SET_RELEASE_FENCES has this pseudo prototype
- *
- * setReleaseFences(long[] layers,
- * int[] releaseFenceIndices);
- *
- * Sets the release fences for device layers on this display which will
- * receive new buffer contents this frame.
- *
- * A release fence is a file descriptor referring to a sync fence object
- * which must be signaled after the device has finished reading from the
- * buffer presented in the prior frame. This indicates that it is safe to
- * start writing to the buffer again. If a given layer's fence is not
- * returned from this function, it must be assumed that the buffer
- * presented on the previous frame is ready to be written.
- *
- * The fences returned by this function must be unique for each layer
- * (even if they point to the same underlying sync object).
- *
- * @param layers is an array of layer handles.
- * @param releaseFenceIndices are indices into outHandles array, each
- * corresponding to an element of layers.
- */
- SET_RELEASE_FENCES = 0x104 << OPCODE_SHIFT,
-
- // display commands
-
- /**
- * SET_COLOR_TRANSFORM has this pseudo prototype
- *
- * setColorTransform(float[16] matrix,
- * ColorTransform hint);
- *
- * Sets a color transform which will be applied after composition.
- *
- * If hint is not ColorTransform::ARBITRARY, then the device may use the
- * hint to apply the desired color transform instead of using the color
- * matrix directly.
- *
- * If the device is not capable of either using the hint or the matrix to
- * apply the desired color transform, it must force all layers to client
- * composition during VALIDATE_DISPLAY.
- *
- * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
- * the client must never apply the color transform during client
- * composition, even if all layers are being composed by the client.
- *
- * The matrix provided is an affine color transformation of the following
- * form:
- *
- * |r.r r.g r.b 0|
- * |g.r g.g g.b 0|
- * |b.r b.g b.b 0|
- * |Tr Tg Tb 1|
- *
- * This matrix must be provided in row-major form:
- *
- * {r.r, r.g, r.b, 0, g.r, ...}.
- *
- * Given a matrix of this form and an input color [R_in, G_in, B_in], the
- * output color [R_out, G_out, B_out] will be:
- *
- * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
- * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
- * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
- *
- * @param matrix is a 4x4 transform matrix (16 floats) as described above.
- * @param hint is a hint value which may be used instead of the given
- * matrix unless it is ColorTransform::ARBITRARY.
- */
- SET_COLOR_TRANSFORM = 0x200 << OPCODE_SHIFT,
-
- /**
- * SET_CLIENT_TARGET has this pseudo prototype
- *
- * setClientTarget(int targetSlot,
- * int targetIndex,
- * int acquireFenceIndex,
- * android.hardware.graphics.common.Dataspace dataspace,
- * Rect[] damage);
- *
- * Sets the buffer handle which will receive the output of client
- * composition. Layers marked as Composition::CLIENT must be composited
- * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
- * marked as Composition::CLIENT must be composited with this buffer by
- * the device.
- *
- * The buffer handle provided may be empty if no layers are being
- * composited by the client. This must not result in an error (unless an
- * invalid display handle is also provided).
- *
- * Also provides a file descriptor referring to an acquire sync fence
- * object, which must be signaled when it is safe to read from the client
- * target buffer. If it is already safe to read from this buffer, an
- * empty handle may be passed instead.
- *
- * For more about dataspaces, see SET_LAYER_DATASPACE.
- *
- * The damage parameter describes a surface damage region as defined in
- * the description of SET_LAYER_SURFACE_DAMAGE.
- *
- * Will be called before PRESENT_DISPLAY if any of the layers are marked
- * as Composition::CLIENT. If no layers are so marked, then it is not
- * necessary to call this function. It is not necessary to call
- * validateDisplay after changing the target through this function.
- *
- * @param targetSlot is the client target buffer slot to use.
- * @param targetIndex is an index into inHandles for the new target
- * buffer.
- * @param acquireFenceIndex is an index into inHandles for a sync fence
- * file descriptor as described above.
- * @param dataspace is the dataspace of the buffer, as described in
- * setLayerDataspace.
- * @param damage is the surface damage region.
- *
- */
- SET_CLIENT_TARGET = 0x201 << OPCODE_SHIFT,
-
- /**
- * SET_OUTPUT_BUFFER has this pseudo prototype
- *
- * setOutputBuffer(int bufferSlot,
- * int bufferIndex,
- * int releaseFenceIndex);
- *
- * Sets the output buffer for a virtual display. That is, the buffer to
- * which the composition result will be written.
- *
- * Also provides a file descriptor referring to a release sync fence
- * object, which must be signaled when it is safe to write to the output
- * buffer. If it is already safe to write to the output buffer, an empty
- * handle may be passed instead.
- *
- * Must be called at least once before PRESENT_DISPLAY, but does not have
- * any interaction with layer state or display validation.
- *
- * @param bufferSlot is the new output buffer.
- * @param bufferIndex is the new output buffer.
- * @param releaseFenceIndex is a sync fence file descriptor as described
- * above.
- */
- SET_OUTPUT_BUFFER = 0x202 << OPCODE_SHIFT,
-
- /**
- * VALIDATE_DISPLAY has this pseudo prototype
- *
- * validateDisplay();
- *
- * Instructs the device to inspect all of the layer state and determine if
- * there are any composition type changes necessary before presenting the
- * display. Permitted changes are described in the definition of
- * Composition above.
- */
- VALIDATE_DISPLAY = 0x203 << OPCODE_SHIFT,
-
- /**
- * ACCEPT_DISPLAY_CHANGES has this pseudo prototype
- *
- * acceptDisplayChanges();
- *
- * Accepts the changes required by the device from the previous
- * validateDisplay call (which may be queried using
- * getChangedCompositionTypes) and revalidates the display. This function
- * is equivalent to requesting the changed types from
- * getChangedCompositionTypes, setting those types on the corresponding
- * layers, and then calling validateDisplay again.
- *
- * After this call it must be valid to present this display. Calling this
- * after validateDisplay returns 0 changes must succeed with NONE, but
- * must have no other effect.
- */
- ACCEPT_DISPLAY_CHANGES = 0x204 << OPCODE_SHIFT,
-
- /**
- * PRESENT_DISPLAY has this pseudo prototype
- *
- * presentDisplay();
- *
- * Presents the current display contents on the screen (or in the case of
- * virtual displays, into the output buffer).
- *
- * Prior to calling this function, the display must be successfully
- * validated with validateDisplay. Note that setLayerBuffer and
- * setLayerSurfaceDamage specifically do not count as layer state, so if
- * there are no other changes to the layer state (or to the buffer's
- * properties as described in setLayerBuffer), then it is safe to call
- * this function without first validating the display.
- */
- PRESENT_DISPLAY = 0x205 << OPCODE_SHIFT,
-
- /**
- * PRESENT_OR_VALIDATE_DISPLAY has this pseudo prototype
- *
- * presentOrValidateDisplay();
- *
- * Presents the current display contents on the screen (or in the case of
- * virtual displays, into the output buffer) if validate can be skipped,
- * or perform a VALIDATE_DISPLAY action instead.
- */
- PRESENT_OR_VALIDATE_DISPLAY = 0x206 << OPCODE_SHIFT,
-
- // layer commands (VALIDATE_DISPLAY not required)
-
- /**
- * SET_LAYER_CURSOR_POSITION has this pseudo prototype
- *
- * setLayerCursorPosition(int x, int y);
- *
- * Asynchronously sets the position of a cursor layer.
- *
- * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
- * If validation succeeds (i.e., the device does not request a composition
- * change for that layer), then once a buffer has been set for the layer
- * and it has been presented, its position may be set by this function at
- * any time between presentDisplay and any subsequent validateDisplay
- * calls for this display.
- *
- * Once validateDisplay is called, this function must not be called again
- * until the validate/present sequence is completed.
- *
- * May be called from any thread so long as it is not interleaved with the
- * validate/present sequence as described above.
- *
- * @param layer is the layer to which the position is set.
- * @param x is the new x coordinate (in pixels from the left of the
- * screen).
- * @param y is the new y coordinate (in pixels from the top of the
- * screen).
- */
- SET_LAYER_CURSOR_POSITION = 0x300 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_BUFFER has this pseudo prototype
- *
- * setLayerBuffer(int bufferSlot,
- * int bufferIndex,
- * int acquireFenceIndex);
- *
- * Sets the buffer handle to be displayed for this layer. If the buffer
- * properties set at allocation time (width, height, format, and usage)
- * have not changed since the previous frame, it is not necessary to call
- * validateDisplay before calling presentDisplay unless new state needs to
- * be validated in the interim.
- *
- * Also provides a file descriptor referring to an acquire sync fence
- * object, which must be signaled when it is safe to read from the given
- * buffer. If it is already safe to read from the buffer, an empty handle
- * may be passed instead.
- *
- * This function must return NONE and have no other effect if called for a
- * layer with a composition type of Composition::SOLID_COLOR (because it
- * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
- * synchronization and buffer updates for these layers are handled
- * elsewhere).
- *
- * @param layer is the layer to which the buffer is set.
- * @param bufferSlot is the buffer slot to use.
- * @param bufferIndex is the buffer handle to set.
- * @param acquireFenceIndex is a sync fence file descriptor as described above.
- */
- SET_LAYER_BUFFER = 0x301 << OPCODE_SHIFT,
-
- /*
- * SET_LAYER_SURFACE_DAMAGE has this pseudo prototype
- *
- * setLayerSurfaceDamage(Rect[] damage);
- *
- * Provides the region of the source buffer which has been modified since
- * the last frame. This region does not need to be validated before
- * calling presentDisplay.
- *
- * Once set through this function, the damage region remains the same
- * until a subsequent call to this function.
- *
- * If damage is non-empty, then it may be assumed that any portion of the
- * source buffer not covered by one of the rects has not been modified
- * this frame. If damage is empty, then the whole source buffer must be
- * treated as if it has been modified.
- *
- * If the layer's contents are not modified relative to the prior frame,
- * damage must contain exactly one empty rect([0, 0, 0, 0]).
- *
- * The damage rects are relative to the pre-transformed buffer, and their
- * origin is the top-left corner. They must not exceed the dimensions of
- * the latched buffer.
- *
- * @param layer is the layer to which the damage region is set.
- * @param damage is the new surface damage region.
- */
- SET_LAYER_SURFACE_DAMAGE = 0x302 << OPCODE_SHIFT,
-
- // layer state commands (VALIDATE_DISPLAY required)
-
- /**
- * SET_LAYER_BLEND_MODE has this pseudo prototype
- *
- * setLayerBlendMode(android.hardware.graphics.common.BlendMode mode)
- *
- * Sets the blend mode of the given layer.
- *
- * @param mode is the new blend mode.
- */
- SET_LAYER_BLEND_MODE = 0x400 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_COLOR has this pseudo prototype
- *
- * setLayerColor(Color color);
- *
- * Sets the color of the given layer. If the composition type of the layer
- * is not Composition::SOLID_COLOR, this call must succeed and have no
- * other effect.
- *
- * @param color is the new color.
- */
- SET_LAYER_COLOR = 0x401 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_COMPOSITION_TYPE has this pseudo prototype
- *
- * setLayerCompositionType(Composition type);
- *
- * Sets the desired composition type of the given layer. During
- * validateDisplay, the device may request changes to the composition
- * types of any of the layers as described in the definition of
- * Composition above.
- *
- * @param type is the new composition type.
- */
- SET_LAYER_COMPOSITION_TYPE = 0x402 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_DATASPACE has this pseudo prototype
- *
- * setLayerDataspace(android.hardware.graphics.common.Dataspace dataspace);
- *
- * Sets the dataspace of the layer.
- *
- * The dataspace provides more information about how to interpret the buffer
- * or solid color, such as the encoding standard and color transform.
- *
- * See the values of Dataspace for more information.
- *
- * @param dataspace is the new dataspace.
- */
- SET_LAYER_DATASPACE = 0x403 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_DISPLAY_FRAME has this pseudo prototype
- *
- * setLayerDisplayFrame(Rect frame);
- *
- * Sets the display frame (the portion of the display covered by a layer)
- * of the given layer. This frame must not exceed the display dimensions.
- *
- * @param frame is the new display frame.
- */
- SET_LAYER_DISPLAY_FRAME = 0x404 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_PLANE_ALPHA has this pseudo prototype
- *
- * setLayerPlaneAlpha(float alpha);
- *
- * Sets an alpha value (a floating point value in the range [0.0, 1.0])
- * which will be applied to the whole layer. It can be conceptualized as a
- * preprocessing step which applies the following function:
- * if (blendMode == BlendMode::PREMULTIPLIED)
- * out.rgb = in.rgb * planeAlpha
- * out.a = in.a * planeAlpha
- *
- * If the device does not support this operation on a layer which is
- * marked Composition::DEVICE, it must request a composition type change
- * to Composition::CLIENT upon the next validateDisplay call.
- *
- * @param alpha is the plane alpha value to apply.
- */
- SET_LAYER_PLANE_ALPHA = 0x405 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_SIDEBAND_STREAM has this pseudo prototype
- *
- * setLayerSidebandStream(int streamIndex)
- *
- * Sets the sideband stream for this layer. If the composition type of the
- * given layer is not Composition::SIDEBAND, this call must succeed and
- * have no other effect.
- *
- * @param streamIndex is the new sideband stream.
- */
- SET_LAYER_SIDEBAND_STREAM = 0x406 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_SOURCE_CROP has this pseudo prototype
- *
- * setLayerSourceCrop(FRect crop);
- *
- * Sets the source crop (the portion of the source buffer which will fill
- * the display frame) of the given layer. This crop rectangle must not
- * exceed the dimensions of the latched buffer.
- *
- * If the device is not capable of supporting a true float source crop
- * (i.e., it will truncate or round the floats to integers), it must set
- * this layer to Composition::CLIENT when crop is non-integral for the
- * most accurate rendering.
- *
- * If the device cannot support float source crops, but still wants to
- * handle the layer, it must use the following code (or similar) to
- * convert to an integer crop:
- * intCrop.left = (int) ceilf(crop.left);
- * intCrop.top = (int) ceilf(crop.top);
- * intCrop.right = (int) floorf(crop.right);
- * intCrop.bottom = (int) floorf(crop.bottom);
- *
- * @param crop is the new source crop.
- */
- SET_LAYER_SOURCE_CROP = 0x407 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_TRANSFORM has this pseudo prototype
- *
- * Sets the transform (rotation/flip) of the given layer.
- *
- * setLayerTransform(Transform transform);
- *
- * @param transform is the new transform.
- */
- SET_LAYER_TRANSFORM = 0x408 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_VISIBLE_REGION has this pseudo prototype
- *
- * setLayerVisibleRegion(Rect[] visible);
- *
- * Specifies the portion of the layer that is visible, including portions
- * under translucent areas of other layers. The region is in screen space,
- * and must not exceed the dimensions of the screen.
- *
- * @param visible is the new visible region, in screen space.
- */
- SET_LAYER_VISIBLE_REGION = 0x409 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_Z_ORDER has this pseudo prototype
- *
- * setLayerZOrder(int z);
- *
- * Sets the desired Z order (height) of the given layer. A layer with a
- * greater Z value occludes a layer with a lesser Z value.
- *
- * @param z is the new Z order.
- */
- SET_LAYER_Z_ORDER = 0x40a << OPCODE_SHIFT,
-
- /**
- * SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT has this pseudo prototype
- *
- * setPresentOrValidateDisplayResult(int state);
- *
- * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
- * @param state is the state of present or validate
- * 1 - Present Succeeded
- * 0 - Validate succeeded
- */
- SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 0x40b << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_PER_FRAME_METADATA has this pseudo prototype
- *
- * setLayerPerFrameMetadata(long display, long layer,
- * PerFrameMetadata[] data);
- *
- * Sets the PerFrameMetadata for the display. This metadata must be used
- * by the implementation to better tone map content to that display.
- *
- * This is a method that may be called every frame. Thus it's
- * implemented using buffered transport.
- * SET_LAYER_PER_FRAME_METADATA is the command used by the buffered transport
- * mechanism.
- */
- SET_LAYER_PER_FRAME_METADATA = 0x303 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_FLOAT_COLOR has this pseudo prototype
- *
- * setLayerColor(FloatColor color);
- *
- * Sets the color of the given layer. If the composition type of the layer
- * is not Composition::SOLID_COLOR, this call must succeed and have no
- * other effect.
- *
- * @param color is the new color using float type.
- */
- SET_LAYER_FLOAT_COLOR = 0x40c << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
- *
- * setLayerColorTransform(float[16] matrix);
- *
- * This command has the following binary layout in bytes:
- *
- * 0 - 16 * 4: matrix
- *
- * Sets a matrix for color transform which will be applied on this layer
- * before composition.
- *
- * If the device is not capable of apply the matrix on this layer, it must force
- * this layer to client composition during VALIDATE_DISPLAY.
- *
- * The matrix provided is an affine color transformation of the following
- * form:
- *
- * |r.r r.g r.b 0|
- * |g.r g.g g.b 0|
- * |b.r b.g b.b 0|
- * |Tr Tg Tb 1|
- *
- * This matrix must be provided in row-major form:
- *
- * {r.r, r.g, r.b, 0, g.r, ...}.
- *
- * Given a matrix of this form and an input color [R_in, G_in, B_in],
- * the input color must first be converted to linear space
- * [R_linear, G_linear, B_linear], then the output linear color
- * [R_out_linear, G_out_linear, B_out_linear] will be:
- *
- * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
- * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
- * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
- *
- * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
- * gamma space: [R_out, G_out, B_out] before blending.
- *
- * @param matrix is a 4x4 transform matrix (16 floats) as described above.
- */
-
- SET_LAYER_COLOR_TRANSFORM = 0x40d << OPCODE_SHIFT,
- /*
- * SET_LAYER_PER_FRAME_METADATA_BLOBS has this pseudo prototype
- *
- * setLayerPerFrameMetadataBlobs(long display, long layer,
- * PerFrameMetadataBlob[] metadata);
- *
- * This command sends metadata that may be used for tone-mapping the
- * associated layer. The metadata structure follows a {key, blob}
- * format (see the PerFrameMetadataBlob struct). All keys must be
- * returned by a prior call to getPerFrameMetadataKeys and must
- * be part of the list of keys associated with blob-type metadata
- * (see PerFrameMetadataKey).
- *
- * This method may be called every frame.
- */
- SET_LAYER_PER_FRAME_METADATA_BLOBS = 0x304 << OPCODE_SHIFT,
-
- /**
- * SET_CLIENT_TARGET_PROPERTY has this pseudo prototype
- *
- * This command has the following binary layout in bytes:
- *
- * 0 - 3: clientTargetProperty.pixelFormat
- * 4 - 7: clientTargetProperty.dataspace
- * 8 - 11: whitePointNits
- *
- * The white point parameter describes the intended white point of the client target buffer.
- * When client composition blends both HDR and SDR content, the client must composite to the
- * brightness space as specified by the hardware composer. This is so that adjusting the real
- * display brightness may be applied atomically with compensating the client target output. For
- * instance, client-compositing a list of SDR layers requires dimming the brightness space of
- * the SDR buffers when an HDR layer is simultaneously device-composited.
- *
- * setClientTargetProperty(ClientTargetProperty clientTargetProperty, float whitePointNits);
- */
- SET_CLIENT_TARGET_PROPERTY = 0x105 << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_GENERIC_METADATA has this pseudo prototype
- *
- * setLayerGenericMetadata(string key, bool mandatory, byte[] value);
- *
- * Sets a piece of generic metadata for the given layer. If this
- * function is called twice with the same key but different values, the
- * newer value must override the older one. Calling this function with a
- * 0-length value must reset that key's metadata as if it had not been
- * set.
- *
- * A given piece of metadata may either be mandatory or a hint
- * (non-mandatory) as indicated by the second parameter. Mandatory
- * metadata may affect the composition result, which is to say that it
- * may cause a visible change in the final image. By contrast, hints may
- * only affect the composition strategy, such as which layers are
- * composited by the client, but must not cause a visible change in the
- * final image. The value of the mandatory flag shall match the value
- * returned from getLayerGenericMetadataKeys for the given key.
- *
- * Only keys which have been returned from getLayerGenericMetadataKeys()
- * shall be accepted. Any other keys must result in an UNSUPPORTED error.
- *
- * The value passed into this function shall be the binary
- * representation of a HIDL type corresponding to the given key. For
- * example, a key of 'com.example.V1_3.Foo' shall be paired with a
- * value of type com.example@1.3::Foo, which would be defined in a
- * vendor HAL extension.
- *
- * This function will be encoded in the command buffer in this order:
- * 1) The key length, stored as a uint32_t
- * 2) The key itself, padded to a uint32_t boundary if necessary
- * 3) The mandatory flag, stored as a uint32_t
- * 4) The value length in bytes, stored as a uint32_t
- * 5) The value itself, padded to a uint32_t boundary if necessary
- *
- * @param key indicates which metadata value should be set on this layer
- * @param mandatory indicates whether this particular key represents
- * mandatory metadata or a hint (non-mandatory metadata), as
- * described above
- * @param value is a binary representation of a HIDL struct
- * corresponding to the key as described above
- */
- SET_LAYER_GENERIC_METADATA = 0x40e << OPCODE_SHIFT,
-
- /**
- * SET_LAYER_WHITE_POINT_NITS has this pseudo prototype
- *
- * setLayerWhitePointNits(float sdrWhitePointNits);
- *
- * Sets the desired white point for the layer. This is intended to be used when presenting
- * an SDR layer alongside HDR content. The HDR content will be presented at the display
- * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
- * provided.
- *
- * @param whitePointNits is the white point in nits.
- */
- SET_LAYER_WHITE_POINT_NITS = 0x305 << OPCODE_SHIFT,
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
deleted file mode 100644
index 4b3d31a..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright (c) 2021, 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.graphics.composer3;
-
-/**
- * Display requests returned by getDisplayRequests.
- */
-@VintfStability
-@Backing(type="int")
-enum DisplayRequest {
- /**
- * Instructs the client to provide a new client target buffer, even if
- * no layers are marked for client composition.
- */
- FLIP_CLIENT_TARGET = 1 << 0,
- /**
- * Instructs the client to write the result of client composition
- * directly into the virtual display output buffer. If any of the
- * layers are not marked as Composition::CLIENT or the given display
- * is not a virtual display, this request has no effect.
- */
- WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1,
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 230980d..f661f8b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -16,11 +16,8 @@
package android.hardware.graphics.composer3;
-import android.hardware.common.fmq.MQDescriptor;
-import android.hardware.common.fmq.SynchronizedReadWrite;
import android.hardware.graphics.composer3.ClientTargetProperty;
import android.hardware.graphics.composer3.ColorMode;
-import android.hardware.graphics.composer3.Command;
import android.hardware.graphics.composer3.ContentType;
import android.hardware.graphics.composer3.DisplayAttribute;
import android.hardware.graphics.composer3.DisplayCapability;
@@ -28,7 +25,6 @@
import android.hardware.graphics.composer3.DisplayContentSample;
import android.hardware.graphics.composer3.DisplayContentSamplingAttributes;
import android.hardware.graphics.composer3.DisplayIdentification;
-import android.hardware.graphics.composer3.ExecuteCommandsStatus;
import android.hardware.graphics.composer3.FormatColorComponent;
import android.hardware.graphics.composer3.HdrCapabilities;
import android.hardware.graphics.composer3.IComposerCallback;
@@ -40,6 +36,8 @@
import android.hardware.graphics.composer3.VirtualDisplay;
import android.hardware.graphics.composer3.VsyncPeriodChangeConstraints;
import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
+import android.hardware.graphics.composer3.command.CommandPayload;
+import android.hardware.graphics.composer3.command.CommandResultPayload;
@VintfStability
interface IComposerClient {
@@ -159,23 +157,13 @@
void destroyVirtualDisplay(long display);
/**
- * Executes commands from the input command message queue. Return values
- * generated by the input commands are written to the output command
- * message queue in the form of value commands.
+ * Executes commands.
*
- * @param inLength is the length of input commands.
- * @param inHandles is an array of handles referenced by the input
- * commands.
+ * @param commands are the commands to be processed.
*
- * @return is the status of the command.
-
- * @exception EX_BAD_PARAMETER when inLength is not equal to the length of
- * commands in the input command message queue.
- * @exception NO_RESOURCES when the output command message queue was not
- * properly drained.
+ * @return are the command statuses.
*/
- ExecuteCommandsStatus executeCommands(
- int inLength, in android.hardware.common.NativeHandle[] inHandles);
+ CommandResultPayload[] executeCommands(in CommandPayload[] commands);
/**
* Retrieves which display configuration is currently active.
@@ -436,17 +424,6 @@
int getMaxVirtualDisplayCount();
/**
- * Gets the output command message queue.
- *
- * This function must only be called inside executeCommands closure.
- *
- * @return is the descriptor of the output command queue.
- *
- * @exception EX_NO_RESOURCES when failed to get the queue temporarily.
- */
- MQDescriptor<int, SynchronizedReadWrite> getOutputCommandQueue();
-
- /**
* Returns the PerFrameMetadataKeys that are supported by this device.
*
* @param display is the display on which to create the layer.
@@ -732,14 +709,6 @@
long display, boolean enable, FormatColorComponent componentMask, long maxFrames);
/**
- * Sets the input command message queue.
- *
- * @param descriptor is the descriptor of the input command message queue.
- * @exception EX_NO_RESOURCES when failed to set the queue temporarily.
- */
- void setInputCommandQueue(in MQDescriptor<int, SynchronizedReadWrite> descriptor);
-
- /**
* Sets the power mode of the given display. The transition must be
* complete when this function returns. It is valid to call this function
* multiple times with the same power mode.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
index b666e6a..3962920 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
@@ -16,8 +16,6 @@
package android.hardware.graphics.composer3;
-import android.hardware.graphics.composer3.PerFrameMetadataKey;
-
/**
* PerFrameMetadataKey
*
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl
new file mode 100644
index 0000000..3a08d3b
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+import android.hardware.common.NativeHandle;
+
+@VintfStability
+parcelable Buffer {
+ /**
+ * Buffer slot in the range [0, bufferSlotCount) where bufferSlotCount is
+ * the parameter used when the layer was created.
+ * @see IComposer.createLayer.
+ * The slot is used as a buffer caching mechanism. When the Buffer.handle
+ * is null, the implementation uses the previous buffer associated with this
+ * slot.
+ */
+ int slot;
+
+ /**
+ * Buffer Handle. Can be null if this is the same buffer that was sent
+ * previously on this slot.
+ */
+ @nullable NativeHandle handle;
+
+ /**
+ * Buffer fence that represents when it is safe to access the buffer.
+ * A null fence indicates that the buffer can be accessed immediately.
+ */
+ @nullable ParcelFileDescriptor fence;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
new file mode 100644
index 0000000..3800eff
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.Composition;
+
+@VintfStability
+parcelable ChangedCompositionTypes {
+ /**
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
+ */
+ long display;
+
+ @VintfStability
+ parcelable Layer {
+ /**
+ * The layer which this commands refers to.
+ * @see IComposer.createLayer
+ */
+ long layer;
+
+ /**
+ * The new composition type.
+ */
+ Composition composition;
+ }
+
+ /**
+ * Indicates which layers has composition changes
+ */
+ Layer[] layers;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
similarity index 60%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
index f67c3ce..d8d45a1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
@@ -14,23 +14,26 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Output parameters for IComposerClient.executeCommands
- */
+import android.hardware.graphics.common.Dataspace;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.command.Buffer;
+
@VintfStability
-parcelable ExecuteCommandsStatus {
+parcelable ClientTarget {
/**
- * Indicates whether the output command message queue has changed.
+ * Client target Buffer
*/
- boolean queueChanged;
+ Buffer buffer;
+
/**
- * Indicates whether the output command message queue has changed.
+ * The dataspace of the buffer, as described in LayerCommand.dataspace.
*/
- int length;
+ Dataspace dataspace;
+
/**
- * An array of handles referenced by the output commands.
+ * The surface damage regions.
*/
- android.hardware.common.NativeHandle[] handles;
+ Rect[] damage;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
new file mode 100644
index 0000000..c80e4ce
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.ClientTargetProperty;
+
+@VintfStability
+parcelable ClientTargetPropertyWithNits {
+ /**
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
+ */
+ long display;
+
+ /**
+ * The Client target property.
+ */
+ ClientTargetProperty clientTargetProperty;
+
+ /**
+ * The white points nits as described in CommandResultPayload.clientTargetProperty
+ */
+ float whitePointNits;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
similarity index 63%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
index c6fd063..9cc8fa7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
@@ -14,25 +14,20 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.common.ColorTransform;
+
@VintfStability
-@Backing(type="int")
-enum BlendMode {
- INVALID = 0,
+parcelable ColorTransformPayload {
/**
- * colorOut = colorSrc
+ * 4x4 transform matrix (16 floats) as described in DisplayCommand.colorTransform.
*/
- NONE = 1,
+ float[] matrix;
+
/**
- * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+ * Hint value which may be used instead of the given matrix unless it
+ * is ColorTransform::ARBITRARY.
*/
- PREMULTIPLIED = 2,
- /**
- * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
- */
- COVERAGE = 3,
+ ColorTransform hint;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
index 10de558..c1555e6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
@@ -14,18 +14,17 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.DisplayCommand;
+import android.hardware.graphics.composer3.command.LayerCommand;
/**
- * Layer requests returned from getDisplayRequests.
+ * Type of commands that can be used in IComposerClient.executeCommands.
+ * Note that this is a union and each command can only have one type.
*/
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
- /**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
- */
- CLEAR_CLIENT_TARGET = 1 << 0,
+union CommandPayload {
+ DisplayCommand displayCommand;
+ LayerCommand layerCommand;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
new file mode 100644
index 0000000..b6086ca
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.ChangedCompositionTypes;
+import android.hardware.graphics.composer3.command.ClientTargetPropertyWithNits;
+import android.hardware.graphics.composer3.command.DisplayRequest;
+import android.hardware.graphics.composer3.command.Error;
+import android.hardware.graphics.composer3.command.PresentFence;
+import android.hardware.graphics.composer3.command.PresentOrValidate;
+import android.hardware.graphics.composer3.command.ReleaseFences;
+
+@VintfStability
+union CommandResultPayload {
+ /**
+ * Indicates an error generated by a command.
+ */
+ Error error;
+
+ /**
+ * Sets the layers for which the device requires a different composition
+ * type than had been set prior to the last call to VALIDATE_DISPLAY. The
+ * client must either update its state with these types and call
+ * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
+ * the display again.
+ */
+ ChangedCompositionTypes changedCompositionType;
+
+ /**
+ * Sets the display requests and the layer requests required for the last
+ * validated configuration.
+ *
+ * Display requests provide information about how the client must handle
+ * the client target. Layer requests provide information about how the
+ * client must handle an individual layer.
+ */
+ DisplayRequest displayRequest;
+
+ /**
+ * Sets the present fence as a result of PRESENT_DISPLAY. For physical
+ * displays, this fence must be signaled at the vsync when the result
+ * of composition of this frame starts to appear (for video-mode panels)
+ * or starts to transfer to panel memory (for command-mode panels). For
+ * virtual displays, this fence must be signaled when writes to the output
+ * buffer have completed and it is safe to read from it.
+ */
+ PresentFence presentFence;
+
+ /**
+ * Sets the release fences for device layers on this display which will
+ * receive new buffer contents this frame.
+ *
+ * A release fence is a file descriptor referring to a sync fence object
+ * which must be signaled after the device has finished reading from the
+ * buffer presented in the prior frame. This indicates that it is safe to
+ * start writing to the buffer again. If a given layer's fence is not
+ * returned from this function, it must be assumed that the buffer
+ * presented on the previous frame is ready to be written.
+ *
+ * The fences returned by this function must be unique for each layer
+ * (even if they point to the same underlying sync object).
+ *
+ */
+ ReleaseFences releaseFences;
+
+ /**
+ * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
+ */
+ PresentOrValidate presentOrValidateResult;
+
+ /**
+ * The white point parameter describes the intended white point of the client target buffer.
+ * When client composition blends both HDR and SDR content, the client must composite to the
+ * brightness space as specified by the hardware composer. This is so that adjusting the real
+ * display brightness may be applied atomically with compensating the client target output. For
+ * instance, client-compositing a list of SDR layers requires dimming the brightness space of
+ * the SDR buffers when an HDR layer is simultaneously device-composited.
+ */
+ ClientTargetPropertyWithNits clientTargetProperty;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl
new file mode 100644
index 0000000..7295ada
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.Buffer;
+import android.hardware.graphics.composer3.command.ClientTarget;
+import android.hardware.graphics.composer3.command.ColorTransformPayload;
+
+@VintfStability
+parcelable DisplayCommand {
+ /**
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
+ */
+ long display;
+
+ /**
+ * Sets a color transform which will be applied after composition.
+ *
+ * If hint is not ColorTransform::ARBITRARY, then the device may use the
+ * hint to apply the desired color transform instead of using the color
+ * matrix directly.
+ *
+ * If the device is not capable of either using the hint or the matrix to
+ * apply the desired color transform, it must force all layers to client
+ * composition during VALIDATE_DISPLAY.
+ *
+ * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
+ * the client must never apply the color transform during client
+ * composition, even if all layers are being composed by the client.
+ *
+ * The matrix provided is an affine color transformation of the following
+ * form:
+ *
+ * |r.r r.g r.b 0|
+ * |g.r g.g g.b 0|
+ * |b.r b.g b.b 0|
+ * |Tr Tg Tb 1|
+ *
+ * This matrix must be provided in row-major form:
+ *
+ * {r.r, r.g, r.b, 0, g.r, ...}.
+ *
+ * Given a matrix of this form and an input color [R_in, G_in, B_in], the
+ * output color [R_out, G_out, B_out] will be:
+ *
+ * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
+ * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
+ * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
+ *
+ */
+ @nullable ColorTransformPayload colorTransform;
+
+ /**
+ * Sets the buffer handle which will receive the output of client
+ * composition. Layers marked as Composition::CLIENT must be composited
+ * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
+ * marked as Composition::CLIENT must be composited with this buffer by
+ * the device.
+ *
+ * The buffer handle provided may be empty if no layers are being
+ * composited by the client. This must not result in an error (unless an
+ * invalid display handle is also provided).
+ *
+ * Also provides a file descriptor referring to an acquire sync fence
+ * object, which must be signaled when it is safe to read from the client
+ * target buffer. If it is already safe to read from this buffer, an
+ * empty handle may be passed instead.
+ *
+ * For more about dataspaces, see SET_LAYER_DATASPACE.
+ *
+ * The damage parameter describes a surface damage region as defined in
+ * the description of SET_LAYER_SURFACE_DAMAGE.
+ *
+ * Will be called before PRESENT_DISPLAY if any of the layers are marked
+ * as Composition::CLIENT. If no layers are so marked, then it is not
+ * necessary to call this function. It is not necessary to call
+ * validateDisplay after changing the target through this function.
+ */
+ @nullable ClientTarget clientTarget;
+
+ /**
+ * Sets the output buffer for a virtual display. That is, the buffer to
+ * which the composition result will be written.
+ *
+ * Also provides a file descriptor referring to a release sync fence
+ * object, which must be signaled when it is safe to write to the output
+ * buffer. If it is already safe to write to the output buffer, an empty
+ * handle may be passed instead.
+ *
+ * Must be called at least once before PRESENT_DISPLAY, but does not have
+ * any interaction with layer state or display validation.
+ */
+ @nullable Buffer virtualDisplayOutputBuffer;
+
+ /**
+ * Instructs the device to inspect all of the layer state and determine if
+ * there are any composition type changes necessary before presenting the
+ * display. Permitted changes are described in the definition of
+ * Composition above.
+ */
+ boolean validateDisplay;
+
+ /**
+ * Accepts the changes required by the device from the previous
+ * validateDisplay call (which may be queried using
+ * getChangedCompositionTypes) and revalidates the display. This function
+ * is equivalent to requesting the changed types from
+ * getChangedCompositionTypes, setting those types on the corresponding
+ * layers, and then calling validateDisplay again.
+ *
+ * After this call it must be valid to present this display. Calling this
+ * after validateDisplay returns 0 changes must succeed with NONE, but
+ * must have no other effect.
+ */
+ boolean acceptDisplayChanges;
+
+ /**
+ * Presents the current display contents on the screen (or in the case of
+ * virtual displays, into the output buffer).
+ *
+ * Prior to calling this function, the display must be successfully
+ * validated with validateDisplay. Note that setLayerBuffer and
+ * setLayerSurfaceDamage specifically do not count as layer state, so if
+ * there are no other changes to the layer state (or to the buffer's
+ * properties as described in setLayerBuffer), then it is safe to call
+ * this function without first validating the display.
+ */
+ boolean presentDisplay;
+
+ /**
+ * Presents the current display contents on the screen (or in the case of
+ * virtual displays, into the output buffer) if validate can be skipped,
+ * or perform a VALIDATE_DISPLAY action instead.
+ */
+ boolean presentOrValidateDisplay;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl
new file mode 100644
index 0000000..10bd10c
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+@VintfStability
+parcelable DisplayRequest {
+ /**
+ * Instructs the client to provide a new client target buffer, even if
+ * no layers are marked for client composition.
+ */
+ const int FLIP_CLIENT_TARGET = 1 << 0;
+
+ /**
+ * Instructs the client to write the result of client composition
+ * directly into the virtual display output buffer. If any of the
+ * layers are not marked as Composition::CLIENT or the given display
+ * is not a virtual display, this request has no effect.
+ */
+ const int WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1;
+
+ /**
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
+ */
+ long display;
+
+ /**
+ * The display requests for the current validated state. This must be a
+ * bitwise-or of the constants in `DisplayRequest`.
+ */
+ int mask;
+
+ @VintfStability
+ parcelable LayerRequest {
+ /**
+ * The client must clear its target with transparent pixels where
+ * this layer would be. The client may ignore this request if the
+ * layer must be blended.
+ */
+ const int CLEAR_CLIENT_TARGET = 1 << 0;
+
+ /**
+ * The layer which this commands refers to.
+ * @see IComposer.createLayer
+ */
+ long layer;
+ /**
+ * The layer requests for the current validated state. This must be a
+ * bitwise-or of the constants in `LayerRequest`.
+ */
+ int mask;
+ }
+
+ /**
+ * The layer requests for the current validated state.
+ */
+ LayerRequest[] layerRequests;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
index 10de558..19843b9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
@@ -14,18 +14,16 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable Error {
/**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
+ * The index in the command payload array.
*/
- CLEAR_CLIENT_TARGET = 1 << 0,
+ int commandIndex;
+ /**
+ * The error generated by the command. Can be one of the IComposerClient.EX_*
+ */
+ int errorCode;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
index c6fd063..a4e1fe8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
@@ -14,25 +14,20 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.composer3.LayerGenericMetadataKey;
+
@VintfStability
-@Backing(type="int")
-enum BlendMode {
- INVALID = 0,
+parcelable GenericMetadata {
/**
- * colorOut = colorSrc
+ * Indicates which metadata value should be set.
*/
- NONE = 1,
+ LayerGenericMetadataKey key;
/**
- * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+ * The binary representation of a AIDL struct corresponding to
+ * the key as described above.
+ * TODO(b/209691612): revisit the use of byte[]
*/
- PREMULTIPLIED = 2,
- /**
- * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
- */
- COVERAGE = 3,
+ byte[] value;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl
new file mode 100644
index 0000000..eac051b
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl
@@ -0,0 +1,301 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.graphics.common.FRect;
+import android.hardware.graphics.common.Point;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.Color;
+import android.hardware.graphics.composer3.FloatColor;
+import android.hardware.graphics.composer3.PerFrameMetadata;
+import android.hardware.graphics.composer3.PerFrameMetadataBlob;
+import android.hardware.graphics.composer3.command.Buffer;
+import android.hardware.graphics.composer3.command.GenericMetadata;
+import android.hardware.graphics.composer3.command.ParcelableBlendMode;
+import android.hardware.graphics.composer3.command.ParcelableComposition;
+import android.hardware.graphics.composer3.command.ParcelableDataspace;
+import android.hardware.graphics.composer3.command.ParcelableTransform;
+import android.hardware.graphics.composer3.command.PlaneAlpha;
+import android.hardware.graphics.composer3.command.WhitePointNits;
+import android.hardware.graphics.composer3.command.ZOrder;
+
+@VintfStability
+parcelable LayerCommand {
+ /**
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
+ */
+ long display;
+
+ /**
+ * The layer which this commands refers to.
+ * @see IComposer.createLayer
+ */
+ long layer;
+
+ /**
+ * Asynchronously sets the position of a cursor layer.
+ *
+ * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
+ * If validation succeeds (i.e., the device does not request a composition
+ * change for that layer), then once a buffer has been set for the layer
+ * and it has been presented, its position may be set by this function at
+ * any time between presentDisplay and any subsequent validateDisplay
+ * calls for this display.
+ *
+ * Once validateDisplay is called, this function must not be called again
+ * until the validate/present sequence is completed.
+ *
+ * May be called from any thread so long as it is not interleaved with the
+ * validate/present sequence as described above.
+ */
+ @nullable Point cursorPosition;
+
+ /**
+ * Sets the buffer handle to be displayed for this layer. If the buffer
+ * properties set at allocation time (width, height, format, and usage)
+ * have not changed since the previous frame, it is not necessary to call
+ * validateDisplay before calling presentDisplay unless new state needs to
+ * be validated in the interim.
+ *
+ * Also provides a file descriptor referring to an acquire sync fence
+ * object, which must be signaled when it is safe to read from the given
+ * buffer. If it is already safe to read from the buffer, an empty handle
+ * may be passed instead.
+ *
+ * This function must return NONE and have no other effect if called for a
+ * layer with a composition type of Composition::SOLID_COLOR (because it
+ * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
+ * synchronization and buffer updates for these layers are handled
+ * elsewhere).
+ */
+ @nullable Buffer buffer;
+
+ /**
+ * Provides the region of the source buffer which has been modified since
+ * the last frame. This region does not need to be validated before
+ * calling presentDisplay.
+ *
+ * Once set through this function, the damage region remains the same
+ * until a subsequent call to this function.
+ *
+ * If damage is non-empty, then it may be assumed that any portion of the
+ * source buffer not covered by one of the rects has not been modified
+ * this frame. If damage is empty, then the whole source buffer must be
+ * treated as if it has been modified.
+ *
+ * If the layer's contents are not modified relative to the prior frame,
+ * damage must contain exactly one empty rect([0, 0, 0, 0]).
+ *
+ * The damage rects are relative to the pre-transformed buffer, and their
+ * origin is the top-left corner. They must not exceed the dimensions of
+ * the latched buffer.
+ */
+ @nullable Rect[] damage;
+
+ /**
+ * Sets the blend mode of the given layer.
+ */
+ @nullable ParcelableBlendMode blendMode;
+
+ /**
+ * Sets the color of the given layer. If the composition type of the layer
+ * is not Composition::SOLID_COLOR, this call must succeed and have no
+ * other effect.
+ */
+ @nullable Color color;
+
+ /**
+ * Sets the color of the given layer. If the composition type of the layer
+ * is not Composition::SOLID_COLOR, this call must succeed and have no
+ * other effect.
+ */
+ @nullable FloatColor floatColor;
+
+ /**
+ * Sets the desired composition type of the given layer. During
+ * validateDisplay, the device may request changes to the composition
+ * types of any of the layers as described in the definition of
+ * Composition above.
+ */
+ @nullable ParcelableComposition composition;
+
+ /**
+ * Sets the dataspace of the layer.
+ *
+ * The dataspace provides more information about how to interpret the buffer
+ * or solid color, such as the encoding standard and color transform.
+ *
+ * See the values of ParcelableDataspace for more information.
+ */
+ @nullable ParcelableDataspace dataspace;
+
+ /**
+ * Sets the display frame (the portion of the display covered by a layer)
+ * of the given layer. This frame must not exceed the display dimensions.
+ */
+ @nullable Rect displayFrame;
+
+ /**
+ * Sets an alpha value (a floating point value in the range [0.0, 1.0])
+ * which will be applied to the whole layer. It can be conceptualized as a
+ * preprocessing step which applies the following function:
+ * if (blendMode == BlendMode::PREMULTIPLIED)
+ * out.rgb = in.rgb * planeAlpha
+ * out.a = in.a * planeAlpha
+ *
+ * If the device does not support this operation on a layer which is
+ * marked Composition::DEVICE, it must request a composition type change
+ * to Composition::CLIENT upon the next validateDisplay call.
+ *
+ */
+ @nullable PlaneAlpha planeAlpha;
+
+ /**
+ * Sets the sideband stream for this layer. If the composition type of the
+ * given layer is not Composition::SIDEBAND, this call must succeed and
+ * have no other effect.
+ */
+ @nullable NativeHandle sidebandStream;
+
+ /**
+ * Sets the source crop (the portion of the source buffer which will fill
+ * the display frame) of the given layer. This crop rectangle must not
+ * exceed the dimensions of the latched buffer.
+ *
+ * If the device is not capable of supporting a true float source crop
+ * (i.e., it will truncate or round the floats to integers), it must set
+ * this layer to Composition::CLIENT when crop is non-integral for the
+ * most accurate rendering.
+ *
+ * If the device cannot support float source crops, but still wants to
+ * handle the layer, it must use the following code (or similar) to
+ * convert to an integer crop:
+ * intCrop.left = (int) ceilf(crop.left);
+ * intCrop.top = (int) ceilf(crop.top);
+ * intCrop.right = (int) floorf(crop.right);
+ * intCrop.bottom = (int) floorf(crop.bottom);
+ */
+ @nullable FRect sourceCrop;
+
+ /**
+ * Sets the transform (rotation/flip) of the given layer.
+ */
+ @nullable ParcelableTransform transform;
+
+ /**
+ * Specifies the portion of the layer that is visible, including portions
+ * under translucent areas of other layers. The region is in screen space,
+ * and must not exceed the dimensions of the screen.
+ */
+ @nullable Rect[] visibleRegion;
+
+ /**
+ * Sets the desired Z order (height) of the given layer. A layer with a
+ * greater Z value occludes a layer with a lesser Z value.
+ */
+ @nullable ZOrder z;
+
+ /**
+ * Sets a matrix for color transform which will be applied on this layer
+ * before composition.
+ *
+ * If the device is not capable of apply the matrix on this layer, it must force
+ * this layer to client composition during VALIDATE_DISPLAY.
+ *
+ * The matrix provided is an affine color transformation of the following
+ * form:
+ *
+ * |r.r r.g r.b 0|
+ * |g.r g.g g.b 0|
+ * |b.r b.g b.b 0|
+ * |Tr Tg Tb 1|
+ *
+ * This matrix must be provided in row-major form:
+ *
+ * {r.r, r.g, r.b, 0, g.r, ...}.
+ *
+ * Given a matrix of this form and an input color [R_in, G_in, B_in],
+ * the input color must first be converted to linear space
+ * [R_linear, G_linear, B_linear], then the output linear color
+ * [R_out_linear, G_out_linear, B_out_linear] will be:
+ *
+ * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
+ * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
+ * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
+ *
+ * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
+ * gamma space: [R_out, G_out, B_out] before blending.
+ */
+ @nullable float[] colorTransform;
+
+ /**
+ * Sets the desired white point for the layer. This is intended to be used when presenting
+ * an SDR layer alongside HDR content. The HDR content will be presented at the display
+ * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+ * provided.
+ */
+ @nullable WhitePointNits whitePointNits;
+
+ /**
+ * Sets a piece of generic metadata for the given layer. If this
+ * function is called twice with the same key but different values, the
+ * newer value must override the older one. Calling this function with a
+ * 0-length value must reset that key's metadata as if it had not been
+ * set.
+ *
+ * A given piece of metadata may either be mandatory or a hint
+ * (non-mandatory) as indicated by the second parameter. Mandatory
+ * metadata may affect the composition result, which is to say that it
+ * may cause a visible change in the final image. By contrast, hints may
+ * only affect the composition strategy, such as which layers are
+ * composited by the client, but must not cause a visible change in the
+ * final image. The value of the mandatory flag shall match the value
+ * returned from getLayerGenericMetadataKeys for the given key.
+ *
+ * Only keys which have been returned from getLayerGenericMetadataKeys()
+ * shall be accepted. Any other keys must result in an UNSUPPORTED error.
+ *
+ * The value passed into this function shall be the binary
+ * representation of a stable AIDL type corresponding to the given key. For
+ * example, a key of 'com.example.Foo-V2' shall be paired with a
+ * value of type com.exampleFoo-V2, which would be defined in a
+ * vendor HAL extension.
+ */
+ @nullable GenericMetadata genericMetadata;
+
+ /**
+ * Sets the PerFrameMetadata for the display. This metadata must be used
+ * by the implementation to better tone map content to that display.
+ *
+ * This is a command that may be called every frame.
+ */
+ @nullable PerFrameMetadata[] perFrameMetadata;
+
+ /**
+ * This command sends metadata that may be used for tone-mapping the
+ * associated layer. The metadata structure follows a {key, blob}
+ * format (see the PerFrameMetadataBlob struct). All keys must be
+ * returned by a prior call to getPerFrameMetadataKeys and must
+ * be part of the list of keys associated with blob-type metadata
+ * (see PerFrameMetadataKey).
+ *
+ * This command may be called every frame.
+ */
+ @nullable PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
index 10de558..f912853 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
@@ -14,18 +14,11 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.BlendMode;
+
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
- /**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
- */
- CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableBlendMode {
+ BlendMode blendMode;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
index 10de558..91979d8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
@@ -14,18 +14,11 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.composer3.Composition;
+
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
- /**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
- */
- CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableComposition {
+ Composition composition;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
index 10de558..6be750d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
@@ -14,18 +14,11 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.Dataspace;
+
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
- /**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
- */
- CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableDataspace {
+ Dataspace dataspace;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
index 10de558..910d014 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
@@ -14,18 +14,11 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.Transform;
+
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
- /**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
- */
- CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableTransform {
+ Transform transform;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
index 10de558..fa1889b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
@@ -14,18 +14,14 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PlaneAlpha {
/**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
+ * An alpha value (a floating point value in the range [0.0, 1.0])
+ * which will be applied to a whole layer.
+ * @see LayerCommand.planeAlpha
*/
- CLEAR_CLIENT_TARGET = 1 << 0,
+ float alpha;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
index 10de558..0c14406 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PresentFence {
/**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
*/
- CLEAR_CLIENT_TARGET = 1 << 0,
+ long display;
+
+ /**
+ * The present fence for this display.
+ */
+ ParcelFileDescriptor fence;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
similarity index 64%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
index 10de558..7fc60c4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
@@ -14,18 +14,19 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PresentOrValidate {
/**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
*/
- CLEAR_CLIENT_TARGET = 1 << 0,
+ long display;
+
+ /**
+ * Whether PresentOrValidate presented or validated the display.
+ */
+ @VintfStability enum Result { Presented, Validated }
+ Result result;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl
new file mode 100644
index 0000000..762f5eb
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+@VintfStability
+parcelable ReleaseFences {
+ /**
+ * The display which this commands refers to.
+ * @see IComposer.createDisplay
+ */
+ long display;
+ @VintfStability
+ parcelable Layer {
+ /**
+ * The layer which this commands refers to.
+ * @see IComposer.createLayer
+ */
+ long layer;
+
+ /**
+ * The release fence for this layer.
+ */
+ ParcelFileDescriptor fence;
+ }
+
+ /**
+ * The layers which has release fences.
+ */
+ Layer[] layers;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl
new file mode 100644
index 0000000..ec46cdf
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2021, 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.graphics.composer3.command;
+
+@VintfStability
+parcelable WhitePointNits {
+ /**
+ * The desired white point for the layer. This is intended to be used when presenting
+ * an SDR layer alongside HDR content. The HDR content will be presented at the display
+ * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+ * provided.
+ * @see LayerCommand.whitePointNits.
+ */
+ float nits;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
index 10de558..68120b0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
@@ -14,18 +14,14 @@
* limitations under the License.
*/
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
-/**
- * Layer requests returned from getDisplayRequests.
- */
@VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable ZOrder {
/**
- * The client must clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
+ * The desired Z order (height) of the given layer. A layer with a
+ * greater Z value occludes a layer with a lesser Z value.
+ * @see LayerCommand.z;
*/
- CLEAR_CLIENT_TARGET = 1 << 0,
+ int z;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
index d59190d..5bda15a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
@@ -74,25 +74,25 @@
static_assert(aidl::android::hardware::graphics::composer3::Capability::SKIP_VALIDATE ==
static_cast<aidl::android::hardware::graphics::composer3::Capability>(4));
-static_assert(aidl::android::hardware::graphics::composer3::LayerRequest::CLEAR_CLIENT_TARGET ==
- static_cast<aidl::android::hardware::graphics::composer3::LayerRequest>(
- ::android::hardware::graphics::composer::V2_1::IComposerClient::LayerRequest::
- CLEAR_CLIENT_TARGET));
+static_assert(aidl::android::hardware::graphics::composer3::command::DisplayRequest::LayerRequest::
+ CLEAR_CLIENT_TARGET ==
+ static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+ LayerRequest::CLEAR_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::INVALID ==
- static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::INVALID ==
+ static_cast<aidl::android::hardware::graphics::common::BlendMode>(
::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
INVALID));
static_assert(
- aidl::android::hardware::graphics::composer3::BlendMode::NONE ==
- static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+ aidl::android::hardware::graphics::common::BlendMode::NONE ==
+ static_cast<aidl::android::hardware::graphics::common::BlendMode>(
::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::NONE));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::PREMULTIPLIED ==
- static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::PREMULTIPLIED ==
+ static_cast<aidl::android::hardware::graphics::common::BlendMode>(
::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
PREMULTIPLIED));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::COVERAGE ==
- static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::COVERAGE ==
+ static_cast<aidl::android::hardware::graphics::common::BlendMode>(
::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
COVERAGE));
@@ -121,15 +121,14 @@
::android::hardware::graphics::composer::V2_1::IComposerClient::Composition::
SIDEBAND));
-static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::FLIP_CLIENT_TARGET ==
- static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
- ::android::hardware::graphics::composer::V2_1::IComposerClient::
- DisplayRequest::FLIP_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::
+static_assert(
+ aidl::android::hardware::graphics::composer3::command::DisplayRequest::FLIP_CLIENT_TARGET ==
+ static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+ DisplayRequest::FLIP_CLIENT_TARGET));
+static_assert(aidl::android::hardware::graphics::composer3::command::DisplayRequest::
WRITE_CLIENT_TARGET_TO_OUTPUT ==
- static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
- ::android::hardware::graphics::composer::V2_1::IComposerClient::
- DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
+ static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+ DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
static_assert(aidl::android::hardware::graphics::composer3::HandleIndex::EMPTY ==
static_cast<aidl::android::hardware::graphics::composer3::HandleIndex>(
@@ -188,162 +187,6 @@
::android::hardware::graphics::composer::V2_4::IComposerClient::DisplayCapability::
AUTO_LOW_LATENCY_MODE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::LENGTH_MASK ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- LENGTH_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_SHIFT ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- OPCODE_SHIFT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_MASK ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- OPCODE_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_DISPLAY ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SELECT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_LAYER ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SELECT_LAYER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_ERROR ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_ERROR));
-static_assert(
- aidl::android::hardware::graphics::composer3::Command::SET_CHANGED_COMPOSITION_TYPES ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_CHANGED_COMPOSITION_TYPES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_DISPLAY_REQUESTS ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_DISPLAY_REQUESTS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_PRESENT_FENCE ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_PRESENT_FENCE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_RELEASE_FENCES ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_RELEASE_FENCES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_COLOR_TRANSFORM ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_COLOR_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_OUTPUT_BUFFER ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_OUTPUT_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::VALIDATE_DISPLAY ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::ACCEPT_DISPLAY_CHANGES ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- ACCEPT_DISPLAY_CHANGES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_DISPLAY ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- PRESENT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_OR_VALIDATE_DISPLAY ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- PRESENT_OR_VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_CURSOR_POSITION ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_CURSOR_POSITION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BUFFER ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SURFACE_DAMAGE ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_SURFACE_DAMAGE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BLEND_MODE ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_BLEND_MODE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COMPOSITION_TYPE ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_COMPOSITION_TYPE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DATASPACE ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_DATASPACE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DISPLAY_FRAME ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_DISPLAY_FRAME));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PLANE_ALPHA ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_PLANE_ALPHA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SIDEBAND_STREAM ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_SIDEBAND_STREAM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SOURCE_CROP ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_SOURCE_CROP));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_TRANSFORM ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_VISIBLE_REGION ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_VISIBLE_REGION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_Z_ORDER ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_Z_ORDER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::
- SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_PER_FRAME_METADATA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_FLOAT_COLOR ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_FLOAT_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR_TRANSFORM ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_COLOR_TRANSFORM));
-static_assert(
- aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_PER_FRAME_METADATA_BLOBS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET_PROPERTY ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_CLIENT_TARGET_PROPERTY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_GENERIC_METADATA ==
- static_cast<aidl::android::hardware::graphics::composer3::Command>(
- ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
- SET_LAYER_GENERIC_METADATA));
-
static_assert(aidl::android::hardware::graphics::composer3::DisplayAttribute::INVALID ==
static_cast<aidl::android::hardware::graphics::composer3::DisplayAttribute>(
::android::hardware::graphics::composer::V2_4::IComposerClient::Attribute::
@@ -612,4 +455,4 @@
return true;
}
-} // namespace android::h2a
\ No newline at end of file
+} // namespace android::h2a
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index 9bf8609..741572d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -35,7 +35,6 @@
"VtsHalGraphicsComposer3_TargetTest.cpp",
"VtsHalGraphicsComposer3_ReadbackTest.cpp",
"composer-vts/GraphicsComposerCallback.cpp",
- "composer-vts/TestCommandReader.cpp",
],
shared_libs: [
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 6f83b90..717b60c 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -28,7 +28,6 @@
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include "composer-vts/include/GraphicsComposerCallback.h"
-#include "composer-vts/include/TestCommandReader.h"
namespace aidl::android::hardware::graphics::composer3::vts {
namespace {
@@ -51,6 +50,8 @@
// assume the first display is primary and is never removed
mPrimaryDisplay = waitForFirstDisplay();
+ ASSERT_NO_FATAL_FAILURE(mInvalidDisplayId = GetInvalidDisplayId());
+
int32_t activeConfig;
EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &activeConfig).isOk());
EXPECT_TRUE(mComposerClient
@@ -68,9 +69,7 @@
EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false).isOk());
mComposerCallback->setVsyncAllowed(false);
- // set up command writer/reader and gralloc
- mWriter = std::make_shared<CommandWriterBase>(1024);
- mReader = std::make_unique<TestCommandReader>();
+ // set up gralloc
mGraphicBuffer = allocate();
ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
@@ -102,8 +101,15 @@
void TearDown() override {
ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
- EXPECT_EQ(0, mReader->mErrors.size());
- EXPECT_EQ(0, mReader->mCompositionChanges.size());
+ const auto errors = mReader.takeErrors();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ std::vector<int64_t> layers;
+ std::vector<Composition> types;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+ ASSERT_TRUE(layers.empty());
+ ASSERT_TRUE(types.empty());
if (mComposerCallback != nullptr) {
EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
@@ -120,11 +126,6 @@
"VtsHalGraphicsComposer3_ReadbackTest");
}
- void clearCommandReaderState() {
- mReader->mCompositionChanges.clear();
- mReader->mErrors.clear();
- }
-
void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
for (auto layer : layers) {
layer->write(mWriter);
@@ -133,31 +134,27 @@
}
void execute() {
- TestCommandReader* reader = mReader.get();
- CommandWriterBase* writer = mWriter.get();
- bool queueChanged = false;
- int32_t commandLength = 0;
- std::vector<NativeHandle> commandHandles;
- ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
- if (queueChanged) {
- auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
- ASSERT_TRUE(ret.isOk());
+ const auto& commands = mWriter.getPendingCommands();
+ if (commands.empty()) {
+ mWriter.reset();
+ return;
}
- ExecuteCommandsStatus commandStatus;
- EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
- .isOk());
+ std::vector<command::CommandResultPayload> results;
+ const auto status = mComposerClient->executeCommands(commands, &results);
+ ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
- if (commandStatus.queueChanged) {
- MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
- ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
- reader->setMQDescriptor(outputCommandQueue);
- }
- ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
- reader->parse();
- reader->reset();
- writer->reset();
+ mReader.parse(results);
+ mWriter.reset();
+ }
+
+ bool getHasReadbackBuffer() {
+ ReadbackBufferAttributes readBackBufferAttributes;
+ const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
+ &readBackBufferAttributes);
+ mPixelFormat = readBackBufferAttributes.format;
+ mDataspace = readBackBufferAttributes.dataspace;
+ return error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
}
std::shared_ptr<IComposer> mComposer;
@@ -166,15 +163,15 @@
std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
// the first display and is assumed never to be removed
int64_t mPrimaryDisplay;
+ int64_t mInvalidDisplayId;
int32_t mDisplayWidth;
int32_t mDisplayHeight;
std::vector<ColorMode> mTestColorModes;
- std::shared_ptr<CommandWriterBase> mWriter;
- std::unique_ptr<TestCommandReader> mReader;
+ CommandWriterBase mWriter;
+ CommandReaderBase mReader;
::android::sp<::android::GraphicBuffer> mGraphicBuffer;
std::unique_ptr<TestRenderEngine> mTestRenderEngine;
- bool mHasReadbackBuffer;
common::PixelFormat mPixelFormat;
common::Dataspace mDataspace;
@@ -204,6 +201,27 @@
}
}
}
+
+ // returns an invalid display id (one that has not been registered to a
+ // display. Currently assuming that a device will never have close to
+ // std::numeric_limit<uint64_t>::max() displays registered while running tests
+ int64_t GetInvalidDisplayId() {
+ int64_t id = std::numeric_limits<int64_t>::max();
+ std::vector<int64_t> displays = mComposerCallback->getDisplays();
+ while (id > 0) {
+ if (std::none_of(displays.begin(), displays.end(),
+ [&](const auto& display) { return id == display; })) {
+ return id;
+ }
+ id--;
+ }
+
+ // Although 0 could be an invalid display, a return value of 0
+ // from GetInvalidDisplayId means all other ids are in use, a condition which
+ // we are assuming a device will never have
+ EXPECT_NE(0, id);
+ return id;
+ }
};
class GraphicsCompositionTest : public GraphicsCompositionTestBase,
@@ -214,20 +232,10 @@
TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -249,20 +257,23 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
// if hwc cannot handle and asks for composition change,
// just succeed the test
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(layers);
@@ -273,26 +284,14 @@
TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
-
ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
@@ -317,21 +316,24 @@
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->presentDisplay();
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(layers);
@@ -342,20 +344,10 @@
TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -375,7 +367,7 @@
mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
static_cast<uint32_t>(mDisplayHeight), 1,
static_cast<uint32_t>(common::PixelFormat::RGBA_8888), usage);
- mWriter->setLayerBuffer(0, mGraphicBuffer->handle, -1);
+ mWriter.setLayerBuffer(mPrimaryDisplay, layer->getLayer(), 0, mGraphicBuffer->handle, -1);
// expected color for each pixel
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -385,48 +377,97 @@
mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- mWriter->validateDisplay();
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
}
+TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadDisplay) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ ASSERT_NE(nullptr, mGraphicBuffer);
+ ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+ aidl::android::hardware::common::NativeHandle bufferHandle =
+ ::android::dupToAidl(mGraphicBuffer->handle);
+ ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
+
+ const auto error = mComposerClient->setReadbackBuffer(mInvalidDisplayId, bufferHandle, fence);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadParameter) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ aidl::android::hardware::common::NativeHandle bufferHandle = ::android::dupToAidl(nullptr);
+ ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
+ const auto error =
+ mComposerClient->setReadbackBuffer(mPrimaryDisplay, bufferHandle, releaseFence);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ ndk::ScopedFileDescriptor releaseFence;
+ const auto error = mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &releaseFence);
+
+ EXPECT_TRUE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+}
+
TEST_P(GraphicsCompositionTest, ClientComposition) {
EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount)
.isOk());
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
EXPECT_TRUE(mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)
.isOk());
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
-
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
{0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
@@ -450,13 +491,18 @@
mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (!mReader->mCompositionChanges.empty()) {
- ASSERT_EQ(1, mReader->mCompositionChanges.size());
- ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
+ ASSERT_EQ(1, changedCompositionLayers.size());
+ ASSERT_EQ(1, changedCompositionTypes.size());
+ ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
PixelFormat clientFormat = PixelFormat::RGBA_8888;
auto clientUsage = static_cast<uint32_t>(
@@ -487,18 +533,20 @@
mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
layer->setToClientComposition(mWriter);
- mWriter->acceptDisplayChanges();
- mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
- std::vector<common::Rect>(1, damage));
+ mWriter.acceptDisplayChanges(mPrimaryDisplay);
+ mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+ clientDataspace, std::vector<common::Rect>(1, damage));
execute();
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ ASSERT_TRUE(changedCompositionLayers.empty());
}
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->presentDisplay();
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
@@ -509,20 +557,10 @@
mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -568,15 +606,18 @@
clientLayer->setDisplayFrame(clientFrame);
clientLayer->setZOrder(0);
clientLayer->write(mWriter);
- mWriter->validateDisplay();
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 1) {
- mReader->mCompositionChanges.clear();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (changedCompositionTypes.size() != 1) {
continue;
}
// create client target buffer
- ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+ ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
static_cast<uint32_t>(mDisplayHeight),
static_cast<int32_t>(common::PixelFormat::RGBA_8888),
@@ -597,42 +638,32 @@
EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
clientLayer->setToClientComposition(mWriter);
- mWriter->acceptDisplayChanges();
- mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
- std::vector<common::Rect>(1, clientFrame));
+ mWriter.acceptDisplayChanges(mPrimaryDisplay);
+ mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+ clientDataspace, std::vector<common::Rect>(1, clientFrame));
execute();
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
- ASSERT_EQ(0, mReader->mErrors.size());
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ ASSERT_EQ(0, changedCompositionLayers.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->presentDisplay();
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
}
TEST_P(GraphicsCompositionTest, SetLayerDamage) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
-
common::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -653,18 +684,21 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -680,14 +714,17 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ ASSERT_TRUE(changedCompositionLayers.empty());
+ ASSERT_TRUE(changedCompositionTypes.empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
@@ -695,20 +732,10 @@
TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -728,19 +755,22 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->presentDisplay();
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -753,26 +783,14 @@
TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
-
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
{0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
@@ -800,18 +818,21 @@
mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -821,20 +842,10 @@
TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -865,17 +876,20 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- mWriter->presentDisplay();
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -887,14 +901,17 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ ASSERT_TRUE(changedCompositionLayers.empty());
+ ASSERT_TRUE(changedCompositionTypes.empty());
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(layers);
@@ -990,26 +1007,14 @@
TEST_P(GraphicsBlendModeCompositionTest, None) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
-
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
setBackgroundColor(BLACK);
@@ -1021,18 +1026,21 @@
mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(mLayers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(mLayers);
@@ -1043,26 +1051,14 @@
TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
-
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
setBackgroundColor(BLACK);
@@ -1075,42 +1071,34 @@
mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(mLayers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
}
TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -1123,18 +1111,21 @@
mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(mLayers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(mLayers);
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1146,7 +1137,7 @@
protected:
void SetUp() override {
GraphicsCompositionTest::SetUp();
- mWriter->selectDisplay(mPrimaryDisplay);
+
auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
backgroundLayer->setColor({0, 0, 0, 0});
backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
@@ -1177,8 +1168,6 @@
TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
for (ColorMode mode : mTestColorModes) {
- ASSERT_NE(nullptr, mWriter);
- mWriter->selectDisplay(mPrimaryDisplay);
auto error =
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC);
if (!error.isOk() &&
@@ -1188,16 +1177,7 @@
return;
}
- ReadbackBufferAttributes readBackBufferAttributes;
- error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -1214,18 +1194,21 @@
{0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
writeLayers(mLayers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(mLayers);
@@ -1236,20 +1219,10 @@
TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -1267,18 +1240,21 @@
{mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
writeLayers(mLayers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
+ std::vector<int64_t> changedCompositionLayers;
+ std::vector<Composition> changedCompositionTypes;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+ &changedCompositionTypes);
+ if (!changedCompositionLayers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(mLayers);
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1288,19 +1264,10 @@
TEST_P(GraphicsTransformCompositionTest, ROT_180) {
for (ColorMode mode : mTestColorModes) {
- mWriter->selectDisplay(mPrimaryDisplay);
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
- ReadbackBufferAttributes readBackBufferAttributes;
- const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
- &readBackBufferAttributes);
-
- mPixelFormat = readBackBufferAttributes.format;
- mDataspace = readBackBufferAttributes.dataspace;
- mHasReadbackBuffer =
- error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
- if (!mHasReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
return;
}
@@ -1319,18 +1286,20 @@
{0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
writeLayers(mLayers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (!mReader->mCompositionChanges.empty()) {
- clearCommandReaderState();
+ std::vector<int64_t> layers;
+ std::vector<Composition> types;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+ if (!layers.empty()) {
GTEST_SUCCEED();
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
mTestRenderEngine->setRenderLayers(mLayers);
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1357,4 +1326,4 @@
::android::PrintInstanceNameToString);
} // namespace
-} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index b9460c8..7a20a53 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -4,10 +4,10 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
#include <aidl/android/hardware/graphics/common/FRect.h>
#include <aidl/android/hardware/graphics/common/Rect.h>
-#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/IComposer.h>
#include <android-base/properties.h>
@@ -27,7 +27,6 @@
#include <unordered_set>
#include <utility>
#include "composer-vts/include/GraphicsComposerCallback.h"
-#include "composer-vts/include/TestCommandReader.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion
@@ -1148,45 +1147,33 @@
// Tests for Command.
class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
protected:
- void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::SetUp());
-
- mWriter = std::make_unique<CommandWriterBase>(1024);
- mReader = std::make_unique<TestCommandReader>();
- }
-
void TearDown() override {
- ASSERT_EQ(0, mReader->mErrors.size());
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ const auto errors = mReader.takeErrors();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ std::vector<int64_t> layers;
+ std::vector<Composition> types;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+ ASSERT_TRUE(layers.empty());
+ ASSERT_TRUE(types.empty());
+
ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
}
void execute() {
- TestCommandReader* reader = mReader.get();
- CommandWriterBase* writer = mWriter.get();
- bool queueChanged = false;
- int32_t commandLength = 0;
- std::vector<NativeHandle> commandHandles;
- ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
- if (queueChanged) {
- auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
- ASSERT_TRUE(ret.isOk());
+ const auto& commands = mWriter.getPendingCommands();
+ if (commands.empty()) {
+ mWriter.reset();
+ return;
}
- ExecuteCommandsStatus commandStatus;
- EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
- .isOk());
+ std::vector<command::CommandResultPayload> results;
+ const auto status = mComposerClient->executeCommands(commands, &results);
+ ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
- if (commandStatus.queueChanged) {
- MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
- ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
- reader->setMQDescriptor(outputCommandQueue);
- }
- ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
- reader->parse();
- reader->reset();
- writer->reset();
+ mReader.parse(results);
+ mWriter.reset();
}
static inline auto toTimePoint(nsecs_t time) {
@@ -1255,7 +1242,6 @@
std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
}
- mWriter->selectDisplay(display.get());
EXPECT_TRUE(mComposerClient->setPowerMode(display.get(), PowerMode::ON).isOk());
EXPECT_TRUE(
mComposerClient
@@ -1270,42 +1256,41 @@
ASSERT_EQ(::android::OK, buffer->initCheck());
ASSERT_NE(nullptr, buffer->handle);
- mWriter->selectLayer(layer);
- mWriter->setLayerCompositionType(Composition::DEVICE);
- mWriter->setLayerDisplayFrame(display.getFrameRect());
- mWriter->setLayerPlaneAlpha(1);
- mWriter->setLayerSourceCrop(display.getCrop());
- mWriter->setLayerTransform(static_cast<Transform>(0));
- mWriter->setLayerVisibleRegion(std::vector<Rect>(1, display.getFrameRect()));
- mWriter->setLayerZOrder(10);
- mWriter->setLayerBlendMode(BlendMode::NONE);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, display.getFrameRect()));
- mWriter->setLayerBuffer(0, buffer->handle, -1);
- mWriter->setLayerDataspace(common::Dataspace::UNKNOWN);
+ mWriter.setLayerCompositionType(display.get(), layer, Composition::DEVICE);
+ mWriter.setLayerDisplayFrame(display.get(), layer, display.getFrameRect());
+ mWriter.setLayerPlaneAlpha(display.get(), layer, 1);
+ mWriter.setLayerSourceCrop(display.get(), layer, display.getCrop());
+ mWriter.setLayerTransform(display.get(), layer, static_cast<Transform>(0));
+ mWriter.setLayerVisibleRegion(display.get(), layer,
+ std::vector<Rect>(1, display.getFrameRect()));
+ mWriter.setLayerZOrder(display.get(), layer, 10);
+ mWriter.setLayerBlendMode(display.get(), layer, BlendMode::NONE);
+ mWriter.setLayerSurfaceDamage(display.get(), layer,
+ std::vector<Rect>(1, display.getFrameRect()));
+ mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+ mWriter.setLayerDataspace(display.get(), layer, common::Dataspace::UNKNOWN);
- mWriter->validateDisplay();
+ mWriter.validateDisplay(display.get());
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- mReader->mCompositionChanges.clear();
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->presentDisplay();
+ mWriter.presentDisplay(display.get());
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
{
auto buffer = allocate();
ASSERT_NE(nullptr, buffer->handle);
- mWriter->selectLayer(layer);
- mWriter->setLayerBuffer(0, buffer->handle, -1);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
- mWriter->validateDisplay();
+ mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+ mWriter.setLayerSurfaceDamage(display.get(), layer,
+ std::vector<Rect>(1, {0, 0, 10, 10}));
+ mWriter.validateDisplay(display.get());
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- mReader->mCompositionChanges.clear();
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->presentDisplay();
+ mWriter.presentDisplay(display.get());
execute();
}
@@ -1411,26 +1396,23 @@
}};
// clang-format on
- std::unique_ptr<CommandWriterBase> mWriter;
- std::unique_ptr<TestCommandReader> mReader;
+ CommandWriterBase mWriter;
+ CommandReaderBase mReader;
};
TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) {
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->setColorTransform(kIdentity.data(), ColorTransform::IDENTITY);
+ mWriter.setColorTransform(mPrimaryDisplay, kIdentity.data(), ColorTransform::IDENTITY);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerColorTransform(kIdentity.data());
+ mWriter.setLayerColorTransform(mPrimaryDisplay, layer, kIdentity.data());
execute();
- if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
- mReader->mErrors.clear();
+ const auto errors = mReader.takeErrors();
+ if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
GTEST_SUCCEED() << "setLayerColorTransform is not supported";
return;
}
@@ -1440,8 +1422,8 @@
EXPECT_TRUE(
mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN, std::vector<Rect>());
+ mWriter.setClientTarget(mPrimaryDisplay, 0, nullptr, -1, Dataspace::UNKNOWN,
+ std::vector<Rect>());
execute();
}
@@ -1460,30 +1442,26 @@
kBufferSlotCount, &display)
.isOk());
- mWriter->selectDisplay(display.display);
auto handle = allocate()->handle;
- mWriter->setOutputBuffer(0, handle, -1);
+ mWriter.setOutputBuffer(display.display, 0, handle, -1);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, VALIDATE_DISPLAY) {
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->validateDisplay();
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->validateDisplay();
- mWriter->acceptDisplayChanges();
+ mWriter.validateDisplay(mPrimaryDisplay);
+ mWriter.acceptDisplayChanges(mPrimaryDisplay);
execute();
}
// TODO(b/208441745) fix the test failure
TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY) {
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->validateDisplay();
- mWriter->presentDisplay();
+ mWriter.validateDisplay(mPrimaryDisplay);
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
}
@@ -1503,7 +1481,6 @@
GTEST_SUCCEED() << "Device does not have skip validate capability, skipping";
return;
}
- mWriter->selectDisplay(mPrimaryDisplay);
mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
std::vector<RenderIntent> renderIntents;
@@ -1518,37 +1495,39 @@
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectLayer(layer);
- mWriter->setLayerCompositionType(Composition::DEVICE);
- mWriter->setLayerDisplayFrame(displayFrame);
- mWriter->setLayerPlaneAlpha(1);
- mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
- mWriter->setLayerTransform(static_cast<Transform>(0));
- mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
- mWriter->setLayerZOrder(10);
- mWriter->setLayerBlendMode(BlendMode::NONE);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
- mWriter->setLayerBuffer(0, handle, -1);
- mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+ mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+ mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+ mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+ mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+ {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+ mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+ mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+ mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+ mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+ mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+ mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
- mWriter->validateDisplay();
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
+ std::vector<int64_t> layers;
+ std::vector<Composition> types;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+ if (!layers.empty()) {
GTEST_SUCCEED() << "Composition change requested, skipping test";
return;
}
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
- ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->selectLayer(layer);
auto handle2 = allocate()->handle;
ASSERT_NE(nullptr, handle2);
- mWriter->setLayerBuffer(0, handle2, -1);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
- mWriter->presentDisplay();
+ mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle2, -1);
+ mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, {0, 0, 10, 10}));
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
}
}
@@ -1562,33 +1541,37 @@
ASSERT_NE(nullptr, handle);
Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerBuffer(0, handle, -1);
- mWriter->setLayerCompositionType(Composition::CURSOR);
- mWriter->setLayerDisplayFrame(displayFrame);
- mWriter->setLayerPlaneAlpha(1);
- mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
- mWriter->setLayerTransform(static_cast<Transform>(0));
- mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
- mWriter->setLayerZOrder(10);
- mWriter->setLayerBlendMode(BlendMode::NONE);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
- mWriter->setLayerDataspace(Dataspace::UNKNOWN);
- mWriter->validateDisplay();
+ mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+ mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+ mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+ mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+ mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+ {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+ mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+ mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+ mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+ mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+ mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
+ mWriter.validateDisplay(mPrimaryDisplay);
execute();
- if (mReader->mCompositionChanges.size() != 0) {
+ std::vector<int64_t> layers;
+ std::vector<Composition> types;
+ mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+ if (!layers.empty()) {
GTEST_SUCCEED() << "Composition change requested, skipping test";
return;
}
- mWriter->presentDisplay();
- ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter.presentDisplay(mPrimaryDisplay);
+ ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter->setLayerCursorPosition(1, 1);
- mWriter->setLayerCursorPosition(0, 0);
- mWriter->validateDisplay();
- mWriter->presentDisplay();
+ mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 1, 1);
+ execute();
+
+ mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 0, 0);
+ mWriter.validateDisplay(mPrimaryDisplay);
+ mWriter.presentDisplay(mPrimaryDisplay);
execute();
}
@@ -1598,10 +1581,7 @@
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
-
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerBuffer(0, handle, -1);
+ mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
execute();
}
@@ -1612,58 +1592,77 @@
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, empty));
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, unit));
- mWriter->setLayerSurfaceDamage(std::vector<Rect>());
+ mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>());
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) {
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerBlendMode(BlendMode::NONE);
- mWriter->setLayerBlendMode(BlendMode::PREMULTIPLIED);
- mWriter->setLayerBlendMode(BlendMode::COVERAGE);
+ mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::PREMULTIPLIED);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::COVERAGE);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COLOR) {
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerColor(Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
- static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
- mWriter->setLayerColor(Color{0, 0, 0, 0});
+ mWriter.setLayerColor(mPrimaryDisplay, layer,
+ Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
+ static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0, 0, 0, 0});
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COMPOSITION_TYPE) {
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerCompositionType(Composition::CLIENT);
- mWriter->setLayerCompositionType(Composition::DEVICE);
- mWriter->setLayerCompositionType(Composition::SOLID_COLOR);
- mWriter->setLayerCompositionType(Composition::CURSOR);
+ mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CLIENT);
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::SOLID_COLOR);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_DATASPACE) {
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+ mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
execute();
}
@@ -1671,9 +1670,7 @@
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerDisplayFrame(Rect{0, 0, 1, 1});
+ mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, Rect{0, 0, 1, 1});
execute();
}
@@ -1681,11 +1678,13 @@
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerPlaneAlpha(0.0f);
- mWriter->setLayerPlaneAlpha(1.0f);
+ mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 0.0f);
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1.0f);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SIDEBAND_STREAM) {
@@ -1703,9 +1702,7 @@
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerSidebandStream(handle);
+ mWriter.setLayerSidebandStream(mPrimaryDisplay, layer, handle);
execute();
}
@@ -1713,9 +1710,7 @@
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerSourceCrop(FRect{0.0f, 0.0f, 1.0f, 1.0f});
+ mWriter.setLayerSourceCrop(mPrimaryDisplay, layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
execute();
}
@@ -1723,19 +1718,41 @@
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerTransform(static_cast<Transform>(0));
- mWriter->setLayerTransform(Transform::FLIP_H);
- mWriter->setLayerTransform(Transform::FLIP_V);
- mWriter->setLayerTransform(Transform::ROT_90);
- mWriter->setLayerTransform(Transform::ROT_180);
- mWriter->setLayerTransform(Transform::ROT_270);
- mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
- static_cast<int>(Transform::ROT_90)));
- mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
- static_cast<int>(Transform::ROT_90)));
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_H);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_V);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_90);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_180);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_270);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerTransform(mPrimaryDisplay, layer,
+ static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
+ static_cast<int>(Transform::ROT_90)));
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerTransform(mPrimaryDisplay, layer,
+ static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
+ static_cast<int>(Transform::ROT_90)));
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_VISIBLE_REGION) {
@@ -1745,32 +1762,36 @@
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerVisibleRegion(std::vector<Rect>(1, empty));
- mWriter->setLayerVisibleRegion(std::vector<Rect>(1, unit));
- mWriter->setLayerVisibleRegion(std::vector<Rect>());
+ mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>());
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_Z_ORDER) {
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
- mWriter->setLayerZOrder(10);
- mWriter->setLayerZOrder(0);
+ mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mWriter.setLayerZOrder(mPrimaryDisplay, layer, 0);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
int64_t layer;
EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
- mWriter->selectDisplay(mPrimaryDisplay);
- mWriter->selectLayer(layer);
-
/**
* DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
* the D65 white point and the SRGB transfer functions.
@@ -1796,11 +1817,11 @@
aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
- mWriter->setLayerPerFrameMetadata(aidlMetadata);
+ mWriter.setLayerPerFrameMetadata(mPrimaryDisplay, layer, aidlMetadata);
execute();
- if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
- mReader->mErrors.clear();
+ const auto errors = mReader.takeErrors();
+ if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
return;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
index 2b058c7..df038db 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
@@ -28,7 +28,6 @@
defaults: ["hidl_defaults"],
srcs: [
"GraphicsComposerCallback.cpp",
- "TestCommandReader.cpp",
"ReadbackVts.cpp",
"RenderEngineVts.cpp",
],
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
index b612309..a6954b4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
@@ -32,15 +32,14 @@
const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
common::Dataspace::DISPLAY_P3};
-void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
- writer->selectLayer(mLayer);
- writer->setLayerDisplayFrame(mDisplayFrame);
- writer->setLayerSourceCrop(mSourceCrop);
- writer->setLayerZOrder(mZOrder);
- writer->setLayerSurfaceDamage(mSurfaceDamage);
- writer->setLayerTransform(mTransform);
- writer->setLayerPlaneAlpha(mAlpha);
- writer->setLayerBlendMode(mBlendMode);
+void TestLayer::write(CommandWriterBase& writer) {
+ writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
+ writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
+ writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
+ writer.setLayerSurfaceDamage(mDisplay, mLayer, mSurfaceDamage);
+ writer.setLayerTransform(mDisplay, mLayer, mTransform);
+ writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha);
+ writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
}
std::string ReadbackHelper::getColorModeString(ColorMode mode) {
@@ -254,10 +253,10 @@
EXPECT_EQ(::android::OK, status);
}
-void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+void TestColorLayer::write(CommandWriterBase& writer) {
TestLayer::write(writer);
- writer->setLayerCompositionType(Composition::SOLID_COLOR);
- writer->setLayerColor(mColor);
+ writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
+ writer.setLayerColor(mDisplay, mLayer, mColor);
}
LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
@@ -297,12 +296,12 @@
setSourceCrop({0, 0, (float)width, (float)height});
}
-void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+void TestBufferLayer::write(CommandWriterBase& writer) {
TestLayer::write(writer);
- writer->setLayerCompositionType(mComposition);
- writer->setLayerVisibleRegion(std::vector<Rect>(1, mDisplayFrame));
+ writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
+ writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
if (mGraphicBuffer->handle != nullptr)
- writer->setLayerBuffer(0, mGraphicBuffer->handle, mFillFence);
+ writer.setLayerBuffer(mDisplay, mLayer, 0, mGraphicBuffer->handle, mFillFence);
}
LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
@@ -346,15 +345,12 @@
ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
}
-void TestBufferLayer::setDataspace(common::Dataspace dataspace,
- const std::shared_ptr<CommandWriterBase>& writer) {
- writer->selectLayer(mLayer);
- writer->setLayerDataspace(dataspace);
+void TestBufferLayer::setDataspace(common::Dataspace dataspace, CommandWriterBase& writer) {
+ writer.setLayerDataspace(mDisplay, mLayer, dataspace);
}
-void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
- writer->selectLayer(mLayer);
- writer->setLayerCompositionType(Composition::CLIENT);
+void TestBufferLayer::setToClientComposition(CommandWriterBase& writer) {
+ writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
}
-} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
index e83750e..50ce462 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
@@ -86,4 +86,4 @@
ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
}
-} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
deleted file mode 100644
index a5a84d9..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (c) 2021, 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.
- */
-
-#include "include/TestCommandReader.h"
-#include <gtest/gtest.h>
-
-namespace aidl::android::hardware::graphics::composer3::vts {
-
-void TestCommandReader::parse() {
- mErrors.clear();
- mCompositionChanges.clear();
- while (!isEmpty()) {
- int32_t command;
- uint16_t length;
- ASSERT_TRUE(beginCommand(&command, &length));
-
- parseSingleCommand(command, length);
-
- endCommand();
- }
-}
-
-void TestCommandReader::parseSingleCommand(int32_t commandRaw, uint16_t length) {
- auto command = static_cast<Command>(commandRaw);
-
- switch (command) {
- case Command::SET_CLIENT_TARGET_PROPERTY: {
- ASSERT_EQ(2, length);
- read();
- close(readFence());
- } break;
- case Command::SELECT_DISPLAY: {
- ASSERT_EQ(2, length);
- read64(); // display
- } break;
- case Command::SET_ERROR: {
- ASSERT_EQ(2, length);
- auto loc = read();
- auto err = readSigned();
- std::pair<uint32_t, uint32_t> error(loc, err);
- mErrors.push_back(error);
- } break;
- case Command::SET_CHANGED_COMPOSITION_TYPES: {
- ASSERT_EQ(0, length % 3);
- for (uint16_t count = 0; count < length / 3; ++count) {
- uint64_t layerId = read64();
- uint32_t composition = read();
-
- std::pair<uint64_t, uint32_t> compositionChange(layerId, composition);
- mCompositionChanges.push_back(compositionChange);
- }
- } break;
- case Command::SET_DISPLAY_REQUESTS: {
- ASSERT_EQ(1, length % 3);
- read(); // displayRequests, ignored for now
- for (uint16_t count = 0; count < (length - 1) / 3; ++count) {
- read64(); // layer
- // silently eat requests to clear the client target, since we won't be testing
- // client composition anyway
- ASSERT_EQ(1u, read());
- }
- } break;
- case Command::SET_PRESENT_FENCE: {
- ASSERT_EQ(1, length);
- close(readFence());
- } break;
- case Command::SET_RELEASE_FENCES: {
- ASSERT_EQ(0, length % 3);
- for (uint16_t count = 0; count < length / 3; ++count) {
- read64();
- close(readFence());
- }
- } break;
- default:
- GTEST_FAIL() << "unexpected return command " << std::hex << static_cast<int>(command);
- break;
- }
-}
-} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
index 85b4fdc..d40e3d2 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
@@ -21,7 +21,6 @@
#pragma clang diagnostic ignored "-Wconversion"
#include <GraphicsComposerCallback.h>
-#include <TestCommandReader.h>
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer3/command-buffer.h>
@@ -54,7 +53,7 @@
class TestLayer {
public:
TestLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
- : mComposerClient(client) {
+ : mDisplay(display), mComposerClient(client) {
client->createLayer(display, kBufferSlotCount, &mLayer);
}
@@ -62,7 +61,7 @@
// call destroyLayers here
virtual ~TestLayer(){};
- virtual void write(const std::shared_ptr<CommandWriterBase>& writer);
+ virtual void write(CommandWriterBase& writer);
virtual LayerSettings toRenderEngineLayerSettings();
void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
@@ -83,7 +82,10 @@
float getAlpha() const { return mAlpha; }
+ int64_t getLayer() const { return mLayer; }
+
protected:
+ int64_t mDisplay;
int64_t mLayer;
Rect mDisplayFrame = {0, 0, 0, 0};
std::vector<Rect> mSurfaceDamage;
@@ -103,7 +105,7 @@
TestColorLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
: TestLayer{client, display} {}
- void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+ void write(CommandWriterBase& writer) override;
LayerSettings toRenderEngineLayerSettings() override;
@@ -121,7 +123,7 @@
uint32_t height, common::PixelFormat format,
Composition composition = Composition::DEVICE);
- void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+ void write(CommandWriterBase& writer) override;
LayerSettings toRenderEngineLayerSettings() override;
@@ -129,9 +131,9 @@
void setBuffer(std::vector<Color> colors);
- void setDataspace(Dataspace dataspace, const std::shared_ptr<CommandWriterBase>& writer);
+ void setDataspace(Dataspace dataspace, CommandWriterBase& writer);
- void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer);
+ void setToClientComposition(CommandWriterBase& writer);
uint32_t getWidth() const { return mWidth; }
@@ -211,4 +213,4 @@
native_handle_t mBufferHandle;
};
-} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
index eaff6d7..2798e09 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
@@ -68,4 +68,4 @@
DisplaySettings mDisplaySettings;
};
-} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
deleted file mode 100644
index 852a56e..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Copyright (c) 2021, 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.
- */
-#pragma once
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <android/hardware/graphics/composer3/command-buffer.h>
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion
-
-namespace aidl::android::hardware::graphics::composer3::vts {
-
-class TestCommandReader : public CommandReaderBase {
- public:
- virtual ~TestCommandReader() = default;
-
- std::vector<std::pair<uint32_t, uint32_t>> mErrors;
- std::vector<std::pair<uint64_t, uint32_t>> mCompositionChanges;
-
- // Parse all commands in the return command queue. Call GTEST_FAIL() for
- // unexpected errors or commands.
- void parse();
- virtual void parseSingleCommand(int32_t commandRaw, uint16_t length);
-};
-} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
index d02cf9c..b586e7f 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
@@ -19,15 +19,16 @@
#include <algorithm>
#include <limits>
#include <memory>
+#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include <inttypes.h>
#include <string.h>
-#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
#include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
#include <aidl/android/hardware/graphics/composer3/Color.h>
-#include <aidl/android/hardware/graphics/composer3/Command.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/FloatColor.h>
#include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
@@ -36,39 +37,29 @@
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
+#include <aidl/android/hardware/graphics/composer3/command/CommandPayload.h>
+#include <aidl/android/hardware/graphics/composer3/command/CommandResultPayload.h>
+
#include <aidl/android/hardware/graphics/common/ColorTransform.h>
#include <aidl/android/hardware/graphics/common/FRect.h>
#include <aidl/android/hardware/graphics/common/Rect.h>
#include <aidl/android/hardware/graphics/common/Transform.h>
-#include <fmq/AidlMessageQueue.h>
#include <log/log.h>
#include <sync/sync.h>
#include <aidlcommonsupport/NativeHandle.h>
+using aidl::android::hardware::graphics::common::BlendMode;
using aidl::android::hardware::graphics::common::ColorTransform;
using aidl::android::hardware::graphics::common::Dataspace;
using aidl::android::hardware::graphics::common::FRect;
using aidl::android::hardware::graphics::common::Rect;
using aidl::android::hardware::graphics::common::Transform;
-using aidl::android::hardware::graphics::composer3::BlendMode;
-using aidl::android::hardware::graphics::composer3::ClientTargetProperty;
-using aidl::android::hardware::graphics::composer3::Color;
-using aidl::android::hardware::graphics::composer3::Command;
-using aidl::android::hardware::graphics::composer3::Composition;
-using aidl::android::hardware::graphics::composer3::FloatColor;
-using aidl::android::hardware::graphics::composer3::HandleIndex;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadata;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob;
+using namespace aidl::android::hardware::graphics::composer3;
using aidl::android::hardware::common::NativeHandle;
-using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
-using android::AidlMessageQueue;
-using CommandQueueType = AidlMessageQueue<int32_t, SynchronizedReadWrite>;
-using aidl::android::hardware::common::fmq::MQDescriptor;
-using DescriptorType = MQDescriptor<int32_t, SynchronizedReadWrite>;
namespace aidl::android::hardware::graphics::composer3 {
@@ -76,820 +67,552 @@
// units of uint32_t's.
class CommandWriterBase {
public:
- CommandWriterBase(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
- mData = std::make_unique<int32_t[]>(mDataMaxSize);
- reset();
- }
+ CommandWriterBase() { reset(); }
virtual ~CommandWriterBase() { reset(); }
void reset() {
- mDataWritten = 0;
- mCommandEnd = 0;
-
- // handles in mDataHandles are owned by the caller
- mDataHandles.clear();
-
- // handles in mTemporaryHandles are owned by the writer
- for (auto handle : mTemporaryHandles) {
- native_handle_close(handle);
- native_handle_delete(handle);
- }
- mTemporaryHandles.clear();
+ mDisplayCommand.reset();
+ mLayerCommand.reset();
+ mCommands.clear();
+ mCommandsResults.clear();
}
- Command getCommand(uint32_t offset) {
- uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
- return static_cast<Command>(val & static_cast<uint32_t>(Command::OPCODE_MASK));
+ void setError(int32_t index, int32_t errorCode) {
+ command::Error error;
+ error.commandIndex = index;
+ error.errorCode = errorCode;
+ mCommandsResults.emplace_back(std::move(error));
}
- bool writeQueue(bool* outQueueChanged, int32_t* outCommandLength,
- std::vector<NativeHandle>* outCommandHandles) {
- if (mDataWritten == 0) {
- *outQueueChanged = false;
- *outCommandLength = 0;
- outCommandHandles->clear();
- return true;
- }
-
- // After data are written to the queue, it may not be read by the
- // remote reader when
- //
- // - the writer does not send them (because of other errors)
- // - the hwbinder transaction fails
- // - the reader does not read them (because of other errors)
- //
- // Discard the stale data here.
- size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
- if (staleDataSize > 0) {
- ALOGW("discarding stale data from message queue");
- CommandQueueType::MemTransaction tx;
- if (mQueue->beginRead(staleDataSize, &tx)) {
- mQueue->commitRead(staleDataSize);
- }
- }
-
- // write data to queue, optionally resizing it
- if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
- if (!mQueue->write(mData.get(), mDataWritten)) {
- ALOGE("failed to write commands to message queue");
- return false;
- }
-
- *outQueueChanged = false;
- } else {
- auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
- if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) {
- ALOGE("failed to prepare a new message queue ");
- return false;
- }
-
- mQueue = std::move(newQueue);
- *outQueueChanged = true;
- }
-
- *outCommandLength = mDataWritten;
- *outCommandHandles = std::move(mDataHandles);
-
- return true;
+ void setPresentOrValidateResult(int64_t display, command::PresentOrValidate::Result result) {
+ command::PresentOrValidate presentOrValidate;
+ presentOrValidate.display = display;
+ presentOrValidate.result = result;
+ mCommandsResults.emplace_back(std::move(presentOrValidate));
}
- DescriptorType getMQDescriptor() const {
- return (mQueue) ? mQueue->dupeDesc() : DescriptorType{};
- }
-
- static constexpr uint16_t kSelectDisplayLength = 2;
- void selectDisplay(int64_t display) {
- beginCommand(Command::SELECT_DISPLAY, kSelectDisplayLength);
- write64(display);
- endCommand();
- }
-
- static constexpr uint16_t kSelectLayerLength = 2;
- void selectLayer(int64_t layer) {
- beginCommand(Command::SELECT_LAYER, kSelectLayerLength);
- write64(layer);
- endCommand();
- }
-
- static constexpr uint16_t kSetErrorLength = 2;
- void setError(uint32_t location, int32_t error) {
- beginCommand(Command::SET_ERROR, kSetErrorLength);
- write(location);
- writeSigned(error);
- endCommand();
- }
-
- static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
- void setPresentOrValidateResult(uint32_t state) {
- beginCommand(Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT,
- kPresentOrValidateDisplayResultLength);
- write(state);
- endCommand();
- }
-
- void setChangedCompositionTypes(const std::vector<int64_t>& layers,
+ void setChangedCompositionTypes(int64_t display, const std::vector<int64_t>& layers,
const std::vector<Composition>& types) {
- size_t totalLayers = std::min(layers.size(), types.size());
- size_t currentLayer = 0;
+ command::ChangedCompositionTypes changedCompositionTypes;
+ changedCompositionTypes.display = display;
+ changedCompositionTypes.layers.reserve(layers.size());
+ for (int i = 0; i < layers.size(); i++) {
+ auto layer = command::ChangedCompositionTypes::Layer{.layer = layers[i],
+ .composition = types[i]};
+ changedCompositionTypes.layers.emplace_back(std::move(layer));
+ }
+ mCommandsResults.emplace_back(std::move(changedCompositionTypes));
+ }
- while (currentLayer < totalLayers) {
- size_t count =
- std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
+ void setDisplayRequests(int64_t display, int32_t displayRequestMask,
+ const std::vector<int64_t>& layers,
+ const std::vector<int32_t>& layerRequestMasks) {
+ command::DisplayRequest displayRequest;
+ displayRequest.display = display;
+ displayRequest.mask = displayRequestMask;
+ displayRequest.layerRequests.reserve(layers.size());
+ for (int i = 0; i < layers.size(); i++) {
+ auto layerRequest = command::DisplayRequest::LayerRequest{.layer = layers[i],
+ .mask = layerRequestMasks[i]};
+ displayRequest.layerRequests.emplace_back(std::move(layerRequest));
+ }
+ mCommandsResults.emplace_back(std::move(displayRequest));
+ }
- beginCommand(Command::SET_CHANGED_COMPOSITION_TYPES, count * 3);
- for (size_t i = 0; i < count; i++) {
- write64(layers[currentLayer + i]);
- writeSigned(static_cast<int32_t>(types[currentLayer + i]));
+ void setPresentFence(int64_t display, ::ndk::ScopedFileDescriptor presentFence) {
+ if (presentFence.get() >= 0) {
+ command::PresentFence presentFenceCommand;
+ presentFenceCommand.fence = std::move(presentFence);
+ presentFenceCommand.display = display;
+ mCommandsResults.emplace_back(std::move(presentFenceCommand));
+ } else {
+ ALOGW("%s: invalid present fence %d", __func__, presentFence.get());
+ }
+ }
+
+ void setReleaseFences(int64_t display, const std::vector<int64_t>& layers,
+ std::vector<::ndk::ScopedFileDescriptor> releaseFences) {
+ command::ReleaseFences releaseFencesCommand;
+ releaseFencesCommand.display = display;
+ for (int i = 0; i < layers.size(); i++) {
+ if (releaseFences[i].get() >= 0) {
+ command::ReleaseFences::Layer layer;
+ layer.layer = layers[i];
+ layer.fence = std::move(releaseFences[i]);
+ releaseFencesCommand.layers.emplace_back(std::move(layer));
+ } else {
+ ALOGW("%s: invalid release fence %d", __func__, releaseFences[i].get());
}
- endCommand();
-
- currentLayer += count;
}
+ mCommandsResults.emplace_back(std::move(releaseFencesCommand));
}
- void setDisplayRequests(uint32_t displayRequestMask, const std::vector<int64_t>& layers,
- const std::vector<uint32_t>& layerRequestMasks) {
- size_t totalLayers = std::min(layers.size(), layerRequestMasks.size());
- size_t currentLayer = 0;
+ void setClientTargetProperty(int64_t display, const ClientTargetProperty& clientTargetProperty,
+ float whitePointNits) {
+ command::ClientTargetPropertyWithNits clientTargetPropertyWithNits;
+ clientTargetPropertyWithNits.display = display;
+ clientTargetPropertyWithNits.clientTargetProperty = clientTargetProperty;
+ clientTargetPropertyWithNits.whitePointNits = whitePointNits;
+ mCommandsResults.emplace_back(std::move(clientTargetPropertyWithNits));
+ }
- while (currentLayer < totalLayers) {
- size_t count =
- std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3);
+ void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) {
+ command::ColorTransformPayload colorTransformPayload;
+ colorTransformPayload.matrix.assign(matrix, matrix + 16);
+ colorTransformPayload.hint = hint;
+ getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload));
+ }
- beginCommand(Command::SET_DISPLAY_REQUESTS, 1 + count * 3);
- write(displayRequestMask);
- for (size_t i = 0; i < count; i++) {
- write64(layers[currentLayer + i]);
- write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
- }
- endCommand();
+ void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
+ int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
+ command::ClientTarget clientTargetCommand;
+ clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
+ clientTargetCommand.dataspace = dataspace;
+ clientTargetCommand.damage.assign(damage.begin(), damage.end());
+ getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
+ }
- currentLayer += count;
+ void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
+ int releaseFence) {
+ getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
+ getBuffer(slot, buffer, releaseFence));
+ }
+
+ void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; }
+
+ void presentOrvalidateDisplay(int64_t display) {
+ getDisplayCommand(display).presentOrValidateDisplay = true;
+ }
+
+ void acceptDisplayChanges(int64_t display) {
+ getDisplayCommand(display).acceptDisplayChanges = true;
+ }
+
+ void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; }
+
+ void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
+ common::Point cursorPosition;
+ cursorPosition.x = x;
+ cursorPosition.y = y;
+ getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition));
+ }
+
+ void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
+ const native_handle_t* buffer, int acquireFence) {
+ getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
+ }
+
+ void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
+ getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end());
+ }
+
+ void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) {
+ command::ParcelableBlendMode parcelableBlendMode;
+ parcelableBlendMode.blendMode = mode;
+ getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode));
+ }
+
+ void setLayerColor(int64_t display, int64_t layer, Color color) {
+ getLayerCommand(display, layer).color.emplace(std::move(color));
+ }
+
+ void setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
+ command::ParcelableComposition compositionPayload;
+ compositionPayload.composition = type;
+ getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload));
+ }
+
+ void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) {
+ command::ParcelableDataspace dataspacePayload;
+ dataspacePayload.dataspace = dataspace;
+ getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload));
+ }
+
+ void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) {
+ getLayerCommand(display, layer).displayFrame.emplace(frame);
+ }
+
+ void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
+ command::PlaneAlpha planeAlpha;
+ planeAlpha.alpha = alpha;
+ getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha));
+ }
+
+ void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) {
+ NativeHandle handle;
+ if (stream) handle = ::android::dupToAidl(stream);
+ getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle));
+ }
+
+ void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) {
+ getLayerCommand(display, layer).sourceCrop.emplace(crop);
+ }
+
+ void setLayerTransform(int64_t display, int64_t layer, Transform transform) {
+ command::ParcelableTransform transformPayload;
+ transformPayload.transform = transform;
+ getLayerCommand(display, layer).transform.emplace(std::move(transformPayload));
+ }
+
+ void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
+ getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
+ }
+
+ void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
+ command::ZOrder zorder;
+ zorder.z = z;
+ getLayerCommand(display, layer).z.emplace(std::move(zorder));
+ }
+
+ void setLayerPerFrameMetadata(int64_t display, int64_t layer,
+ const std::vector<PerFrameMetadata>& metadataVec) {
+ getLayerCommand(display, layer)
+ .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end());
+ }
+
+ void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) {
+ getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16);
+ }
+
+ void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
+ const std::vector<PerFrameMetadataBlob>& metadata) {
+ getLayerCommand(display, layer)
+ .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
+ }
+
+ void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) {
+ getLayerCommand(display, layer).floatColor.emplace(color);
+ }
+
+ void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key,
+ const bool mandatory, const std::vector<uint8_t>& value) {
+ command::GenericMetadata metadata;
+ metadata.key.name = key;
+ metadata.key.mandatory = mandatory;
+ metadata.value.assign(value.begin(), value.end());
+ getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata));
+ }
+
+ void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) {
+ getLayerCommand(display, layer)
+ .whitePointNits.emplace(command::WhitePointNits{.nits = whitePointNits});
+ }
+
+ const std::vector<command::CommandPayload>& getPendingCommands() {
+ if (mLayerCommand.has_value()) {
+ mCommands.emplace_back(std::move(*mLayerCommand));
+ mLayerCommand.reset();
}
- }
-
- static constexpr uint16_t kSetPresentFenceLength = 1;
- void setPresentFence(int presentFence) {
- beginCommand(Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
- writeFence(presentFence);
- endCommand();
- }
-
- void setReleaseFences(const std::vector<int64_t>& layers,
- const std::vector<int>& releaseFences) {
- size_t totalLayers = std::min(layers.size(), releaseFences.size());
- size_t currentLayer = 0;
-
- while (currentLayer < totalLayers) {
- size_t count =
- std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
-
- beginCommand(Command::SET_RELEASE_FENCES, count * 3);
- for (size_t i = 0; i < count; i++) {
- write64(layers[currentLayer + i]);
- writeFence(releaseFences[currentLayer + i]);
- }
- endCommand();
-
- currentLayer += count;
+ if (mDisplayCommand.has_value()) {
+ mCommands.emplace_back(std::move(*mDisplayCommand));
+ mDisplayCommand.reset();
}
+ return mCommands;
}
- static constexpr uint16_t kSetColorTransformLength = 17;
- void setColorTransform(const float* matrix, ColorTransform hint) {
- beginCommand(Command::SET_COLOR_TRANSFORM, kSetColorTransformLength);
- for (int i = 0; i < 16; i++) {
- writeFloat(matrix[i]);
- }
- writeSigned(static_cast<int32_t>(hint));
- endCommand();
- }
-
- void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
- Dataspace dataspace, const std::vector<Rect>& damage) {
- setClientTargetInternal(slot, target, acquireFence, static_cast<int32_t>(dataspace),
- damage);
- }
-
- static constexpr uint16_t kSetOutputBufferLength = 3;
- void setOutputBuffer(uint32_t slot, const native_handle_t* buffer, int releaseFence) {
- beginCommand(Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength);
- write(slot);
- writeHandle(buffer, true);
- writeFence(releaseFence);
- endCommand();
- }
-
- static constexpr uint16_t kValidateDisplayLength = 0;
- void validateDisplay() {
- beginCommand(Command::VALIDATE_DISPLAY, kValidateDisplayLength);
- endCommand();
- }
-
- static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
- void presentOrvalidateDisplay() {
- beginCommand(Command::PRESENT_OR_VALIDATE_DISPLAY, kPresentOrValidateDisplayLength);
- endCommand();
- }
-
- static constexpr uint16_t kAcceptDisplayChangesLength = 0;
- void acceptDisplayChanges() {
- beginCommand(Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
- endCommand();
- }
-
- static constexpr uint16_t kPresentDisplayLength = 0;
- void presentDisplay() {
- beginCommand(Command::PRESENT_DISPLAY, kPresentDisplayLength);
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerCursorPositionLength = 2;
- void setLayerCursorPosition(int32_t x, int32_t y) {
- beginCommand(Command::SET_LAYER_CURSOR_POSITION, kSetLayerCursorPositionLength);
- writeSigned(x);
- writeSigned(y);
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerBufferLength = 3;
- void setLayerBuffer(uint32_t slot, const native_handle_t* buffer, int acquireFence) {
- beginCommand(Command::SET_LAYER_BUFFER, kSetLayerBufferLength);
- write(slot);
- writeHandle(buffer, true);
- writeFence(acquireFence);
- endCommand();
- }
-
- void setLayerSurfaceDamage(const std::vector<Rect>& damage) {
- bool doWrite = (damage.size() <= kMaxLength / 4);
- size_t length = (doWrite) ? damage.size() * 4 : 0;
-
- beginCommand(Command::SET_LAYER_SURFACE_DAMAGE, length);
- // When there are too many rectangles in the damage region and doWrite
- // is false, we write no rectangle at all which means the entire
- // layer is damaged.
- if (doWrite) {
- writeRegion(damage);
- }
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerBlendModeLength = 1;
- void setLayerBlendMode(BlendMode mode) {
- beginCommand(Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength);
- writeSigned(static_cast<int32_t>(mode));
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerColorLength = 1;
- void setLayerColor(Color color) {
- beginCommand(Command::SET_LAYER_COLOR, kSetLayerColorLength);
- writeColor(color);
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
- void setLayerCompositionType(Composition type) {
- beginCommand(Command::SET_LAYER_COMPOSITION_TYPE, kSetLayerCompositionTypeLength);
- writeSigned(static_cast<int32_t>(type));
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerDataspaceLength = 1;
- void setLayerDataspace(Dataspace dataspace) {
- setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
- }
-
- static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
- void setLayerDisplayFrame(const Rect& frame) {
- beginCommand(Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength);
- writeRect(frame);
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
- void setLayerPlaneAlpha(float alpha) {
- beginCommand(Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength);
- writeFloat(alpha);
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
- void setLayerSidebandStream(const native_handle_t* stream) {
- beginCommand(Command::SET_LAYER_SIDEBAND_STREAM, kSetLayerSidebandStreamLength);
- writeHandle(stream);
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerSourceCropLength = 4;
- void setLayerSourceCrop(const FRect& crop) {
- beginCommand(Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength);
- writeFRect(crop);
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerTransformLength = 1;
- void setLayerTransform(Transform transform) {
- beginCommand(Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
- writeSigned(static_cast<int32_t>(transform));
- endCommand();
- }
-
- void setLayerVisibleRegion(const std::vector<Rect>& visible) {
- bool doWrite = (visible.size() <= kMaxLength / 4);
- size_t length = (doWrite) ? visible.size() * 4 : 0;
-
- beginCommand(Command::SET_LAYER_VISIBLE_REGION, length);
- // When there are too many rectangles in the visible region and
- // doWrite is false, we write no rectangle at all which means the
- // entire layer is visible.
- if (doWrite) {
- writeRegion(visible);
- }
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerZOrderLength = 1;
- void setLayerZOrder(uint32_t z) {
- beginCommand(Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength);
- write(z);
- endCommand();
- }
-
- void setLayerPerFrameMetadata(const std::vector<PerFrameMetadata>& metadataVec) {
- beginCommand(Command::SET_LAYER_PER_FRAME_METADATA, metadataVec.size() * 2);
- for (const auto& metadata : metadataVec) {
- writeSigned(static_cast<int32_t>(metadata.key));
- writeFloat(metadata.value);
- }
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerColorTransformLength = 16;
- void setLayerColorTransform(const float* matrix) {
- beginCommand(Command::SET_LAYER_COLOR_TRANSFORM, kSetLayerColorTransformLength);
- for (int i = 0; i < 16; i++) {
- writeFloat(matrix[i]);
- }
- endCommand();
- }
-
- void setLayerPerFrameMetadataBlobs(const std::vector<PerFrameMetadataBlob>& metadata) {
- // in units of uint32_t's
- size_t commandLength = 0;
-
- if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
- LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
- return;
- }
-
- // space for numElements
- commandLength += 1;
-
- for (auto metadataBlob : metadata) {
- commandLength += 1; // key of metadata blob
- commandLength += 1; // size information of metadata blob
-
- // metadata content size
- size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
- commandLength += metadataSize;
- commandLength +=
- (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
- }
-
- if (commandLength > std::numeric_limits<uint16_t>::max()) {
- LOG_FATAL("dynamic metadata size is too large");
- return;
- }
-
- // Blobs are written as:
- // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
- uint16_t length = static_cast<uint16_t>(commandLength);
- beginCommand(Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
- write(static_cast<uint32_t>(metadata.size()));
- for (auto metadataBlob : metadata) {
- writeSigned(static_cast<int32_t>(metadataBlob.key));
- write(static_cast<uint32_t>(metadataBlob.blob.size()));
- writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
- }
- endCommand();
- }
-
- static constexpr uint16_t kSetLayerFloatColorLength = 4;
- void setLayerFloatColor(FloatColor color) {
- beginCommand(Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength);
- writeFloatColor(color);
- endCommand();
- }
-
- static constexpr uint16_t kSetClientTargetPropertyLength = 2;
- void setClientTargetProperty(const ClientTargetProperty& clientTargetProperty) {
- beginCommand(Command::SET_CLIENT_TARGET_PROPERTY, kSetClientTargetPropertyLength);
- writeSigned(static_cast<int32_t>(clientTargetProperty.pixelFormat));
- writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace));
- endCommand();
- }
-
- void setLayerGenericMetadata(const std::string& key, const bool mandatory,
- const std::vector<uint8_t>& value) {
- const size_t commandSize = 3 + sizeToElements(key.size()) + sizeToElements(value.size());
- if (commandSize > std::numeric_limits<uint16_t>::max()) {
- LOG_FATAL("Too much generic metadata (%zu elements)", commandSize);
- return;
- }
-
- beginCommand(Command::SET_LAYER_GENERIC_METADATA, static_cast<uint16_t>(commandSize));
- write(key.size());
- writeBlob(key.size(), reinterpret_cast<const unsigned char*>(key.c_str()));
- write(mandatory);
- write(value.size());
- writeBlob(value.size(), value.data());
- endCommand();
+ std::vector<command::CommandResultPayload> getPendingCommandResults() {
+ return std::move(mCommandsResults);
}
protected:
- template <typename T>
- void beginCommand(T command, uint16_t length) {
- beginCommandBase(static_cast<Command>(command), length);
+ command::Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) {
+ command::Buffer bufferCommand;
+ bufferCommand.slot = slot;
+ if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
+ if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
+ return bufferCommand;
}
- void setClientTargetInternal(uint32_t slot, const native_handle_t* target, int acquireFence,
- int32_t dataspace, const std::vector<Rect>& damage) {
- bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
- size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
-
- beginCommand(Command::SET_CLIENT_TARGET, length);
- write(slot);
- writeHandle(target, true);
- writeFence(acquireFence);
- writeSigned(dataspace);
- // When there are too many rectangles in the damage region and doWrite
- // is false, we write no rectangle at all which means the entire
- // client target is damaged.
- if (doWrite) {
- writeRegion(damage);
- }
- endCommand();
- }
-
- void setLayerDataspaceInternal(int32_t dataspace) {
- beginCommand(Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
- writeSigned(dataspace);
- endCommand();
- }
-
- void beginCommandBase(Command command, uint16_t length) {
- if (mCommandEnd) {
- LOG_FATAL("endCommand was not called before command 0x%x", command);
- }
-
- growData(1 + length);
- write(static_cast<uint32_t>(command) | length);
-
- mCommandEnd = mDataWritten + length;
- }
-
- void endCommand() {
- if (!mCommandEnd) {
- LOG_FATAL("beginCommand was not called");
- } else if (mDataWritten > mCommandEnd) {
- LOG_FATAL("too much data written");
- mDataWritten = mCommandEnd;
- } else if (mDataWritten < mCommandEnd) {
- LOG_FATAL("too little data written");
- while (mDataWritten < mCommandEnd) {
- write(0);
- }
- }
-
- mCommandEnd = 0;
- }
-
- void write(uint32_t val) { mData[mDataWritten++] = val; }
-
- void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
- void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
- void write64(uint64_t val) {
- uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
- uint32_t hi = static_cast<uint32_t>(val >> 32);
- write(lo);
- write(hi);
- }
-
- void writeRect(const Rect& rect) {
- writeSigned(rect.left);
- writeSigned(rect.top);
- writeSigned(rect.right);
- writeSigned(rect.bottom);
- }
-
- void writeRegion(const std::vector<Rect>& region) {
- for (const auto& rect : region) {
- writeRect(rect);
- }
- }
-
- void writeFRect(const FRect& rect) {
- writeFloat(rect.left);
- writeFloat(rect.top);
- writeFloat(rect.right);
- writeFloat(rect.bottom);
- }
-
- void writeColor(const Color& color) {
- write((color.r << 0) | (color.g << 8) | (color.b << 16) | (color.a << 24));
- }
-
- void writeFloatColor(const FloatColor& color) {
- writeFloat(color.r);
- writeFloat(color.g);
- writeFloat(color.b);
- writeFloat(color.a);
- }
-
- void writeBlob(uint32_t length, const unsigned char* blob) {
- memcpy(&mData[mDataWritten], blob, length);
- uint32_t numElements = length / 4;
- mDataWritten += numElements;
- mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
- }
-
- // ownership of handle is not transferred
- void writeHandle(const native_handle_t* handle, bool useCache) {
- if (!handle) {
- writeSigned(
- static_cast<int32_t>((useCache) ? HandleIndex::CACHED : HandleIndex::EMPTY));
- return;
- }
-
- mDataHandles.push_back(::android::dupToAidl(handle));
- writeSigned(mDataHandles.size() - 1);
- }
-
- void writeHandle(const native_handle_t* handle) { writeHandle(handle, false); }
-
- // ownership of fence is transferred
- void writeFence(int fence) {
- native_handle_t* handle = nullptr;
- if (fence >= 0) {
- handle = getTemporaryHandle(1, 0);
- if (handle) {
- handle->data[0] = fence;
- } else {
- ALOGW("failed to get temporary handle for fence %d", fence);
- sync_wait(fence, -1);
- close(fence);
- }
- }
-
- writeHandle(handle);
- }
-
- native_handle_t* getTemporaryHandle(int numFds, int numInts) {
- native_handle_t* handle = native_handle_create(numFds, numInts);
- if (handle) {
- mTemporaryHandles.push_back(handle);
- }
- return handle;
- }
-
- static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
-
- std::unique_ptr<int32_t[]> mData;
- uint32_t mDataWritten;
+ std::optional<command::DisplayCommand> mDisplayCommand;
+ std::optional<command::LayerCommand> mLayerCommand;
+ std::vector<command::CommandPayload> mCommands;
+ std::vector<command::CommandResultPayload> mCommandsResults;
private:
- void growData(uint32_t grow) {
- uint32_t newWritten = mDataWritten + grow;
- if (newWritten < mDataWritten) {
- LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32 ", growing by %" PRIu32,
- mDataWritten, grow);
- }
+ // std::vector<native_handle_t*> mTemporaryHandles;
- if (newWritten <= mDataMaxSize) {
- return;
+ command::DisplayCommand& getDisplayCommand(int64_t display) {
+ if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
+ if (mDisplayCommand.has_value()) mCommands.emplace_back(std::move(*mDisplayCommand));
+ mDisplayCommand.emplace();
+ mDisplayCommand->display = display;
+ return *mDisplayCommand;
}
-
- uint32_t newMaxSize = mDataMaxSize << 1;
- if (newMaxSize < newWritten) {
- newMaxSize = newWritten;
- }
-
- auto newData = std::make_unique<int32_t[]>(newMaxSize);
- std::copy_n(mData.get(), mDataWritten, newData.get());
- mDataMaxSize = newMaxSize;
- mData = std::move(newData);
+ return *mDisplayCommand;
}
- uint32_t sizeToElements(uint32_t size) { return (size + 3) / 4; }
-
- uint32_t mDataMaxSize;
- // end offset of the current command
- uint32_t mCommandEnd;
-
- std::vector<NativeHandle> mDataHandles;
- std::vector<native_handle_t*> mTemporaryHandles;
-
- std::unique_ptr<CommandQueueType> mQueue;
+ command::LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
+ if (!mLayerCommand.has_value() || mLayerCommand->display != display ||
+ mLayerCommand->layer != layer) {
+ if (mLayerCommand.has_value()) mCommands.emplace_back(std::move(*mLayerCommand));
+ mLayerCommand.emplace();
+ mLayerCommand->display = display;
+ mLayerCommand->layer = layer;
+ return *mLayerCommand;
+ }
+ return *mLayerCommand;
+ }
};
-// This class helps parse a command queue. Note that all sizes/lengths are in
-// units of uint32_t's.
class CommandReaderBase {
public:
- CommandReaderBase() : mDataMaxSize(0) { reset(); }
+ ~CommandReaderBase() { resetData(); }
- bool setMQDescriptor(const DescriptorType& descriptor) {
- mQueue = std::make_unique<CommandQueueType>(descriptor, false);
- if (mQueue->isValid()) {
- return true;
- } else {
- mQueue = nullptr;
- return false;
+ // Parse and execute commands from the command queue. The commands are
+ // actually return values from the server and will be saved in ReturnData.
+ void parse(const std::vector<command::CommandResultPayload>& results) {
+ resetData();
+
+ for (const auto& result : results) {
+ switch (result.getTag()) {
+ case command::CommandResultPayload::Tag::error:
+ parseSetError(result.get<command::CommandResultPayload::Tag::error>());
+ break;
+ case command::CommandResultPayload::Tag::changedCompositionType:
+ parseSetChangedCompositionTypes(
+ result.get<
+ command::CommandResultPayload::Tag::changedCompositionType>());
+ break;
+ case command::CommandResultPayload::Tag::displayRequest:
+ parseSetDisplayRequests(
+ result.get<command::CommandResultPayload::Tag::displayRequest>());
+ break;
+ case command::CommandResultPayload::Tag::presentFence:
+ parseSetPresentFence(
+ result.get<command::CommandResultPayload::Tag::presentFence>());
+ break;
+ case command::CommandResultPayload::Tag::releaseFences:
+ parseSetReleaseFences(
+ result.get<command::CommandResultPayload::Tag::releaseFences>());
+ break;
+ case command::CommandResultPayload::Tag::presentOrValidateResult:
+ parseSetPresentOrValidateDisplayResult(
+ result.get<
+ command::CommandResultPayload::Tag::presentOrValidateResult>());
+ break;
+ case command::CommandResultPayload::Tag::clientTargetProperty:
+ parseSetClientTargetProperty(
+ result.get<command::CommandResultPayload::Tag::clientTargetProperty>());
+ break;
+ }
}
}
- bool readQueue(int32_t commandLength, std::vector<NativeHandle> commandHandles) {
- if (!mQueue) {
+ std::vector<command::Error> takeErrors() { return std::move(mErrors); }
+
+ bool hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
+ uint32_t* outNumLayerRequestMasks) const {
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *outNumChangedCompositionTypes = 0;
+ *outNumLayerRequestMasks = 0;
return false;
}
- auto quantumCount = mQueue->getQuantumCount();
- if (mDataMaxSize < quantumCount) {
- mDataMaxSize = quantumCount;
- mData = std::make_unique<int32_t[]>(mDataMaxSize);
+ const ReturnData& data = found->second;
+
+ *outNumChangedCompositionTypes = static_cast<uint32_t>(data.compositionTypes.size());
+ *outNumLayerRequestMasks = static_cast<uint32_t>(data.requestMasks.size());
+
+ return !(data.compositionTypes.empty() && data.requestMasks.empty());
+ }
+
+ // Get and clear saved changed composition types.
+ void takeChangedCompositionTypes(int64_t display, std::vector<int64_t>* outLayers,
+ std::vector<Composition>* outTypes) {
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ outLayers->clear();
+ outTypes->clear();
+ return;
}
- if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
- ALOGE("failed to read commands from message queue");
- return false;
+ ReturnData& data = found->second;
+
+ *outLayers = std::move(data.changedLayers);
+ *outTypes = std::move(data.compositionTypes);
+ }
+
+ // Get and clear saved display requests.
+ void takeDisplayRequests(int64_t display, uint32_t* outDisplayRequestMask,
+ std::vector<int64_t>* outLayers,
+ std::vector<uint32_t>* outLayerRequestMasks) {
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *outDisplayRequestMask = 0;
+ outLayers->clear();
+ outLayerRequestMasks->clear();
+ return;
}
- mDataSize = commandLength;
- mDataRead = 0;
- mCommandBegin = 0;
- mCommandEnd = 0;
- mDataHandles = std::move(commandHandles);
- return true;
+ ReturnData& data = found->second;
+
+ *outDisplayRequestMask = data.displayRequests;
+ *outLayers = std::move(data.requestedLayers);
+ *outLayerRequestMasks = std::move(data.requestMasks);
}
- void reset() {
- mDataSize = 0;
- mDataRead = 0;
- mCommandBegin = 0;
- mCommandEnd = 0;
- mDataHandles.clear();
- }
-
- protected:
- template <typename T>
- bool beginCommand(T* outCommand, uint16_t* outLength) {
- return beginCommandBase(reinterpret_cast<Command*>(outCommand), outLength);
- }
-
- bool isEmpty() const { return (mDataRead >= mDataSize); }
-
- bool beginCommandBase(Command* outCommand, uint16_t* outLength) {
- if (mCommandEnd) {
- LOG_FATAL("endCommand was not called for last command");
+ // Get and clear saved release fences.
+ void takeReleaseFences(int64_t display, std::vector<int64_t>* outLayers,
+ std::vector<int>* outReleaseFences) {
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ outLayers->clear();
+ outReleaseFences->clear();
+ return;
}
- constexpr uint32_t opcode_mask = static_cast<uint32_t>(Command::OPCODE_MASK);
- constexpr uint32_t length_mask = static_cast<uint32_t>(Command::LENGTH_MASK);
+ ReturnData& data = found->second;
- uint32_t val = read();
- *outCommand = static_cast<Command>(val & opcode_mask);
- *outLength = static_cast<uint16_t>(val & length_mask);
+ *outLayers = std::move(data.releasedLayers);
+ *outReleaseFences = std::move(data.releaseFences);
+ }
- if (mDataRead + *outLength > mDataSize) {
- ALOGE("command 0x%x has invalid command length %" PRIu16, *outCommand, *outLength);
- // undo the read() above
- mDataRead--;
- return false;
+ // Get and clear saved present fence.
+ void takePresentFence(int64_t display, int* outPresentFence) {
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *outPresentFence = -1;
+ return;
}
- mCommandEnd = mDataRead + *outLength;
+ ReturnData& data = found->second;
- return true;
+ *outPresentFence = data.presentFence;
+ data.presentFence = -1;
}
- void endCommand() {
- if (!mCommandEnd) {
- LOG_FATAL("beginCommand was not called");
- } else if (mDataRead > mCommandEnd) {
- LOG_FATAL("too much data read");
- mDataRead = mCommandEnd;
- } else if (mDataRead < mCommandEnd) {
- LOG_FATAL("too little data read");
- mDataRead = mCommandEnd;
+ // Get what stage succeeded during PresentOrValidate: Present or Validate
+ void takePresentOrValidateStage(int64_t display, uint32_t* state) {
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *state = static_cast<uint32_t>(-1);
+ return;
+ }
+ ReturnData& data = found->second;
+ *state = data.presentOrValidateState;
+ }
+
+ // Get the client target properties requested by hardware composer.
+ void takeClientTargetProperty(int64_t display, ClientTargetProperty* outClientTargetProperty,
+ float* outWhitePointNits) {
+ auto found = mReturnData.find(display);
+
+ // If not found, return the default values.
+ if (found == mReturnData.end()) {
+ outClientTargetProperty->pixelFormat = common::PixelFormat::RGBA_8888;
+ outClientTargetProperty->dataspace = Dataspace::UNKNOWN;
+ *outWhitePointNits = -1.f;
+ return;
}
- mCommandBegin = mCommandEnd;
- mCommandEnd = 0;
+ ReturnData& data = found->second;
+ *outClientTargetProperty = data.clientTargetProperty;
+ *outWhitePointNits = data.clientTargetWhitePointNits;
}
- uint32_t getCommandLoc() const { return mCommandBegin; }
-
- uint32_t read() { return mData[mDataRead++]; }
-
- int32_t readSigned() {
- int32_t val;
- memcpy(&val, &mData[mDataRead++], sizeof(val));
- return val;
- }
-
- float readFloat() {
- float val;
- memcpy(&val, &mData[mDataRead++], sizeof(val));
- return val;
- }
-
- uint64_t read64() {
- uint32_t lo = read();
- uint32_t hi = read();
- return (static_cast<uint64_t>(hi) << 32) | lo;
- }
-
- Color readColor() {
- uint32_t val = read();
- return Color{
- static_cast<int8_t>((val >> 0) & 0xff),
- static_cast<int8_t>((val >> 8) & 0xff),
- static_cast<int8_t>((val >> 16) & 0xff),
- static_cast<int8_t>((val >> 24) & 0xff),
- };
- }
-
- // ownership of handle is not transferred
- const native_handle_t* readHandle(bool* outUseCache) {
- const native_handle_t* handle = nullptr;
-
- int32_t index = readSigned();
- switch (index) {
- case static_cast<int32_t>(HandleIndex::EMPTY):
- *outUseCache = false;
- break;
- case static_cast<int32_t>(HandleIndex::CACHED):
- *outUseCache = true;
- break;
- default:
- if (static_cast<size_t>(index) < mDataHandles.size()) {
- handle = ::android::makeFromAidl(mDataHandles[index]);
- } else {
- ALOGE("invalid handle index %zu", static_cast<size_t>(index));
- }
- *outUseCache = false;
- break;
- }
-
- return handle;
- }
-
- const native_handle_t* readHandle() {
- bool useCache;
- return readHandle(&useCache);
- }
-
- // ownership of fence is transferred
- int readFence() {
- auto handle = readHandle();
- if (!handle || handle->numFds == 0) {
- return -1;
- }
-
- if (handle->numFds != 1) {
- ALOGE("invalid fence handle with %d fds", handle->numFds);
- return -1;
- }
-
- int fd = dup(handle->data[0]);
- if (fd < 0) {
- ALOGW("failed to dup fence %d", handle->data[0]);
- sync_wait(handle->data[0], -1);
- fd = -1;
- }
-
- return fd;
- }
-
- std::unique_ptr<int32_t[]> mData;
- uint32_t mDataRead;
-
private:
- std::unique_ptr<CommandQueueType> mQueue;
- uint32_t mDataMaxSize;
+ void resetData() {
+ mErrors.clear();
- uint32_t mDataSize;
+ for (auto& data : mReturnData) {
+ if (data.second.presentFence >= 0) {
+ close(data.second.presentFence);
+ }
+ for (auto fence : data.second.releaseFences) {
+ if (fence >= 0) {
+ close(fence);
+ }
+ }
+ }
- // begin/end offsets of the current command
- uint32_t mCommandBegin;
- uint32_t mCommandEnd;
+ mReturnData.clear();
+ }
- std::vector<NativeHandle> mDataHandles;
+ void parseSetError(const command::Error& error) { mErrors.emplace_back(error); }
+
+ void parseSetChangedCompositionTypes(
+ const command::ChangedCompositionTypes& changedCompositionTypes) {
+ auto& data = mReturnData[changedCompositionTypes.display];
+
+ data.changedLayers.reserve(changedCompositionTypes.layers.size());
+ data.compositionTypes.reserve(changedCompositionTypes.layers.size());
+ for (const auto& layer : changedCompositionTypes.layers) {
+ data.changedLayers.push_back(layer.layer);
+ data.compositionTypes.push_back(layer.composition);
+ }
+ }
+
+ void parseSetDisplayRequests(const command::DisplayRequest& displayRequest) {
+ auto& data = mReturnData[displayRequest.display];
+
+ data.displayRequests = displayRequest.mask;
+ data.requestedLayers.reserve(displayRequest.layerRequests.size());
+ data.requestMasks.reserve(displayRequest.layerRequests.size());
+ for (const auto& layerRequest : displayRequest.layerRequests) {
+ data.requestedLayers.push_back(layerRequest.layer);
+ data.requestMasks.push_back(layerRequest.mask);
+ }
+ }
+
+ void parseSetPresentFence(const command::PresentFence& presentFence) {
+ auto& data = mReturnData[presentFence.display];
+ if (data.presentFence >= 0) {
+ close(data.presentFence);
+ }
+ data.presentFence = dup(presentFence.fence.get());
+ }
+
+ void parseSetReleaseFences(const command::ReleaseFences& releaseFences) {
+ auto& data = mReturnData[releaseFences.display];
+ data.releasedLayers.reserve(releaseFences.layers.size());
+ data.releaseFences.reserve(releaseFences.layers.size());
+ for (const auto& layer : releaseFences.layers) {
+ data.releasedLayers.push_back(layer.layer);
+ data.releaseFences.push_back(dup(layer.fence.get()));
+ }
+ }
+
+ void parseSetPresentOrValidateDisplayResult(
+ const command::PresentOrValidate& presentOrValidate) {
+ auto& data = mReturnData[presentOrValidate.display];
+ data.presentOrValidateState =
+ presentOrValidate.result == command::PresentOrValidate::Result::Presented ? 1 : 0;
+ }
+
+ void parseSetClientTargetProperty(
+ const command::ClientTargetPropertyWithNits& clientTargetProperty) {
+ auto& data = mReturnData[clientTargetProperty.display];
+ data.clientTargetProperty.pixelFormat =
+ clientTargetProperty.clientTargetProperty.pixelFormat;
+ data.clientTargetProperty.dataspace = clientTargetProperty.clientTargetProperty.dataspace;
+ data.clientTargetWhitePointNits = clientTargetProperty.whitePointNits;
+ }
+
+ struct ReturnData {
+ int32_t displayRequests = 0;
+
+ std::vector<int64_t> changedLayers;
+ std::vector<Composition> compositionTypes;
+
+ std::vector<int64_t> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+
+ int presentFence = -1;
+
+ std::vector<int64_t> releasedLayers;
+ std::vector<int> releaseFences;
+
+ uint32_t presentOrValidateState;
+
+ ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
+ Dataspace::UNKNOWN};
+ float clientTargetWhitePointNits = -1.f;
+ };
+
+ std::vector<command::Error> mErrors;
+ std::unordered_map<int64_t, ReturnData> mReturnData;
};
} // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
index c892863..7004955 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
@@ -17,25 +17,22 @@
#pragma once
#include <limits>
+#include "aidl/android/hardware/graphics/common/BlendMode.h"
#include "aidl/android/hardware/graphics/common/FRect.h"
#include "aidl/android/hardware/graphics/common/Rect.h"
-#include "aidl/android/hardware/graphics/composer3/BlendMode.h"
#include "aidl/android/hardware/graphics/composer3/Capability.h"
#include "aidl/android/hardware/graphics/composer3/ClientTargetProperty.h"
#include "aidl/android/hardware/graphics/composer3/Color.h"
-#include "aidl/android/hardware/graphics/composer3/Command.h"
#include "aidl/android/hardware/graphics/composer3/Composition.h"
#include "aidl/android/hardware/graphics/composer3/ContentType.h"
#include "aidl/android/hardware/graphics/composer3/DisplayAttribute.h"
#include "aidl/android/hardware/graphics/composer3/DisplayCapability.h"
#include "aidl/android/hardware/graphics/composer3/DisplayConnectionType.h"
-#include "aidl/android/hardware/graphics/composer3/DisplayRequest.h"
#include "aidl/android/hardware/graphics/composer3/FloatColor.h"
#include "aidl/android/hardware/graphics/composer3/FormatColorComponent.h"
#include "aidl/android/hardware/graphics/composer3/HandleIndex.h"
#include "aidl/android/hardware/graphics/composer3/IComposer.h"
#include "aidl/android/hardware/graphics/composer3/LayerGenericMetadataKey.h"
-#include "aidl/android/hardware/graphics/composer3/LayerRequest.h"
#include "aidl/android/hardware/graphics/composer3/PerFrameMetadata.h"
#include "aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h"
#include "aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.h"
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index fae7592..6e2f1d4 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -25,6 +25,7 @@
name: "android.hardware.health",
vendor_available: true,
recovery_available: true,
+ host_supported: true,
srcs: ["android/hardware/health/*.aidl"],
stability: "vintf",
backend: {
@@ -48,6 +49,7 @@
name: "android.hardware.health-translate-ndk",
vendor_available: true,
recovery_available: true,
+ host_supported: true,
srcs: ["android/hardware/health/translate-ndk.cpp"],
shared_libs: [
"libbinder_ndk",
@@ -61,6 +63,9 @@
"android.hardware.health@2.0",
"android.hardware.health@2.1",
],
+ defaults: [
+ "libbinder_ndk_host_user",
+ ],
}
java_library {
diff --git a/health/aidl/android/hardware/health/translate-ndk.cpp b/health/aidl/android/hardware/health/translate-ndk.cpp
index 7fe6ced..78880cc 100644
--- a/health/aidl/android/hardware/health/translate-ndk.cpp
+++ b/health/aidl/android/hardware/health/translate-ndk.cpp
@@ -106,36 +106,41 @@
}
__attribute__((warn_unused_result)) bool translate(
+ const ::android::hardware::health::V2_0::HealthInfo& in,
+ aidl::android::hardware::health::HealthInfo* out) {
+ out->chargerAcOnline = static_cast<bool>(in.legacy.chargerAcOnline);
+ out->chargerUsbOnline = static_cast<bool>(in.legacy.chargerUsbOnline);
+ out->chargerWirelessOnline = static_cast<bool>(in.legacy.chargerWirelessOnline);
+ out->maxChargingCurrentMicroamps = static_cast<int32_t>(in.legacy.maxChargingCurrent);
+ out->maxChargingVoltageMicrovolts = static_cast<int32_t>(in.legacy.maxChargingVoltage);
+ out->batteryStatus =
+ static_cast<aidl::android::hardware::health::BatteryStatus>(in.legacy.batteryStatus);
+ out->batteryHealth =
+ static_cast<aidl::android::hardware::health::BatteryHealth>(in.legacy.batteryHealth);
+ out->batteryPresent = static_cast<bool>(in.legacy.batteryPresent);
+ out->batteryLevel = static_cast<int32_t>(in.legacy.batteryLevel);
+ out->batteryVoltageMillivolts = static_cast<int32_t>(in.legacy.batteryVoltage);
+ out->batteryTemperatureTenthsCelsius = static_cast<int32_t>(in.legacy.batteryTemperature);
+ out->batteryCurrentMicroamps = static_cast<int32_t>(in.legacy.batteryCurrent);
+ out->batteryCycleCount = static_cast<int32_t>(in.legacy.batteryCycleCount);
+ out->batteryFullChargeUah = static_cast<int32_t>(in.legacy.batteryFullCharge);
+ out->batteryChargeCounterUah = static_cast<int32_t>(in.legacy.batteryChargeCounter);
+ out->batteryTechnology = in.legacy.batteryTechnology;
+ out->batteryCurrentAverageMicroamps = static_cast<int32_t>(in.batteryCurrentAverage);
+ out->diskStats.clear();
+ out->diskStats.resize(in.diskStats.size());
+ for (size_t i = 0; i < in.diskStats.size(); ++i)
+ if (!translate(in.diskStats[i], &out->diskStats[i])) return false;
+ out->storageInfos.clear();
+ out->storageInfos.resize(in.storageInfos.size());
+ for (size_t i = 0; i < in.storageInfos.size(); ++i)
+ if (!translate(in.storageInfos[i], &out->storageInfos[i])) return false;
+ return true;
+}
+__attribute__((warn_unused_result)) bool translate(
const ::android::hardware::health::V2_1::HealthInfo& in,
aidl::android::hardware::health::HealthInfo* out) {
- out->chargerAcOnline = static_cast<bool>(in.legacy.legacy.chargerAcOnline);
- out->chargerUsbOnline = static_cast<bool>(in.legacy.legacy.chargerUsbOnline);
- out->chargerWirelessOnline = static_cast<bool>(in.legacy.legacy.chargerWirelessOnline);
- out->maxChargingCurrentMicroamps = static_cast<int32_t>(in.legacy.legacy.maxChargingCurrent);
- out->maxChargingVoltageMicrovolts = static_cast<int32_t>(in.legacy.legacy.maxChargingVoltage);
- out->batteryStatus = static_cast<aidl::android::hardware::health::BatteryStatus>(
- in.legacy.legacy.batteryStatus);
- out->batteryHealth = static_cast<aidl::android::hardware::health::BatteryHealth>(
- in.legacy.legacy.batteryHealth);
- out->batteryPresent = static_cast<bool>(in.legacy.legacy.batteryPresent);
- out->batteryLevel = static_cast<int32_t>(in.legacy.legacy.batteryLevel);
- out->batteryVoltageMillivolts = static_cast<int32_t>(in.legacy.legacy.batteryVoltage);
- out->batteryTemperatureTenthsCelsius =
- static_cast<int32_t>(in.legacy.legacy.batteryTemperature);
- out->batteryCurrentMicroamps = static_cast<int32_t>(in.legacy.legacy.batteryCurrent);
- out->batteryCycleCount = static_cast<int32_t>(in.legacy.legacy.batteryCycleCount);
- out->batteryFullChargeUah = static_cast<int32_t>(in.legacy.legacy.batteryFullCharge);
- out->batteryChargeCounterUah = static_cast<int32_t>(in.legacy.legacy.batteryChargeCounter);
- out->batteryTechnology = in.legacy.legacy.batteryTechnology;
- out->batteryCurrentAverageMicroamps = static_cast<int32_t>(in.legacy.batteryCurrentAverage);
- out->diskStats.clear();
- out->diskStats.resize(in.legacy.diskStats.size());
- for (size_t i = 0; i < in.legacy.diskStats.size(); ++i)
- if (!translate(in.legacy.diskStats[i], &out->diskStats[i])) return false;
- out->storageInfos.clear();
- out->storageInfos.resize(in.legacy.storageInfos.size());
- for (size_t i = 0; i < in.legacy.storageInfos.size(); ++i)
- if (!translate(in.legacy.storageInfos[i], &out->storageInfos[i])) return false;
+ if (!translate(in.legacy, out)) return false;
out->batteryCapacityLevel = static_cast<aidl::android::hardware::health::BatteryCapacityLevel>(
in.batteryCapacityLevel);
out->batteryChargeTimeToFullNowSeconds =
diff --git a/health/aidl/include/android/hardware/health/translate-ndk.h b/health/aidl/include/android/hardware/health/translate-ndk.h
index 2f8fe04..91add42 100644
--- a/health/aidl/include/android/hardware/health/translate-ndk.h
+++ b/health/aidl/include/android/hardware/health/translate-ndk.h
@@ -33,6 +33,9 @@
const ::android::hardware::health::V2_0::DiskStats& in,
aidl::android::hardware::health::DiskStats* out);
__attribute__((warn_unused_result)) bool translate(
+ const ::android::hardware::health::V2_0::HealthInfo& in,
+ aidl::android::hardware::health::HealthInfo* out);
+__attribute__((warn_unused_result)) bool translate(
const ::android::hardware::health::V2_1::HealthInfo& in,
aidl::android::hardware::health::HealthInfo* out);
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
new file mode 100644
index 0000000..311e951
--- /dev/null
+++ b/health/utils/libhealthshim/Android.bp
@@ -0,0 +1,78 @@
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_defaults {
+ name: "libhealthshim_defaults",
+ host_supported: true, // for testing
+ defaults: [
+ "libbinder_ndk_host_user",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ static_libs: [
+ "android.hardware.health-V1-ndk",
+ "android.hardware.health-translate-ndk",
+ "android.hardware.health@1.0",
+ "android.hardware.health@2.0",
+ ],
+ shared_libs: [
+ // These can be expected from the device or from host.
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+}
+
+// Shim library that wraps a HIDL IHealth object into an AIDL IHealth object.
+cc_library_static {
+ name: "libhealthshim",
+ defaults: ["libhealthshim_defaults"],
+ recovery_available: true,
+ srcs: [
+ "shim.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+}
+
+cc_test {
+ name: "libhealthshim_test",
+ defaults: ["libhealthshim_defaults"],
+ static_libs: [
+ "libhealthshim",
+ "libgmock",
+ ],
+ srcs: [
+ "test.cpp",
+ ],
+ test_suites: ["general-tests"],
+ test_options: {
+ unit_test: true,
+ },
+}
diff --git a/health/utils/libhealthshim/include/health-shim/shim.h b/health/utils/libhealthshim/include/health-shim/shim.h
new file mode 100644
index 0000000..f36fa5d
--- /dev/null
+++ b/health/utils/libhealthshim/include/health-shim/shim.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <map>
+
+#include <aidl/android/hardware/health/BnHealth.h>
+#include <android/hardware/health/2.0/IHealth.h>
+
+namespace aidl::android::hardware::health {
+
+// Shim that wraps HIDL IHealth with an AIDL BnHealth.
+// The wrapper always have isRemote() == false because it is BnHealth.
+class HealthShim : public BnHealth {
+ using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+ using HidlHealthInfoCallback = ::android::hardware::health::V2_0::IHealthInfoCallback;
+
+ public:
+ explicit HealthShim(const ::android::sp<HidlHealth>& service);
+
+ ndk::ScopedAStatus registerCallback(
+ const std::shared_ptr<IHealthInfoCallback>& in_callback) override;
+ ndk::ScopedAStatus unregisterCallback(
+ const std::shared_ptr<IHealthInfoCallback>& in_callback) override;
+ ndk::ScopedAStatus update() override;
+ ndk::ScopedAStatus getChargeCounterUah(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getCurrentNowMicroamps(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getCurrentAverageMicroamps(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getCapacity(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getEnergyCounterNwh(int64_t* _aidl_return) override;
+ ndk::ScopedAStatus getChargeStatus(BatteryStatus* _aidl_return) override;
+ ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* _aidl_return) override;
+ ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* _aidl_return) override;
+ ndk::ScopedAStatus getHealthInfo(HealthInfo* _aidl_return) override;
+
+ private:
+ ::android::sp<HidlHealth> service_;
+ std::map<std::shared_ptr<IHealthInfoCallback>, ::android::sp<HidlHealthInfoCallback>>
+ callback_map_;
+};
+
+} // namespace aidl::android::hardware::health
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
new file mode 100644
index 0000000..1329679
--- /dev/null
+++ b/health/utils/libhealthshim/shim.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/hardware/health/translate-ndk.h>
+#include <health-shim/shim.h>
+
+using ::android::sp;
+using ::android::h2a::translate;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::health::V2_0::Result;
+using ::android::hardware::health::V2_0::toString;
+using ::ndk::ScopedAStatus;
+using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+using HidlHealthInfoCallback = ::android::hardware::health::V2_0::IHealthInfoCallback;
+using HidlHealthInfo = ::android::hardware::health::V2_0::HealthInfo;
+
+namespace aidl::android::hardware::health {
+
+namespace {
+
+class HealthInfoCallbackShim : public HidlHealthInfoCallback {
+ using AidlHealthInfoCallback = ::aidl::android::hardware::health::IHealthInfoCallback;
+ using AidlHealthInfo = ::aidl::android::hardware::health::HealthInfo;
+
+ public:
+ explicit HealthInfoCallbackShim(const std::shared_ptr<AidlHealthInfoCallback>& impl)
+ : impl_(impl) {}
+ Return<void> healthInfoChanged(const HidlHealthInfo& info) override {
+ AidlHealthInfo aidl_info;
+ // translate() should always return true.
+ CHECK(translate(info, &aidl_info));
+ // This is a oneway function, so we can't (and shouldn't) check for errors.
+ (void)impl_->healthInfoChanged(aidl_info);
+ return Void();
+ }
+
+ private:
+ std::shared_ptr<AidlHealthInfoCallback> impl_;
+};
+
+ScopedAStatus ResultToStatus(Result result) {
+ switch (result) {
+ case Result::SUCCESS:
+ return ScopedAStatus::ok();
+ case Result::NOT_SUPPORTED:
+ return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ case Result::UNKNOWN:
+ return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_UNKNOWN);
+ case Result::NOT_FOUND:
+ return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ case Result::CALLBACK_DIED:
+ return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_CALLBACK_DIED);
+ }
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ IHealth::STATUS_UNKNOWN, ("Unrecognized result value " + toString(result)).c_str());
+}
+
+template <typename T>
+ScopedAStatus ReturnAndResultToStatus(const Return<T>& ret, Result result) {
+ if (ret.isOk()) {
+ return ResultToStatus(result);
+ }
+ if (ret.isDeadObject()) {
+ return ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
+ }
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(IHealth::STATUS_UNKNOWN,
+ ret.description().c_str());
+}
+
+ScopedAStatus ReturnResultToStatus(const Return<Result>& return_result) {
+ return ReturnAndResultToStatus(return_result, return_result.isOk()
+ ? static_cast<Result>(return_result)
+ : Result::UNKNOWN);
+}
+
+} // namespace
+
+HealthShim::HealthShim(const sp<HidlHealth>& service) : service_(service) {}
+
+ScopedAStatus HealthShim::registerCallback(
+ const std::shared_ptr<IHealthInfoCallback>& in_callback) {
+ sp<HidlHealthInfoCallback> shim(new HealthInfoCallbackShim(in_callback));
+ callback_map_.emplace(in_callback, shim);
+ return ReturnResultToStatus(service_->registerCallback(shim));
+}
+
+ScopedAStatus HealthShim::unregisterCallback(
+ const std::shared_ptr<IHealthInfoCallback>& in_callback) {
+ auto it = callback_map_.find(in_callback);
+ if (it == callback_map_.end()) {
+ return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ sp<HidlHealthInfoCallback> shim = it->second;
+ callback_map_.erase(it);
+ return ReturnResultToStatus(service_->unregisterCallback(shim));
+}
+
+ScopedAStatus HealthShim::update() {
+ return ReturnResultToStatus(service_->update());
+}
+
+ScopedAStatus HealthShim::getChargeCounterUah(int32_t* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getChargeCounter([out, &out_result](auto result, auto value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ *out = value;
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCurrentNowMicroamps(int32_t* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getCurrentNow([out, &out_result](auto result, auto value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ *out = value;
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCurrentAverageMicroamps(int32_t* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getCurrentAverage([out, &out_result](auto result, auto value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ *out = value;
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCapacity(int32_t* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getCapacity([out, &out_result](auto result, auto value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ *out = value;
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getEnergyCounterNwh(int64_t* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getEnergyCounter([out, &out_result](auto result, auto value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ *out = value;
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getChargeStatus(BatteryStatus* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getChargeStatus([out, &out_result](auto result, auto value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ *out = static_cast<BatteryStatus>(value);
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getStorageInfo(std::vector<StorageInfo>* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getStorageInfo([out, &out_result](auto result, const auto& value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ out->clear();
+ out->reserve(value.size());
+ for (const auto& hidl_info : value) {
+ auto& aidl_info = out->emplace_back();
+ // translate() should always return true.
+ CHECK(translate(hidl_info, &aidl_info));
+ }
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getDiskStats(std::vector<DiskStats>* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getDiskStats([out, &out_result](auto result, const auto& value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ out->clear();
+ out->reserve(value.size());
+ for (const auto& hidl_info : value) {
+ auto& aidl_info = out->emplace_back();
+ // translate() should always return true.
+ CHECK(translate(hidl_info, &aidl_info));
+ }
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getHealthInfo(HealthInfo* out) {
+ Result out_result = Result::UNKNOWN;
+ auto ret = service_->getHealthInfo([out, &out_result](auto result, const auto& value) {
+ out_result = result;
+ if (out_result != Result::SUCCESS) return;
+ // translate() should always return true.
+ CHECK(translate(value, out));
+ });
+ return ReturnAndResultToStatus(ret, out_result);
+}
+
+} // namespace aidl::android::hardware::health
diff --git a/health/utils/libhealthshim/test.cpp b/health/utils/libhealthshim/test.cpp
new file mode 100644
index 0000000..d1dfb8b
--- /dev/null
+++ b/health/utils/libhealthshim/test.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <health-shim/shim.h>
+
+#include <android/hardware/health/translate-ndk.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using HidlHealth = android::hardware::health::V2_0::IHealth;
+using HidlHealthInfoCallback = android::hardware::health::V2_0::IHealthInfoCallback;
+using HidlStorageInfo = android::hardware::health::V2_0::StorageInfo;
+using HidlDiskStats = android::hardware::health::V2_0::DiskStats;
+using HidlHealthInfo = android::hardware::health::V2_0::HealthInfo;
+using HidlBatteryStatus = android::hardware::health::V1_0::BatteryStatus;
+using android::sp;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::health::V2_0::Result;
+using ndk::SharedRefBase;
+using testing::Invoke;
+using testing::NiceMock;
+
+namespace aidl::android::hardware::health {
+MATCHER(IsOk, "") {
+ *result_listener << "status is " << arg.getDescription();
+ return arg.isOk();
+}
+
+MATCHER_P(ExceptionIs, exception_code, "") {
+ *result_listener << "status is " << arg.getDescription();
+ return arg.getExceptionCode() == exception_code;
+}
+
+class MockHidlHealth : public HidlHealth {
+ public:
+ MOCK_METHOD(Return<Result>, registerCallback, (const sp<HidlHealthInfoCallback>& callback),
+ (override));
+ MOCK_METHOD(Return<Result>, unregisterCallback, (const sp<HidlHealthInfoCallback>& callback),
+ (override));
+ MOCK_METHOD(Return<Result>, update, (), (override));
+ MOCK_METHOD(Return<void>, getChargeCounter, (getChargeCounter_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getCurrentNow, (getCurrentNow_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getCurrentAverage, (getCurrentAverage_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getCapacity, (getCapacity_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getEnergyCounter, (getEnergyCounter_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getChargeStatus, (getChargeStatus_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getStorageInfo, (getStorageInfo_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getDiskStats, (getDiskStats_cb _hidl_cb), (override));
+ MOCK_METHOD(Return<void>, getHealthInfo, (getHealthInfo_cb _hidl_cb), (override));
+};
+
+class HealthShimTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ hidl = new NiceMock<MockHidlHealth>();
+ shim = SharedRefBase::make<HealthShim>(hidl);
+ }
+ sp<MockHidlHealth> hidl;
+ std::shared_ptr<IHealth> shim;
+};
+
+#define ADD_TEST(name, aidl_name, AidlValueType, hidl_value, not_supported_hidl_value) \
+ TEST_F(HealthShimTest, name) { \
+ ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \
+ cb(Result::SUCCESS, hidl_value); \
+ return Void(); \
+ })); \
+ AidlValueType value; \
+ ASSERT_THAT(shim->aidl_name(&value), IsOk()); \
+ ASSERT_EQ(value, static_cast<AidlValueType>(hidl_value)); \
+ } \
+ \
+ TEST_F(HealthShimTest, name##Unsupported) { \
+ ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \
+ cb(Result::NOT_SUPPORTED, not_supported_hidl_value); \
+ return Void(); \
+ })); \
+ AidlValueType value; \
+ ASSERT_THAT(shim->aidl_name(&value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \
+ }
+
+ADD_TEST(getChargeCounter, getChargeCounterUah, int32_t, 0xFEEDBEEF, 0)
+ADD_TEST(getCurrentNow, getCurrentNowMicroamps, int32_t, 0xC0FFEE, 0)
+ADD_TEST(getCurrentAverage, getCurrentAverageMicroamps, int32_t, 0xA2D401D, 0)
+ADD_TEST(getCapacity, getCapacity, int32_t, 77, 0)
+ADD_TEST(getEnergyCounter, getEnergyCounterNwh, int64_t, 0x1234567887654321, 0)
+ADD_TEST(getChargeStatus, getChargeStatus, BatteryStatus, HidlBatteryStatus::CHARGING,
+ HidlBatteryStatus::UNKNOWN)
+
+#undef ADD_TEST
+
+template <typename AidlValueType, typename HidlValueType>
+bool Translate(const HidlValueType& hidl_value, AidlValueType* aidl_value) {
+ return ::android::h2a::translate(hidl_value, aidl_value);
+}
+
+template <typename AidlValueType, typename HidlValueType>
+bool Translate(const std::vector<HidlValueType>& hidl_vec, std::vector<AidlValueType>* aidl_vec) {
+ aidl_vec->clear();
+ aidl_vec->reserve(hidl_vec.size());
+ for (const auto& hidl_value : hidl_vec) {
+ auto& aidl_value = aidl_vec->emplace_back();
+ if (!Translate(hidl_value, &aidl_value)) return false;
+ }
+ return true;
+}
+
+#define ADD_INFO_TEST(name, AidlValueType, hidl_value) \
+ TEST_F(HealthShimTest, name) { \
+ AidlValueType expected_aidl_value; \
+ ASSERT_TRUE(Translate(hidl_value, &expected_aidl_value)); \
+ ON_CALL(*hidl, name).WillByDefault(Invoke([&](auto cb) { \
+ cb(Result::SUCCESS, hidl_value); \
+ return Void(); \
+ })); \
+ AidlValueType aidl_value; \
+ ASSERT_THAT(shim->name(&aidl_value), IsOk()); \
+ ASSERT_EQ(aidl_value, expected_aidl_value); \
+ } \
+ \
+ TEST_F(HealthShimTest, name##Unsupported) { \
+ ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \
+ cb(Result::NOT_SUPPORTED, {}); \
+ return Void(); \
+ })); \
+ AidlValueType aidl_value; \
+ ASSERT_THAT(shim->name(&aidl_value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \
+ }
+
+ADD_INFO_TEST(getStorageInfo, std::vector<StorageInfo>,
+ (std::vector<HidlStorageInfo>{{
+ .lifetimeA = 15,
+ .lifetimeB = 18,
+ }}))
+
+ADD_INFO_TEST(getDiskStats, std::vector<DiskStats>,
+ (std::vector<HidlDiskStats>{{
+ .reads = 100,
+ .writes = 200,
+ }}))
+
+ADD_INFO_TEST(getHealthInfo, HealthInfo,
+ (HidlHealthInfo{
+ .batteryCurrentAverage = 999,
+ }))
+
+#undef ADD_INFO_TEST
+
+} // namespace aidl::android::hardware::health
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index a7be660..8e5a0ff 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -41,6 +41,10 @@
"general-tests",
"vts",
],
+ sanitize: {
+ cfi: false,
+ },
+
}
cc_test_library {
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index aebe8d9..0ad254d 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -5385,7 +5385,7 @@
* must be in the range [0, n).
*
* Outputs:
- * * 0: The reversed tensor.
+ * * 0: The reversed tensor of the same shape as the input tensor.
* For {@link OperandType::TENSOR_QUANT8_ASYMM} and
* {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensors,
* the scales and zeroPoint must be the same as input0.
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index c167a6d..9f530b3 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -645,6 +645,10 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+ return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
@@ -699,6 +703,10 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+ return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
@@ -752,6 +760,10 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+ return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 64550ef..73c3820 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -583,6 +583,7 @@
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
+ ASSERT_GT(attested_key_cert_chain.size(), 0);
CheckedDeleteKey(&attested_key_blob);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
@@ -612,6 +613,7 @@
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
+ ASSERT_GT(attested_key_cert_chain.size(), 0);
CheckedDeleteKey(&attested_key_blob);
CheckedDeleteKey(&attest_key.keyBlob);
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
index a5acdc1..53afef7 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -17,6 +17,7 @@
#include "FilterTests.h"
#include <inttypes.h>
+#include <algorithm>
#include <aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.h>
#include <aidlcommonsupport/NativeHandle.h>
@@ -31,23 +32,24 @@
mPidFilterOutputCount++;
mMsgCondition.signal();
- // HACK: we need to cast the const away as DemuxFilterEvent contains a ScopedFileDescriptor
- // that cannot be copied.
- for (auto&& e : const_cast<std::vector<DemuxFilterEvent>&>(events)) {
- auto it = mFilterEventPromises.find(e.getTag());
- if (it != mFilterEventPromises.cend()) {
- it->second.set_value(std::move(e));
- mFilterEventPromises.erase(it);
+ for (auto it = mFilterCallbackVerifiers.begin(); it != mFilterCallbackVerifiers.end();) {
+ auto& [verifier, promise] = *it;
+ if (verifier(events)) {
+ promise.set_value();
+ it = mFilterCallbackVerifiers.erase(it);
+ } else {
+ ++it;
}
- }
+ };
return ::ndk::ScopedAStatus::ok();
}
-std::future<DemuxFilterEvent> FilterCallback::getNextFilterEventWithTag(DemuxFilterEvent::Tag tag) {
- // Note: this currently only supports one future per DemuxFilterEvent::Tag.
- mFilterEventPromises[tag] = std::promise<DemuxFilterEvent>();
- return mFilterEventPromises[tag].get_future();
+std::future<void> FilterCallback::verifyFilterCallback(FilterCallbackVerifier&& verifier) {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+ mFilterCallbackVerifiers.emplace_back(std::move(verifier), std::move(promise));
+ return future;
}
void FilterCallback::testFilterDataOutput() {
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index 6258bac..f579441 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -60,9 +60,18 @@
class FilterCallback : public BnFilterCallback {
public:
+ /**
+ * A FilterCallbackVerifier is used to test and verify filter callbacks.
+ * The function should return true when a callback has been handled by this
+ * filter verifier. This will cause the associated future to be unblocked.
+ * If the function returns false, we continue to wait for future callbacks
+ * (the future remains blocked).
+ */
+ using FilterCallbackVerifier = std::function<bool(const std::vector<DemuxFilterEvent>&)>;
+
virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override;
- std::future<DemuxFilterEvent> getNextFilterEventWithTag(DemuxFilterEvent::Tag tag);
+ std::future<void> verifyFilterCallback(FilterCallbackVerifier&& verifier);
virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override {
return ::ndk::ScopedAStatus::ok();
@@ -85,7 +94,7 @@
int32_t mFilterId;
std::shared_ptr<IFilter> mFilter;
- std::unordered_map<DemuxFilterEvent::Tag, std::promise<DemuxFilterEvent>> mFilterEventPromises;
+ std::vector<std::pair<FilterCallbackVerifier, std::promise<void>>> mFilterCallbackVerifiers;
native_handle_t* mAvSharedHandle = nullptr;
uint64_t mAvSharedMemSize = -1;
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 88890e4..89e42df 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -640,10 +640,51 @@
testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
}
-// TODO: move boilerplate into text fixture
-TEST_P(TunerFilterAidlTest, FilterTimeDelayHintTest) {
- description("Test filter delay hint.");
+static bool isMediaFilter(const FilterConfig& filterConfig) {
+ switch (filterConfig.type.mainType) {
+ case DemuxFilterMainType::TS: {
+ // TS Audio and Video filters are media filters
+ auto tsFilterType =
+ filterConfig.type.subType.get<DemuxFilterSubType::Tag::tsFilterType>();
+ return (tsFilterType == DemuxTsFilterType::AUDIO ||
+ tsFilterType == DemuxTsFilterType::VIDEO);
+ }
+ case DemuxFilterMainType::MMTP: {
+ // MMTP Audio and Video filters are media filters
+ auto mmtpFilterType =
+ filterConfig.type.subType.get<DemuxFilterSubType::Tag::mmtpFilterType>();
+ return (mmtpFilterType == DemuxMmtpFilterType::AUDIO ||
+ mmtpFilterType == DemuxMmtpFilterType::VIDEO);
+ }
+ default:
+ return false;
+ }
+}
+static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event) {
+ switch (event.getTag()) {
+ case DemuxFilterEvent::Tag::section:
+ return event.get<DemuxFilterEvent::Tag::section>().dataLength;
+ case DemuxFilterEvent::Tag::media:
+ return event.get<DemuxFilterEvent::Tag::media>().dataLength;
+ case DemuxFilterEvent::Tag::pes:
+ return event.get<DemuxFilterEvent::Tag::pes>().dataLength;
+ case DemuxFilterEvent::Tag::download:
+ return event.get<DemuxFilterEvent::Tag::download>().dataLength;
+ case DemuxFilterEvent::Tag::ipPayload:
+ return event.get<DemuxFilterEvent::Tag::ipPayload>().dataLength;
+
+ case DemuxFilterEvent::Tag::tsRecord:
+ case DemuxFilterEvent::Tag::mmtpRecord:
+ case DemuxFilterEvent::Tag::temi:
+ case DemuxFilterEvent::Tag::monitorEvent:
+ case DemuxFilterEvent::Tag::startId:
+ return 0;
+ }
+}
+
+// TODO: move boilerplate into text fixture
+void TunerFilterAidlTest::testDelayHint(const FilterConfig& filterConf) {
int32_t feId;
int32_t demuxId;
std::shared_ptr<IDemux> demux;
@@ -657,40 +698,87 @@
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFilterTests.setDemux(demux);
- const auto& filterConf = filterMap[live.ipFilterId];
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
- ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
- ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
+ bool mediaFilter = isMediaFilter(filterConf);
auto filter = mFilterTests.getFilterById(filterId);
- auto delayValue = std::chrono::milliseconds(5000);
- FilterDelayHint delayHint;
- delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS;
- delayHint.hintValue = delayValue.count();
+ auto timeDelayInMs = std::chrono::milliseconds(filterConf.timeDelayInMs);
+ if (timeDelayInMs.count() > 0) {
+ FilterDelayHint delayHint;
+ delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS;
+ delayHint.hintValue = timeDelayInMs.count();
- auto status = filter->setDelayHint(delayHint);
- ASSERT_TRUE(status.isOk());
+ // setDelayHint should fail for media filters.
+ ASSERT_EQ(filter->setDelayHint(delayHint).isOk(), !mediaFilter);
+ }
- auto startTime = std::chrono::steady_clock::now();
- ASSERT_TRUE(mFilterTests.startFilter(filterId));
+ int dataDelayInBytes = filterConf.dataDelayInBytes;
+ if (dataDelayInBytes > 0) {
+ FilterDelayHint delayHint;
+ delayHint.hintType = FilterDelayHintType::DATA_SIZE_DELAY_IN_BYTES;
+ delayHint.hintValue = dataDelayInBytes;
- auto cb = mFilterTests.getFilterCallbacks().at(filterId);
- auto future = cb->getNextFilterEventWithTag(DemuxFilterEvent::Tag::ipPayload);
+ // setDelayHint should fail for media filters.
+ ASSERT_EQ(filter->setDelayHint(delayHint).isOk(), !mediaFilter);
+ }
- // block and wait for callback to be received.
- ASSERT_EQ(future.wait_for(std::chrono::seconds(10)), std::future_status::ready);
- auto duration = std::chrono::steady_clock::now() - startTime;
- ASSERT_GE(duration, delayValue);
+ // start and stop filter in order to circumvent callback scheduler race
+ // conditions after adjusting filter delays.
+ mFilterTests.startFilter(filterId);
+ mFilterTests.stopFilter(filterId);
- // cleanup
- ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+ if (!mediaFilter) {
+ auto cb = mFilterTests.getFilterCallbacks().at(filterId);
+ int callbackSize = 0;
+ auto future = cb->verifyFilterCallback(
+ [&callbackSize](const std::vector<DemuxFilterEvent>& events) {
+ for (const auto& event : events) {
+ callbackSize += getDemuxFilterEventDataLength(event);
+ }
+ return true;
+ });
+
+ // The configure stage can also produce events, so we should set the delay
+ // hint beforehand.
+ ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+
+ auto startTime = std::chrono::steady_clock::now();
+ ASSERT_TRUE(mFilterTests.startFilter(filterId));
+
+ // block and wait for callback to be received.
+ auto timeout = std::chrono::seconds(30);
+ ASSERT_EQ(future.wait_for(timeout), std::future_status::ready);
+ auto duration = std::chrono::steady_clock::now() - startTime;
+
+ bool delayHintTest = duration >= timeDelayInMs;
+ bool dataSizeTest = callbackSize >= dataDelayInBytes;
+
+ if (timeDelayInMs.count() > 0 && dataDelayInBytes > 0) {
+ ASSERT_TRUE(delayHintTest || dataSizeTest);
+ } else {
+ // if only one of time delay / data delay is configured, one of them
+ // holds true by default, so we want both assertions to be true.
+ ASSERT_TRUE(delayHintTest && dataSizeTest);
+ }
+
+ ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+ }
+
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
ASSERT_TRUE(mDemuxTests.closeDemux());
ASSERT_TRUE(mFrontendTests.closeFrontend());
}
+TEST_P(TunerFilterAidlTest, FilterDelayHintTest) {
+ description("Test filter time delay hint.");
+
+ for (const auto& obj : filterMap) {
+ testDelayHint(obj.second);
+ }
+}
+
TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
description("Feed ts data from playback and configure Ts section filter to get output");
if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index 13c5a80..7f80d90 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -140,6 +140,7 @@
void reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf,
FrontendConfig frontendConf);
void testTimeFilter(TimeFilterConfig filterConf);
+ void testDelayHint(const FilterConfig& filterConf);
DemuxFilterType getLinkageFilterType(int bit) {
DemuxFilterType type;
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 7ccf31a..b6cc5f8 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -96,6 +96,8 @@
AvStreamType streamType;
int32_t ipCid;
int32_t monitorEventTypes;
+ int timeDelayInMs = 0;
+ int dataDelayInBytes = 0;
bool operator<(const FilterConfig& /*c*/) const { return false; }
};
@@ -336,6 +338,12 @@
if (filterConfig.hasMonitorEventTypes()) {
filterMap[id].monitorEventTypes = (int32_t)filterConfig.getMonitorEventTypes();
}
+ if (filterConfig.hasTimeDelayInMs()) {
+ filterMap[id].timeDelayInMs = filterConfig.getTimeDelayInMs();
+ }
+ if (filterConfig.hasDataDelayInBytes()) {
+ filterMap[id].dataDelayInBytes = filterConfig.getDataDelayInBytes();
+ }
if (filterConfig.hasAvFilterSettings_optional()) {
auto av = filterConfig.getFirstAvFilterSettings_optional();
if (av->hasAudioStreamType_optional()) {
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index 6c637a4..db1d076 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -256,6 +256,7 @@
ctor public Filter();
method @Nullable public android.media.tuner.testing.configuration.V1_0.AvFilterSettings getAvFilterSettings_optional();
method @Nullable public java.math.BigInteger getBufferSize();
+ method @Nullable public java.math.BigInteger getDataDelayInBytes();
method @Nullable public String getId();
method @Nullable public android.media.tuner.testing.configuration.V1_0.IpFilterConfig getIpFilterConfig_optional();
method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum getMainType();
@@ -264,9 +265,11 @@
method @Nullable public android.media.tuner.testing.configuration.V1_0.RecordFilterSettings getRecordFilterSettings_optional();
method @Nullable public android.media.tuner.testing.configuration.V1_0.SectionFilterSettings getSectionFilterSettings_optional();
method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum getSubType();
+ method @Nullable public java.math.BigInteger getTimeDelayInMs();
method @Nullable public boolean getUseFMQ();
method public void setAvFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AvFilterSettings);
method public void setBufferSize(@Nullable java.math.BigInteger);
+ method public void setDataDelayInBytes(@Nullable java.math.BigInteger);
method public void setId(@Nullable String);
method public void setIpFilterConfig_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IpFilterConfig);
method public void setMainType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum);
@@ -275,6 +278,7 @@
method public void setRecordFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.RecordFilterSettings);
method public void setSectionFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.SectionFilterSettings);
method public void setSubType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum);
+ method public void setTimeDelayInMs(@Nullable java.math.BigInteger);
method public void setUseFMQ(@Nullable boolean);
}
diff --git a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
index 8a6229e..da77200 100644
--- a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -101,7 +101,7 @@
bufferSize="16777216" pid="257" useFMQ="false">
<recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
</filter>
- <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false">
+ <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false" timeDelayInMs="5000">
<ipFilterConfig ipCid="1">
<srcIpAddress isIpV4="true" ip="192 168 1 1"/>
<destIpAddress isIpV4="true" ip="192 168 1 1"/>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index fc2827f..54cedfc 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -243,6 +243,10 @@
"bufferSize": the buffer size of the filter in hex.
"pid": the pid that would be used to configure the filter.
"useFMQ": if the filter uses FMQ.
+ "timeDelayInMs": the filter's time delay hint. 0 by default. Must not be
+ longer than 30 seconds.
+ "dataDelayInBytes": the filter's data delay hint. 0 by default. Configured data
+ size must be received within 30 seconds.
Each filter element also contains at most one type-related "filterSettings".
- The settings type should match the filter "subType" attribute.
@@ -274,6 +278,8 @@
<xs:attribute name="pid" type="xs:nonNegativeInteger" use="optional"/>
<xs:attribute name="useFMQ" type="xs:boolean" use="required"/>
<xs:attribute name="monitorEventTypes" type="monitoEvents" use="optional"/>
+ <xs:attribute name="timeDelayInMs" type="xs:nonNegativeInteger" use="optional"/>
+ <xs:attribute name="dataDelayInBytes" type="xs:nonNegativeInteger" use="optional"/>
</xs:complexType>
<!-- DVR SESSION -->
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 5f56fe0..4bed2c7 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -21,11 +21,21 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+filegroup {
+ name: "android.hardware.usb@1.0-service.xml",
+ srcs: ["android.hardware.usb@1.0-service.xml"],
+}
+
+filegroup {
+ name: "android.hardware.usb@1.0-service.rc",
+ srcs: ["android.hardware.usb@1.0-service.rc"],
+}
+
cc_binary {
name: "android.hardware.usb@1.0-service",
defaults: ["hidl_defaults"],
- init_rc: ["android.hardware.usb@1.0-service.rc"],
- vintf_fragments: ["android.hardware.usb@1.0-service.xml"],
+ init_rc: [":android.hardware.usb@1.0-service.rc"],
+ vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
relative_install_path: "hw",
vendor: true,
srcs: [
diff --git a/usb/1.0/default/apex/Android.bp b/usb/1.0/default/apex/Android.bp
new file mode 100644
index 0000000..ee50fdf
--- /dev/null
+++ b/usb/1.0/default/apex/Android.bp
@@ -0,0 +1,59 @@
+// Copyright (C) 2021 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 {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+ name: "com.android.hardware.usb.key",
+ public_key: "com.android.hardware.usb.avbpubkey",
+ private_key: "com.android.hardware.usb.pem",
+}
+
+android_app_certificate {
+ name: "com.android.hardware.usb.certificate",
+ certificate: "com.android.hardware.usb",
+}
+
+genrule {
+ name: "com.android.hardware.usb.rc-gen",
+ srcs: [":android.hardware.usb@1.0-service.rc"],
+ out: ["com.android.hardware.usb.rc"],
+ cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+ name: "com.android.hardware.usb.rc",
+ src: ":com.android.hardware.usb.rc-gen",
+ installable: false,
+}
+
+apex {
+ name: "com.android.hardware.usb",
+ manifest: "manifest.json",
+ file_contexts: "file_contexts",
+ key: "com.android.hardware.usb.key",
+ certificate: ":com.android.hardware.usb.certificate",
+ updatable: false,
+ soc_specific: true,
+ use_vndk_as_stable: true,
+ binaries: ["android.hardware.usb@1.0-service"],
+ prebuilts: [
+ "com.android.hardware.usb.rc",
+ "android.hardware.usb.accessory.prebuilt.xml",
+ "android.hardware.usb.host.prebuilt.xml",
+ ],
+ vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
+}
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
new file mode 100644
index 0000000..0302d63
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pem b/usb/1.0/default/apex/com.android.hardware.usb.pem
new file mode 100644
index 0000000..e1e57da
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAwdimmHgIZHrep3H3YfVaNYEAGg45LUEPIiwHV6aIC9V7zjBS
+SftD30Z21jGyk7hmtas6WMI2vRBDNGrZWDgPeiEQoxXQinuU4Ug5S5X2F8LpWs0y
+ZeNFwQkqZwqGdQlkmy8upfb6T7rDxqRv+C0AtGP1r4r36+Xh5ld5stVaMK0UNhZt
+VW0nQAxyeJL3tm0zfiEA9Zu7FF2IyHm+bo9+eJ7WXfjiJfkclLgqlX3ec2cvVqAf
+NHisj18PEd/qtC64b+FnkgbsdHzWbo8HW5x4STkGXNnH+O3dvkWBX60MOfywfZFw
++yaz5mt7K+ft/V4UA7zKiAEFM+J1lND9/UMJnd0XMYYtcRQF8lmu4dlcjfbbAm0k
+VgoUEsizIeMPLrMj837uVloKKzIXmPsVsfMarP/MrX6TJfzdUhdm01pVO1g0wtHJ
+J3eYQsEnOI7RjL+uZDQvPWAnr71pvacn66PAJC1UPulEEla5lhd30RDItbJkngXp
+3UggW32ZOQt3Oc8P0eo9SCnBlHtCVr8wfxAbxCoPR9qIdX3azkQRqcKqGbBbPnkc
+hSCzeIofUkYGibfbZg4k1yY82xEqZuN7J1zycoGP4wyhXeRLTRWxfPR5dxxmQZaS
+67A1LWrYvAzF8Rd44VMRlI/Qk6zuBsL01j2dfBqit+le+viQmTYb3BpV+1kCAwEA
+AQKCAgAmSfX2LddyiXaLWo6DsePkp5tuihqvHqevl0TIAmPi+oMe4hqO9GueoZt9
+iYl9djILdkvrFkmbpKexpd1SeJhOBlPz8q4jfG+W5B41GOToIp7XSarHx1GS5I2U
+ltaiLX3KzVIIhDVDJF/hT7+yJKl7+DaiOu/nj5vEVMj8EvpinP1eBaYI9quHEi5W
+NKlrRjyikEBRQzZ7ulH3T1zXF87iYnVzUGLTH1aO5aW7q4YSA3KtSKmBQsjK9PrU
+DAefGY9iwgIkLOvtwm7UnbnVVZ3I0NO56WZ/e/SNzcrVLCg7F/eAhgbsBOQKAnbs
+4D35CuknJ9ZVcOYnLncNMw7IRMKULKYLAuLLN1X33y22qaVxYA42rq13mZrijlua
+CMQ2Ur+GNcq8OI3mRDO38yKeJ5b4885LQdlrXXyoGnSjlkU5n8U9Jw6q2rZGiWlk
+4Q71g+KUl0rtXSnFSIJLNTK6Cd3ETStxswLvvCvfLTrRQcO8f2SdVxblmsc9eCDs
+JUxz6Sahkpb9hsY8fozu6laXC/5Ezy0TinRgGjQM/DQqbXtFXgse56mDxzSho5oh
+Spy3X7Q/v4VUtrSKsEZEIEVWCpplzVULpHenCDbU58rHyEcS7ew+kwlfHC73iEhX
+HPujSIKvStO7yCEeY6IdhON8iVX34uvQeAgEe4+rehQHLZUg0QKCAQEA9AS3imKF
+yEt0yNRLcdXSqYkak+OM2kfhBBcLndCT7Terr6yluv/SkPGYjUbmr2XiygMv8IwO
+8f+KbWsNwYCaB22HVYVGL0oUYAlCvWhnia3Iwn6ZZuXuJv5mmfqt/GMlaIfohNLy
+zI2OlcpcAuRfNlenjNyd+inxwdXL28Z86kbabnUlijgqpu4KFOYOlxbTRv93IlfM
+Ico1pZkLS1glDMFLetF+IWq4zqpXrdgNUk1KX3sofOCfZQnlWFrrHbXJPCgPAtlv
+xP4dmJQgtWkWwxUlelfz34LcCUVX2aTlgKjuvgvyCt2ZPWixXbDtjsCBTn3xBhoY
+kDp2OyMC+d543QKCAQEAy11GpYOQvTMKbV07EmN9jTRYg7gRrxsT3Kd4Xy+NpIY8
+v6J5Keeppk9t6WBrJi2cQU/EoHcd3fRkWMnWMNorZDiCu34VG5bfa4pTqnSLdLC4
+/e5UHdHqCy9deAwhlHYWbAx0KnxXWGxkq05dXvQsVuOtAs528NcujnLpwDONQt5P
+e3RIZmOOjr+7rqGp3vA9SuNOINOQpeKxQT6GRGw4mlYofdwOPaE1wCsO8vQCNmCJ
+DEfdm+hWjTLAV2IBCfi5BKRsIAXrABPzkzDeLGDmaQkJTDpK8UQcrFnqItGeo+yl
+fDjxA0zAPWYGcyXcXbtvayX+zCk/SKwQABqUtaumrQKCAQEA0mdizwsGqd8OMsCC
+0QP64j4a0Zvqbqh9yCYK2Sfo9SkEe7SVLnm5WUtIK8EP1fs3ItK+ul454MZj2Nbv
+BINbzL3PbJk/HDV2/hveFS154UgcjD/XC9eEktDXLTvuW2ot7kUJ48V0n5YLdPMI
+hWHfCx9nlFkCSptyHp23aqhqOyOe4pFWLikh9c/Yl46K1BJVWKmcUtt7Y0NVIJWn
+HG9Dew0MhTkv1aaM9X4Bnh9l1SpZz5yFG7AfIGL5A0dZ5cNCYgF0eBN+gVBPuqk2
+ztVvUATizOwblwThr4jAKCU70sVXHj10lZPftwiXrt6I54brt/92HLnRpkMSgQk+
+Xq9KbQKCAQAXxPM47UPBmXGijr8UyyQlmPSvkJggi12q8LgVCA3aKQZ4r5jR2Q3v
+LmF+YZKkh7g3ugcValbHVoVUC2NJmnZv5FsDZx04eE3s1+Inji+ul+lHZM/YHGzq
+mcKnAWP7YkIEpv/850OeRi0OCL7JFmkITtwt88vbIouCgtPnbx8XrbxEhbbgoMpM
+zQQ2yRZ9xD6lviOnmpLRkMl/ArvWy39iKqfY7huMAIezylSY+QQ5LtdV5CB21JUp
+M8FfdUkBzVxyunUY2Rg6jhpuHcwaC8lihXfcvQN9Z6SiUHAZWb7dEg/VkSI6bIIb
+qw0d8FLtcbb4IxzA6CFJcTL9kB3JjiKRAoIBAQC15t3mQHb9iCM4P4U9fpR4syvN
+46vDMhtj3vejerzOro2R7UUCJDvT59DrCQvtKO/ZCyhdTyuyResu6r1vbwq3KWiB
+i0RIeW87cKgJRr6w+KivB+a805WfI9zNRz778b7ajEpBkOs4vRPWu6S1306tdvgM
+Dhj7GT9UFh/k7pNuoSbiuaPUqgZRP55nzgj/FoIN985wnxo/ugckSqZ1bFGFXhYt
+zfIdFvPkf1BlLCnLTE8yESsJ3P37Gfj2XRv9h2I2/8qAGZniKtbVWHlu+5LDJf6V
+x9VpDAH2ZQAqRC3za3gfTjMsglYi7mUDeMYlB4osURNt7jDtElEmsto7AAkI
+-----END RSA PRIVATE KEY-----
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pk8 b/usb/1.0/default/apex/com.android.hardware.usb.pk8
new file mode 100644
index 0000000..9f3f39b
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pk8
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.x509.pem b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
new file mode 100644
index 0000000..210c30d
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF1TCCA70CFFEdsyLGoTRk+VIzqb6aDl1tXeuZMA0GCSqGSIb3DQEBCwUAMIGl
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEhMB8GA1UEAwwYY29t
+LmFuZHJvaWQuaGFyZHdhcmUudXNiMCAXDTIxMTExNzIyMzAwM1oYDzQ3NTkxMDE0
+MjIzMDAzWjCBpTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAU
+BgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsM
+B0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb20xITAf
+BgNVBAMMGGNvbS5hbmRyb2lkLmhhcmR3YXJlLnVzYjCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAM2E0E9ubNU/or7r9UIcFrC4l7CeM0HwtwSjTUKV1Z9K
+7rPFoUPE3cQ+cResnWQay8IGnomLYptAIMe8sLCC83LwU1ucTihxX87qq2W3V14w
+U4AkqDzNvYqKiD3yz9WofKxcu7ut8+1O4Pvp11X8UXuy5kNzf8WGpGB04k6U6KtA
+q8+U8+4h9h1Uvhaa0AeG9Yp22LzRLTb3J+eCoGHJnjoXYsd9T/gvedyXKkuf0lWB
+b3Aor3/CQrpdCW2/iJbuASdBdfilpQShaagxy2wmQsYxnT8ZWf+tIDYjg3xqqVPl
+GChFwCQBdaTuLI/k9gbaXkSxuzRkp5wc/ELhYbkhIS25yefAF2C6num++AHQBh1+
+qO0fHztsK80c5cVoDPWu17/nP7y3QloRyLFUrL3hVW1RQaFwE2Hmv4H0UwVAsleU
+ZIsz2ifTjiSl/tnkFTx0I6BVk7T87QhO3WXN4v6VDYZKeD4gQYS0NfwplahejrFw
+s3EcwKgt6f0KlIpzoEQBmNQBXxsRgL31GWCwCszb7+VrTMzgUpO41R3PyewbeaZk
+S/SHyEOwyf0WIvnZhZ/5CNd9qirClu6jS8kdLvwC2qA25VqSPw126EX1e2xUqm02
+C/6c7JDVocuQhvsJOnnpZt68Iwgw9g/xLCLA9RszH9ccRctZqRnzHB1AjTrBOq0P
+AgMBAAEwDQYJKoZIhvcNAQELBQADggIBAELbSot2Io/JZIYLTxgeReI4lk1KUzf8
+fGlDNlRm+goxOHXWQgvXgiftwM9IOB+H+EtNHAA9Q6ojAmfRe6rZC4p0ZxWOamtR
+V+pQj0c6Zvx8HJPMQdyoHx538iNXM093s2wnf+QuACb3BnvkK7uuLGAlIzWdImtL
+DKKFN05nppViY04tGP5HgT57b7YGwdkEp6euCJcyWIKjlyEH/bwTWM8ws/Px6uhw
++5W2K7KrBsdRKPBF7qwXoS8Ak8pS5de9Xd7mbGBLaUtjsZ0pJbq0aFpuT0GbLWUm
+wiD5Ljq3ea/2GZxbHGiXQ2yNjFSd/jpuxDnnm99t7+HGw1v5Jld+hUVqXXfVNhWe
+hUKIv5TOk1nttNdsaLyDtxyt22JX7NnoPM0MqrkYwA8Xqrbv0VC8D/CVjiBC9Tce
+crhpCISNfQSkdEn/c+q/naFUvQy8oYqXkg1TjeGlcxwJOpGliYbbYT6VAwuI/ssI
+yX3Fkr8f5KhfN2aFnOpidknmLp9EyL2j5bxAtSD9xAHtczMn10uCUdLELjRB1L4f
+1qY+EjpIgK0NIFuEt9K5uZXirXq3K3eixKeJFNji3x/X8NgDALSdnT8JIlSg4DMg
+iWupLrQ9CSHMlgh5P43ALamiRIHQNqEwgj8OIGzsvQTSLbRjbPWYcDZa+Q1hosiA
+Fv7vjDI6oySM
+-----END CERTIFICATE-----
diff --git a/usb/1.0/default/apex/file_contexts b/usb/1.0/default/apex/file_contexts
new file mode 100644
index 0000000..bc84ac4
--- /dev/null
+++ b/usb/1.0/default/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)? u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)? u:object_r:vendor_configs_file:s0
+# binary
+/bin/hw/android\.hardware\.usb@1\.0-service u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
diff --git a/usb/1.0/default/apex/manifest.json b/usb/1.0/default/apex/manifest.json
new file mode 100644
index 0000000..6a1095f
--- /dev/null
+++ b/usb/1.0/default/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.usb",
+ "version": 1
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 774133e..7e3be56 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -35,4 +35,5 @@
@Backing(type="long") @VintfStability
enum UwbAndroidCapabilities {
POWER_STATS_QUERY = 1,
+ ANTENNAE_INTERLEAVING = 2,
}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 37b7efb..f449c60 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -38,4 +38,7 @@
CCC_UWB_CONFIG_ID = 164,
CCC_PULSESHAPE_COMBO = 165,
CCC_URSK_TTL = 166,
+ NB_OF_RANGE_MEASUREMENTS = 227,
+ NB_OF_AZIMUTH_MEASUREMENTS = 228,
+ NB_OF_ELEVATION_MEASUREMENTS = 229,
}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
index c4cb47b..c7708f1 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
@@ -40,6 +40,7 @@
void open(in android.hardware.uwb.IUwbClientCallback clientCallback);
void close();
void coreInit();
+ void sessionInit(int sessionId);
int getSupportedAndroidUciVersion();
long getSupportedAndroidCapabilities();
int sendUciMessage(in byte[] data);
diff --git a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
index 0c98611..f2bb0f1 100644
--- a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
@@ -50,6 +50,14 @@
void coreInit();
/**
+ * Perform any necessary UWB session initializations.
+ * This must be invoked by the framework at the beginging of every new ranging session.
+ *
+ * @param sessionId Session identifier as defined in the UCI specification.
+ */
+ void sessionInit(int sessionId);
+
+ /**
* Supported version of vendor UCI specification.
*
* @return Returns the version of the "android.hardware.uwb.fira_android" types-only
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 3486d5a..0af99e0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -26,6 +26,6 @@
@VintfStability
@Backing(type="long")
enum UwbAndroidCapabilities {
- /** TODO: Change the name if necessary when the corresponding vendor commands are added */
POWER_STATS_QUERY = 0x1,
+ ANTENNAE_INTERLEAVING = 0x2,
}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 850e2da..f5e02c0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -29,9 +29,29 @@
enum UwbVendorSessionSetAppConfigCmdParams {
/** CCC params for ranging start */
- /** Added in vendor version 0. */
+ /**
+ * Added in vendor version 0.
+ * Range 0xA0 - 0xDF reserved for CCC use.
+ */
CCC_RANGING_PROTOCOL_VER = 0xA3,
CCC_UWB_CONFIG_ID = 0xA4,
CCC_PULSESHAPE_COMBO = 0xA5,
CCC_URSK_TTL = 0xA6,
+
+ /**
+ * Range 0xE3 - 0xFF is reserved for proprietary use in the FIRA spec.
+ * In Android, this range is reserved by the Android platform for Android-specific
+ * app config cmd params.
+ * Vendors must not define additional app config cmd params in this range.
+ */
+
+ /**
+ * Added in vendor version 0.
+ * Interleaving ratio if AOA_RESULT_REQ is set to 0xF0.
+ * Supported only if the value returned by getSupportedAndroidCapabilities()
+ * has the bit of UwbAndroidCapabilities.ANTENNAE_INTERLEAVING set to 1.
+ */
+ NB_OF_RANGE_MEASUREMENTS = 0xE3,
+ NB_OF_AZIMUTH_MEASUREMENTS = 0xE4,
+ NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
}
diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp
index 10dbdb6..a5a3f4a 100644
--- a/uwb/aidl/default/uwb_chip.cpp
+++ b/uwb/aidl/default/uwb_chip.cpp
@@ -51,6 +51,10 @@
return ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus UwbChip::sessionInit(int /* sessionId */) {
+ return ndk::ScopedAStatus::ok();
+}
+
::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) {
*version = kAndroidUciVersion;
return ndk::ScopedAStatus::ok();
diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h
index ca97120..46cecd4 100644
--- a/uwb/aidl/default/uwb_chip.h
+++ b/uwb/aidl/default/uwb_chip.h
@@ -37,6 +37,7 @@
::ndk::ScopedAStatus open(const std::shared_ptr<IUwbClientCallback>& clientCallback) override;
::ndk::ScopedAStatus close() override;
::ndk::ScopedAStatus coreInit() override;
+ ::ndk::ScopedAStatus sessionInit(int sesionId) override;
::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override;
::ndk::ScopedAStatus getSupportedAndroidCapabilities(int64_t* capabilities) override;
::ndk::ScopedAStatus sendUciMessage(const std::vector<uint8_t>& data,
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 3820c0f..1da4432 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -166,6 +166,11 @@
EXPECT_TRUE(iuwb_chip->coreInit().isOk());
}
+TEST_P(UwbAidl, ChipSessionInit) {
+ const auto iuwb_chip = getAnyChipAndOpen();
+ EXPECT_TRUE(iuwb_chip->sessionInit(0).isOk());
+}
+
TEST_P(UwbAidl, ChipGetSupportedAndroidUciVersion) {
const auto iuwb_chip = getAnyChipAndOpen();
EXPECT_TRUE(iuwb_chip->coreInit().isOk());
diff --git a/weaver/aidl/default/Weaver.cpp b/weaver/aidl/default/Weaver.cpp
index 56d9c4d..6b77924 100644
--- a/weaver/aidl/default/Weaver.cpp
+++ b/weaver/aidl/default/Weaver.cpp
@@ -15,30 +15,52 @@
*/
#include "Weaver.h"
+#include <array>
namespace aidl {
namespace android {
namespace hardware {
namespace weaver {
+struct Slotinfo {
+ int slot_id;
+ std::vector<uint8_t> key;
+ std::vector<uint8_t> value;
+};
+
+std::array<struct Slotinfo, 16> slot_array;
// Methods from ::android::hardware::weaver::IWeaver follow.
::ndk::ScopedAStatus Weaver::getConfig(WeaverConfig* out_config) {
- (void)out_config;
+ *out_config = {16, 16, 16};
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus Weaver::read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* out_response) {
- (void)in_slotId;
- (void)in_key;
- (void)out_response;
+
+ if (in_slotId > 15 || in_key.size() > 16) {
+ *out_response = {0, {}};
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_FAILED));
+ }
+
+ if (slot_array[in_slotId].key != in_key) {
+ *out_response = {0, {}};
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_INCORRECT_KEY));
+ }
+
+ *out_response = {0, slot_array[in_slotId].value};
+
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus Weaver::write(int32_t in_slotId, const std::vector<uint8_t>& in_key, const std::vector<uint8_t>& in_value) {
- (void)in_slotId;
- (void)in_key;
- (void)in_value;
+
+ if (in_slotId > 15 || in_key.size() > 16 || in_value.size() > 16)
+ return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
+
+ slot_array[in_slotId].key = in_key;
+ slot_array[in_slotId].value = in_value;
+
return ::ndk::ScopedAStatus::ok();
}
diff --git a/wifi/netlinkinterceptor/aidl/Android.bp b/wifi/netlinkinterceptor/aidl/Android.bp
new file mode 100644
index 0000000..924edee
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/Android.bp
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+ name: "android.hardware.net.nlinterceptor",
+ vendor_available: true,
+ srcs: ["android/hardware/net/nlinterceptor/*.aidl"],
+ stability: "vintf",
+ backend: {
+ java: {
+ enabled: false,
+ },
+ },
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/netlinkinterceptor/aidl/aidl_api/NetlinkInterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/netlinkinterceptor/aidl/aidl_api/NetlinkInterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
index 41a1afe..249b343 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/netlinkinterceptor/aidl/aidl_api/NetlinkInterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * Copyright (C) 2021 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
+ * 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,
@@ -31,10 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.net.nlinterceptor;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+interface IInterceptor {
+ int createSocket(in int nlFamily, in int clientNlPid, in String clientName);
+ void closeSocket(in int nlFamily, in int interceptorNlPid);
+ void subscribeGroup(in int nlFamily, in int interceptorNlPid, in int nlGroup);
+ void unsubscribeGroup(in int nlFamily, in int interceptorNlPid, in int nlGroup);
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
similarity index 72%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
index 41a1afe..3d0f955 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * Copyright (C) 2021 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
+ * 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,
@@ -31,10 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
+package android.hardware.net.nlinterceptor;
@VintfStability
-parcelable ExecuteCommandsStatus {
- boolean queueChanged;
- int length;
- android.hardware.common.NativeHandle[] handles;
+interface IInterceptor {
+ android.hardware.net.nlinterceptor.InterceptedSocket createSocket(in int nlFamily, in int clientNlPid, in String clientName);
+ void closeSocket(in android.hardware.net.nlinterceptor.InterceptedSocket handle);
+ void subscribeGroup(in android.hardware.net.nlinterceptor.InterceptedSocket handle, in int nlGroup);
+ void unsubscribeGroup(in android.hardware.net.nlinterceptor.InterceptedSocket handle, in int nlGroup);
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
index cfafc50..b679be5 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * Copyright (C) 2021 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
+ * 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,
@@ -31,8 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
- CLEAR_CLIENT_TARGET = 1,
+package android.hardware.net.nlinterceptor;
+@VintfStability
+parcelable InterceptedSocket {
+ int nlFamily;
+ int portId;
}
diff --git a/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/IInterceptor.aidl b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/IInterceptor.aidl
new file mode 100644
index 0000000..c222a1e
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/IInterceptor.aidl
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021 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.net.nlinterceptor;
+
+import android.hardware.net.nlinterceptor.InterceptedSocket;
+
+/**
+ * Netlink Interceptor
+ *
+ * This HAL provides a way for Android services to route their Netlink traffic to a location other
+ * than the Kernel. One might want to do this for a variety of reasons:
+ * -> Route Netlink traffic to a different host.
+ * -> Route Netlink traffic to a different VM.
+ * -> Convert Netlink commands into proprietary vendor hardware commands.
+ *
+ * Some important notes regarding Netlink Interceptor.
+ * -> All int values are treated as unsigned.
+ * -> Users of Netlink Interceptor must close their sockets with closeSocket manually.
+ * -> PID != process ID. In this case, it is "port ID", a unique number assigned by the kernel to a
+ * given Netlink socket.
+ * -> Netlink PIDs are only unique per family. This means that for all NETLINK_GENERIC sockets,
+ * there can only be one socket with PID "1234". HOWEVER, there can ALSO be a Netlink socket
+ * using NETLINK_ROUTE which has a PID of "1234". Hence, in order to uniquely identify a Netlink
+ * socket, both the PID and Netlink Family are required.
+ */
+@VintfStability
+interface IInterceptor {
+ /**
+ * Creates a Netlink socket on both the HU and TCU, and a bi-directional gRPC stream to carry
+ * data between them. This must be closed by the caller with closeSocket().
+ *
+ * @param nlFamily - Netlink Family. Support for families other than NETLINK_GENERIC is still
+ * experimental.
+ * @param clientNlPid - Port ID of the caller's Netlink socket.
+ * @param clientName - Human readable name of the caller. Used for debugging.
+ *
+ * @return InterceptedSocket identifying the socket on the HU allocated for the caller.
+ */
+ InterceptedSocket createSocket(in int nlFamily, in int clientNlPid, in String clientName);
+
+ /**
+ * Closes a socket and gRPC stream given the socket's identifier. This must be invoked manually
+ * by the caller of createSocket().
+ *
+ * @param handle - unique identifier for a socket returned by createSocket.
+ */
+ void closeSocket(in InterceptedSocket handle);
+
+ /**
+ * Subscribes a socket on the TCU to a Netlink multicast group.
+ *
+ * @param handle - unique identifier for a socket returned by createSocket.
+ * @param nlGroup - A single Netlink multicast group that the caller wants to subscribe to.
+ */
+ void subscribeGroup(in InterceptedSocket handle, in int nlGroup);
+
+ /**
+ * Unsubscribes a socket on the TCU from a Netlink multicast group.
+ *
+ * @param handle - unique identifier for a socket returned by createSocket.
+ * @param nlGroup - A single Netlink multicast group that the caller wants to unsubscribe from.
+ */
+ void unsubscribeGroup(in InterceptedSocket handle, in int nlGroup);
+}
diff --git a/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/InterceptedSocket.aidl b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
new file mode 100644
index 0000000..d74a556
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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.net.nlinterceptor;
+
+/**
+ * Unique identifier for a Netlink socket.
+ */
+@VintfStability
+parcelable InterceptedSocket {
+ /**
+ * Netlink family of the identified socket
+ */
+ int nlFamily;
+
+ /**
+ * Netlink port ID of the identified socket.
+ */
+ int portId;
+}
diff --git a/wifi/netlinkinterceptor/aidl/default/Android.bp b/wifi/netlinkinterceptor/aidl/default/Android.bp
new file mode 100644
index 0000000..5227e51
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/Android.bp
@@ -0,0 +1,48 @@
+//
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+ name: "android.hardware.net.nlinterceptor-service.default",
+ init_rc: ["nlinterceptor-default.rc"],
+ vintf_fragments: ["nlinterceptor-default.xml"],
+ vendor: true,
+ relative_install_path: "hw",
+ defaults: ["nlinterceptor@defaults"],
+ shared_libs: [
+ "android.hardware.net.nlinterceptor-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "libnlinterceptor",
+ "libnl++",
+ ],
+ srcs: [
+ "InterceptorRelay.cpp",
+ "NetlinkInterceptor.cpp",
+ "service.cpp",
+ "util.cpp",
+ ],
+}
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
new file mode 100644
index 0000000..ded9122
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "InterceptorRelay.h"
+
+#include <android-base/logging.h>
+#include <libnl++/printer.h>
+#include <poll.h>
+
+#include <chrono>
+
+#include "util.h"
+
+namespace android::nlinterceptor {
+using namespace std::chrono_literals;
+
+static constexpr std::chrono::milliseconds kPollTimeout = 300ms;
+static constexpr bool kSuperVerbose = true;
+
+InterceptorRelay::InterceptorRelay(uint32_t nlFamily, uint32_t clientNlPid,
+ const std::string& clientName)
+ : mClientName(clientName),
+ mNlSocket(std::make_optional<nl::Socket>(nlFamily, 0, 0)),
+ mClientNlPid(clientNlPid) {}
+
+InterceptorRelay::~InterceptorRelay() {
+ mRunning = false;
+ if (mRelayThread.joinable()) mRelayThread.join();
+}
+
+uint32_t InterceptorRelay::getPid() {
+ auto pidMaybe = mNlSocket->getPid();
+ CHECK(pidMaybe.has_value()) << "Failed to get pid of nl::Socket!";
+ return *pidMaybe;
+}
+
+void InterceptorRelay::relayMessages() {
+ pollfd fds[] = {
+ mNlSocket->preparePoll(POLLIN),
+ };
+ while (mRunning) {
+ if (poll(fds, countof(fds), kPollTimeout.count()) < 0) {
+ PLOG(FATAL) << "poll failed";
+ return;
+ }
+ const auto nlsockEvents = fds[0].revents;
+
+ if (isSocketBad(nlsockEvents)) {
+ LOG(ERROR) << "Netlink socket is bad";
+ mRunning = false;
+ return;
+ }
+ if (!isSocketReadable(nlsockEvents)) continue;
+
+ const auto [msgMaybe, sa] = mNlSocket->receiveFrom();
+ if (!msgMaybe.has_value()) {
+ LOG(ERROR) << "Failed to receive Netlink data!";
+ mRunning = false;
+ return;
+ }
+ const auto msg = *msgMaybe;
+ if (!msg.firstOk()) {
+ LOG(ERROR) << "Netlink packet is malformed!";
+ // Test messages might be empty, this isn't fatal.
+ continue;
+ }
+ if constexpr (kSuperVerbose) {
+ LOG(VERBOSE) << "[" << mClientName
+ << "] nlMsg: " << nl::toString(msg, NETLINK_GENERIC);
+ }
+
+ uint32_t destinationPid = 0;
+ if (sa.nl_pid == 0) {
+ destinationPid = mClientNlPid;
+ }
+
+ if (!mNlSocket->send(msg, destinationPid)) {
+ LOG(ERROR) << "Failed to send Netlink message!";
+ mRunning = false;
+ return;
+ }
+ }
+ LOG(VERBOSE) << "[" << mClientName << "] Exiting relay thread!";
+}
+
+bool InterceptorRelay::start() {
+ if (mRunning) {
+ LOG(ERROR)
+ << "Can't relay messages: InterceptorRelay is already running!";
+ return false;
+ }
+ if (mRelayThread.joinable()) {
+ LOG(ERROR) << "relay thread is already running!";
+ return false;
+ }
+ if (!mNlSocket.has_value()) {
+ LOG(ERROR) << "Netlink socket not initialized!";
+ return false;
+ }
+
+ mRunning = true;
+ mRelayThread = std::thread(&InterceptorRelay::relayMessages, this);
+
+ LOG(VERBOSE) << "Relay threads initialized";
+ return true;
+}
+
+bool InterceptorRelay::subscribeGroup(uint32_t nlGroup) {
+ return mNlSocket->addMembership(nlGroup);
+}
+
+bool InterceptorRelay::unsubscribeGroup(uint32_t nlGroup) {
+ return mNlSocket->dropMembership(nlGroup);
+}
+
+} // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h
new file mode 100644
index 0000000..0178c90
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <libnl++/Socket.h>
+
+#include <mutex>
+#include <thread>
+
+namespace android::nlinterceptor {
+
+class InterceptorRelay {
+ public:
+ /**
+ * Wrapper around the netlink socket and thread which relays messages.
+ *
+ * \param nlFamily - netlink family to use for the netlink socket.
+ * \param clientNlPid - pid of the client netlink socket.
+ * \param clientName - name of the client to be used for debugging.
+ */
+ InterceptorRelay(uint32_t nlFamily, uint32_t clientNlPid,
+ const std::string& clientName);
+
+ /**
+ * Stops the relay thread if running and destroys itself.
+ */
+ ~InterceptorRelay();
+
+ /**
+ * Returns the PID of the internal Netlink socket.
+ *
+ * \return value of PID,
+ */
+ uint32_t getPid();
+
+ /**
+ * Spawns relay thread.
+ */
+ bool start();
+
+ /**
+ * Subscribes the internal socket to a single Netlink multicast group.
+ *
+ * \param nlGroup - Netlink group to subscribe to.
+ * \returns - true for success, false for failure.
+ */
+ bool subscribeGroup(uint32_t nlGroup);
+
+ /**
+ * Unsubscribes the internal socket from a single Netlink multicast group.
+ *
+ * \param nlGroup - Netlink group to unsubscribe from.
+ * \returns - true for success, false for failure.
+ */
+ bool unsubscribeGroup(uint32_t nlGroup);
+
+ private:
+ std::string mClientName; ///< Name of client (Wificond, for example).
+ std::optional<nl::Socket> mNlSocket;
+ const uint32_t mClientNlPid = 0; ///< pid of client NL socket.
+
+ /**
+ * If set to true, the relay thread should be running. Setting this to false
+ * stops the relay thread.
+ */
+ std::atomic_bool mRunning = false;
+
+ /**
+ * Reads incoming Netlink messages destined for mNlSocket. If from the
+ * kernel, the message is relayed to the client specified in the
+ * constructor. Otherwise, the message is relayed to the kernel. This will
+ * run as long as mRunning is set to true.
+ */
+ void relayMessages();
+
+ std::thread mRelayThread;
+};
+
+} // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.cpp b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.cpp
new file mode 100644
index 0000000..908ecf2
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "NetlinkInterceptor.h"
+
+#include <android-base/logging.h>
+#include <libnl++/Socket.h>
+
+namespace android::nlinterceptor {
+
+ndk::ScopedAStatus NetlinkInterceptor::createSocket(
+ int32_t nlFamilyAidl, int32_t clientNlPidAidl,
+ const std::string& clientName, AidlInterceptedSocket* interceptedSocket) {
+ auto nlFamily = static_cast<uint32_t>(nlFamilyAidl);
+ auto clientNlPid = static_cast<uint32_t>(clientNlPidAidl);
+ uint32_t interceptorNlPid = 0;
+
+ std::unique_ptr<InterceptorRelay> interceptor =
+ std::make_unique<InterceptorRelay>(nlFamily, clientNlPid, clientName);
+
+ interceptorNlPid = interceptor->getPid();
+
+ if (interceptorNlPid == 0) {
+ LOG(ERROR) << "Failed to create a Netlink socket for " << clientName
+ << ", " << nlFamily << ":" << clientNlPid;
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+
+ if (mClientMap.find({nlFamily, interceptorNlPid}) != mClientMap.end()) {
+ LOG(ERROR) << "A socket with pid " << interceptorNlPid
+ << " already exists!";
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+
+ if (!interceptor->start()) {
+ LOG(ERROR) << "Failed to start interceptor thread!";
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+
+ if (!mClientMap
+ .emplace(InterceptedSocket(nlFamily, interceptorNlPid),
+ std::move(interceptor))
+ .second) {
+ // If this happens, it is very bad.
+ LOG(FATAL) << "Failed to insert interceptor instance with pid "
+ << interceptorNlPid << " into map!";
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+
+ interceptedSocket->nlFamily = nlFamily;
+ interceptedSocket->portId = interceptorNlPid;
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus NetlinkInterceptor::closeSocket(
+ const AidlInterceptedSocket& interceptedSocket) {
+ InterceptedSocket sock(interceptedSocket);
+
+ auto interceptorIt = mClientMap.find(sock);
+ if (interceptorIt == mClientMap.end()) {
+ LOG(ERROR) << "closeSocket Failed! No such socket " << sock;
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+ mClientMap.erase(interceptorIt);
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus NetlinkInterceptor::subscribeGroup(
+ const AidlInterceptedSocket& interceptedSocket, int32_t nlGroupAidl) {
+ InterceptedSocket sock(interceptedSocket);
+ auto nlGroup = static_cast<uint32_t>(nlGroupAidl);
+
+ auto interceptorIt = mClientMap.find(sock);
+ if (interceptorIt == mClientMap.end()) {
+ LOG(ERROR) << "subscribeGroup failed! No such socket " << sock;
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+
+ auto& interceptor = interceptorIt->second;
+ if (!interceptor->subscribeGroup(nlGroup)) {
+ LOG(ERROR) << "Failed to subscribe " << sock << " to " << nlGroup;
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus NetlinkInterceptor::unsubscribeGroup(
+ const AidlInterceptedSocket& interceptedSocket, int32_t nlGroupAidl) {
+ InterceptedSocket sock(interceptedSocket);
+ auto nlGroup = static_cast<uint32_t>(nlGroupAidl);
+
+ auto interceptorIt = mClientMap.find(sock);
+ if (interceptorIt == mClientMap.end()) {
+ LOG(ERROR) << "unsubscribeGroup failed! No such socket " << sock;
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+
+ auto& interceptor = interceptorIt->second;
+ if (!interceptor->unsubscribeGroup(nlGroup)) {
+ LOG(ERROR) << "Failed to unsubscribe " << sock << " from " << nlGroup;
+ return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+ }
+ return ndk::ScopedAStatus::ok();
+}
+} // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.h b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.h
new file mode 100644
index 0000000..8345654
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/net/nlinterceptor/BnInterceptor.h>
+#include <libnlinterceptor/libnlinterceptor.h>
+
+#include <map>
+
+#include "InterceptorRelay.h"
+
+namespace android::nlinterceptor {
+
+class NetlinkInterceptor
+ : public ::aidl::android::hardware::net::nlinterceptor::BnInterceptor {
+ using ClientMap =
+ std::map<::android::nlinterceptor::InterceptedSocket,
+ std::unique_ptr<::android::nlinterceptor::InterceptorRelay>>;
+
+ using AidlInterceptedSocket =
+ ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket;
+
+ public:
+ ndk::ScopedAStatus createSocket(
+ int32_t nlFamily, int32_t clientNlPid, const std::string& clientName,
+ AidlInterceptedSocket* interceptedSocket) override;
+
+ ndk::ScopedAStatus closeSocket(
+ const AidlInterceptedSocket& interceptedSocket) override;
+
+ ndk::ScopedAStatus subscribeGroup(
+ const AidlInterceptedSocket& interceptedSocket,
+ int32_t nlGroup) override;
+
+ ndk::ScopedAStatus unsubscribeGroup(
+ const AidlInterceptedSocket& interceptedSocket,
+ int32_t nlGroup) override;
+
+ private:
+ ClientMap mClientMap;
+};
+
+} // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/OWNERS b/wifi/netlinkinterceptor/aidl/default/OWNERS
new file mode 100644
index 0000000..b738dac
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/OWNERS
@@ -0,0 +1,2 @@
+chrisweir@google.com
+twasilczyk@google.com
diff --git a/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.rc b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.rc
new file mode 100644
index 0000000..353cb27
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.rc
@@ -0,0 +1,4 @@
+service nlinterceptor /vendor/bin/hw/android.hardware.net.nlinterceptor-service.default
+ class hal
+ user root
+ group system inet
diff --git a/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.xml b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.xml
new file mode 100644
index 0000000..d7d257e
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.xml
@@ -0,0 +1,9 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.net.nlinterceptor</name>
+ <interface>
+ <name>IInterceptor</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/wifi/netlinkinterceptor/aidl/default/service.cpp b/wifi/netlinkinterceptor/aidl/default/service.cpp
new file mode 100644
index 0000000..2aec3a5
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/service.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "NetlinkInterceptor.h"
+
+namespace android::nlinterceptor {
+using namespace std::string_literals;
+
+static void service() {
+ base::SetDefaultTag("nlinterceptor");
+ base::SetMinimumLogSeverity(base::VERBOSE);
+ LOG(DEBUG) << "Netlink Interceptor service starting...";
+
+ // TODO(202549296): Sometimes this causes an Address Sanitizer error.
+ auto interceptor = ndk::SharedRefBase::make<NetlinkInterceptor>();
+ const auto instance = NetlinkInterceptor::descriptor + "/default"s;
+ const auto status = AServiceManager_addService(
+ interceptor->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ LOG(FATAL) << "Netlink Interceptor has stopped";
+}
+
+} // namespace android::nlinterceptor
+
+int main() {
+ ::android::nlinterceptor::service();
+ return 0;
+}
diff --git a/wifi/netlinkinterceptor/aidl/default/util.cpp b/wifi/netlinkinterceptor/aidl/default/util.cpp
new file mode 100644
index 0000000..c734747
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/util.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "util.h"
+
+#include <poll.h>
+
+namespace android::nlinterceptor {
+
+bool isSocketReadable(const short revents) { return 0 != (revents & POLLIN); }
+
+bool isSocketBad(const short revents) {
+ return 0 != (revents & (POLLERR | POLLHUP | POLLNVAL));
+}
+
+} // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/util.h b/wifi/netlinkinterceptor/aidl/default/util.h
new file mode 100644
index 0000000..9b8ec63
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/util.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+
+#include <functional>
+
+namespace android::nlinterceptor {
+
+/**
+ * Handy-dandy helper to get the size of a statically initialized array.
+ *
+ * \param N the array to get the size of.
+ * \return the size of the array.
+ */
+template <typename T, size_t N>
+size_t countof(T (&)[N]) {
+ return N;
+}
+
+/**
+ * Helper to check if socket is readable (POLLIN is set).
+ *
+ * \param revents pollfd.revents value to check.
+ * \return true if socket is ready to read.
+ */
+bool isSocketReadable(short revents);
+
+/**
+ * Helper to check if socket is bad (POLLERR, POLLHUP or POLLNVAL is set).
+ *
+ * \param revents pollfd.revents value to check.
+ * \return true if socket is bad.
+ */
+bool isSocketBad(short revents);
+
+} // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/Android.bp b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
new file mode 100644
index 0000000..00cae32
--- /dev/null
+++ b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
@@ -0,0 +1,65 @@
+//
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_defaults {
+ name: "nlinterceptor@defaults",
+ cpp_std: "experimental",
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wsuggest-override",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libbase",
+ "libutils",
+ ],
+ sanitize: {
+ address: true,
+ undefined: true,
+ all_undefined: true,
+ fuzzer: true,
+ cfi: true,
+ integer_overflow: true,
+ scs: true,
+ },
+ strip: {
+ keep_symbols_and_debug_frame: true,
+ },
+}
+
+cc_library_static {
+ name: "libnlinterceptor",
+ defaults: ["nlinterceptor@defaults"],
+ vendor_available: true,
+ shared_libs: [
+ "android.hardware.net.nlinterceptor-V1-ndk",
+ "libbinder_ndk",
+ ],
+ srcs: [
+ "libnlinterceptor.cpp",
+ ],
+ export_include_dirs: ["include"],
+}
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
new file mode 100644
index 0000000..ac8653e
--- /dev/null
+++ b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+
+#include <aidl/android/hardware/net/nlinterceptor/InterceptedSocket.h>
+#include <android-base/unique_fd.h>
+#include <linux/netlink.h>
+
+#include <optional>
+#include <string>
+
+namespace android::nlinterceptor {
+
+/**
+ * Wrapper structure to uniquely identifies a socket that Netlink Interceptor
+ * has allocated for us.
+ */
+struct InterceptedSocket {
+ uint32_t nlFamily;
+ uint32_t portId;
+
+ InterceptedSocket(
+ ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket sock);
+ InterceptedSocket(uint32_t nlFamily, uint32_t portId);
+
+ bool operator<(const InterceptedSocket& other) const;
+ operator sockaddr_nl() const;
+ operator ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket()
+ const;
+};
+
+/**
+ * Output stream operator for InterceptedSocket
+ */
+std::ostream& operator<<(std::ostream& os, const InterceptedSocket& sock);
+
+/**
+ * Checks if an instance Netlink Interceptor exists.
+ *
+ * \return true if supported, false if not.
+ */
+bool isEnabled();
+
+/**
+ * Asks Netlink Interceptor to allocate a socket to which we can send Netlink
+ * traffic.
+ *
+ * \param clientSocket - File descriptor for the client's Netlink socket.
+ * \param clientName - Human readable name of the client application.
+ * \return Identifier for the socket created by Netlink Interceptor, nullopt on
+ * error.
+ */
+std::optional<InterceptedSocket> createSocket(base::borrowed_fd clientSocket,
+ const std::string& clientName);
+
+/**
+ * Asks Netlink Interceptor to close a socket that it created for us previously,
+ * if it exists.
+ *
+ * \param sock - Identifier for the socket created by Netlink Interceptor.
+ */
+void closeSocket(const InterceptedSocket& sock);
+
+/**
+ * Asks Netlink Interceptor to subscribe a socket that it created for us
+ * previously to a specified multicast group.
+ *
+ * \param sock - Identifier for the socket created by Netlink Interceptor.
+ * \param group - A single Netlink multicast group for which we would like to
+ * receive events.
+ * \return true for success, false if something went wrong.
+ */
+bool subscribe(const InterceptedSocket& sock, uint32_t group);
+
+/**
+ * Asks Netlink Interceptor to unsubscribe a socket that it created for us
+ * previously from a specified multicast group.
+ *
+ * \param sock - Identifier for the socket created by Netlink Interceptor.
+ * \param group - A single Netlink multicast group for which we no longer wish
+ * to receive events.
+ * \return true for success, false if something went wrong.
+ */
+bool unsubscribe(const InterceptedSocket& sock, uint32_t group);
+} // namespace android::nlinterceptor
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers for libnlinterceptor
+struct android_nlinterceptor_InterceptedSocket {
+ uint32_t nlFamily;
+ uint32_t portId;
+};
+
+bool android_nlinterceptor_isEnabled();
+
+bool android_nlinterceptor_createSocket(
+ int clientSocketFd, const char* clientName,
+ struct android_nlinterceptor_InterceptedSocket* interceptedSocket);
+
+void android_nlinterceptor_closeSocket(
+ const struct android_nlinterceptor_InterceptedSocket* sock);
+
+bool android_nlinterceptor_subscribe(
+ const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+
+bool android_nlinterceptor_unsubscribe(
+ const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
new file mode 100644
index 0000000..575f900
--- /dev/null
+++ b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <aidl/android/hardware/net/nlinterceptor/IInterceptor.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android/binder_manager.h>
+#include <libnlinterceptor/libnlinterceptor.h>
+#include <linux/netlink.h>
+
+#include <mutex>
+
+namespace android::nlinterceptor {
+using namespace std::string_literals;
+using namespace ::aidl::android::hardware::net::nlinterceptor;
+using base::borrowed_fd;
+using AidlInterceptedSocket =
+ ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket;
+
+static const auto kServiceName = IInterceptor::descriptor + "/default"s;
+
+InterceptedSocket::InterceptedSocket(
+ ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket sock)
+ : nlFamily(sock.nlFamily), portId(sock.portId) {}
+
+InterceptedSocket::InterceptedSocket(uint32_t nlFamily, uint32_t portId)
+ : nlFamily(nlFamily), portId(portId) {}
+
+std::ostream& operator<<(std::ostream& os, const InterceptedSocket& sock) {
+ return os << "family: " << sock.nlFamily << ", portId: " << sock.portId;
+}
+
+bool InterceptedSocket::operator<(const InterceptedSocket& other) const {
+ if (nlFamily != other.nlFamily) {
+ return nlFamily < other.nlFamily;
+ }
+ return portId < other.portId;
+}
+
+InterceptedSocket::operator sockaddr_nl() const {
+ return {
+ .nl_family = AF_NETLINK,
+ .nl_pad = 0,
+ .nl_pid = portId,
+ .nl_groups = 0,
+ };
+}
+
+InterceptedSocket::operator AidlInterceptedSocket() const {
+ return {
+ .nlFamily = static_cast<int32_t>(nlFamily),
+ .portId = static_cast<int32_t>(portId),
+ };
+}
+
+bool isEnabled() {
+ static std::mutex supportedMutex;
+ static std::optional<bool> interceptorSupported;
+ // Avoid querying service manager when we can cache the result.
+ if (interceptorSupported.has_value()) return *interceptorSupported;
+ std::lock_guard lock(supportedMutex);
+ if (interceptorSupported.has_value()) return *interceptorSupported;
+
+ if (!AServiceManager_isDeclared(kServiceName.c_str())) {
+ interceptorSupported = false;
+ return false;
+ }
+ interceptorSupported = true;
+ return true;
+}
+
+static IInterceptor& getInstance() {
+ static std::mutex instanceMutex;
+ static std::shared_ptr<IInterceptor> interceptorInstance;
+ CHECK(isEnabled()) << "Can't getInstance! Interceptor not supported!";
+ // Don't overwrite the pointer once we've acquired it.
+ if (interceptorInstance != nullptr) return *interceptorInstance;
+ std::lock_guard lock(instanceMutex);
+ if (interceptorInstance != nullptr) return *interceptorInstance;
+ interceptorInstance = IInterceptor::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(kServiceName.c_str())));
+ CHECK(interceptorInstance != nullptr)
+ << "Failed to get Netlink Interceptor service!";
+ return *interceptorInstance;
+}
+
+std::optional<InterceptedSocket> createSocket(borrowed_fd clientSocket,
+ const std::string& clientName) {
+ sockaddr_nl nladdr = {};
+ socklen_t nlsize = sizeof(nladdr);
+ if (getsockname(clientSocket.get(), reinterpret_cast<sockaddr*>(&nladdr),
+ &nlsize) < 0) {
+ PLOG(ERROR) << "Failed to get pid of fd passed by " << clientName;
+ return std::nullopt;
+ }
+
+ ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket
+ interceptedSocket;
+ auto aidlStatus = getInstance().createSocket(
+ nladdr.nl_family, nladdr.nl_pid, clientName, &interceptedSocket);
+ if (!aidlStatus.isOk()) {
+ return std::nullopt;
+ }
+
+ return InterceptedSocket{nladdr.nl_family,
+ uint32_t(interceptedSocket.portId)};
+}
+
+void closeSocket(const InterceptedSocket& sock) {
+ auto aidlStatus = getInstance().closeSocket(sock);
+ if (!aidlStatus.isOk()) {
+ LOG(ERROR) << "Failed to close socket with pid = " << sock.portId;
+ }
+}
+
+bool subscribe(const InterceptedSocket& sock, uint32_t group) {
+ auto aidlStatus = getInstance().subscribeGroup(sock, group);
+ return aidlStatus.isOk();
+}
+
+bool unsubscribe(const InterceptedSocket& sock, uint32_t group) {
+ auto aidlStatus = getInstance().unsubscribeGroup(sock, group);
+ return aidlStatus.isOk();
+}
+
+extern "C" bool android_nlinterceptor_isEnabled() { return isEnabled(); }
+
+extern "C" bool android_nlinterceptor_createSocket(
+ int clientSocketFd, const char* clientName,
+ android_nlinterceptor_InterceptedSocket* interceptedSocket) {
+ if (!clientName || clientSocketFd <= 0) return false;
+ const auto maybeSocket =
+ createSocket(borrowed_fd(clientSocketFd), clientName);
+ if (!maybeSocket) return false;
+ *interceptedSocket = {.nlFamily = maybeSocket->nlFamily,
+ .portId = maybeSocket->portId};
+ return true;
+}
+
+extern "C" void android_nlinterceptor_closeSocket(
+ const android_nlinterceptor_InterceptedSocket* sock) {
+ if (!sock) {
+ LOG(ERROR) << "Can't close socket identified by a null pointer!";
+ return;
+ }
+ closeSocket({sock->nlFamily, sock->portId});
+}
+
+extern "C" bool android_nlinterceptor_subscribe(
+ const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
+ if (!sock) return false;
+ return subscribe({sock->nlFamily, sock->portId}, group);
+}
+
+extern "C" bool android_nlinterceptor_unsubscribe(
+ const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
+ if (!sock) return false;
+ return unsubscribe({sock->nlFamily, sock->portId}, group);
+}
+
+} // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/vts/OWNERS b/wifi/netlinkinterceptor/vts/OWNERS
new file mode 100644
index 0000000..b738dac
--- /dev/null
+++ b/wifi/netlinkinterceptor/vts/OWNERS
@@ -0,0 +1,2 @@
+chrisweir@google.com
+twasilczyk@google.com
diff --git a/wifi/netlinkinterceptor/vts/functional/Android.bp b/wifi/netlinkinterceptor/vts/functional/Android.bp
new file mode 100644
index 0000000..33284e8
--- /dev/null
+++ b/wifi/netlinkinterceptor/vts/functional/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalNetlinkInterceptorV1_0Test",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ cpp_std: "experimental",
+ srcs: [
+ "interceptor_aidl_test.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.net.nlinterceptor-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "libgmock",
+ "android.hardware.automotive.can@libnetdevice",
+ "libnl++",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ disable_framework: true,
+}
diff --git a/wifi/netlinkinterceptor/vts/functional/interceptor_aidl_test.cpp b/wifi/netlinkinterceptor/vts/functional/interceptor_aidl_test.cpp
new file mode 100644
index 0000000..b26d8ec
--- /dev/null
+++ b/wifi/netlinkinterceptor/vts/functional/interceptor_aidl_test.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/net/nlinterceptor/IInterceptor.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <libnetdevice/libnetdevice.h>
+#include <libnl++/MessageFactory.h>
+#include <libnl++/Socket.h>
+#include <libnl++/printer.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <chrono>
+#include <thread>
+
+using aidl::android::hardware::net::nlinterceptor::IInterceptor;
+using AidlInterceptedSocket =
+ ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket;
+using namespace std::chrono_literals;
+using namespace std::string_literals;
+
+class InterceptorAidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ android::base::SetDefaultTag("InterceptorAidlTest");
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+ const auto instance = IInterceptor::descriptor + "/default"s;
+ mNlInterceptorService = IInterceptor::fromBinder(
+ ndk::SpAIBinder(AServiceManager_getService(instance.c_str())));
+
+ ASSERT_NE(mNlInterceptorService, nullptr);
+ mSocket = std::make_unique<android::nl::Socket>(NETLINK_ROUTE);
+ ASSERT_TRUE(mSocket->getPid().has_value());
+
+ // If the test broke last run, clean up our mess, don't worry about "no
+ // such device".
+ if (android::netdevice::del(mTestIfaceName)) {
+ LOG(WARNING) << "Test interface wasn't cleaned up on previous run!";
+ }
+ }
+
+ void multicastReceiver();
+
+ std::shared_ptr<IInterceptor> mNlInterceptorService;
+ std::unique_ptr<android::nl::Socket> mSocket;
+ bool mRunning;
+ bool mGotMulticast;
+ const std::string mTestIfaceName = "interceptorvts0";
+};
+
+TEST_P(InterceptorAidlTest, createSocketTest) {
+ // Ask IInterceptor for a socket.
+ AidlInterceptedSocket interceptedSocket;
+ auto aidlStatus = mNlInterceptorService->createSocket(
+ NETLINK_ROUTE, *(mSocket->getPid()), "createSocketTest",
+ &interceptedSocket);
+ ASSERT_TRUE(aidlStatus.isOk());
+ ASSERT_NE(interceptedSocket.portId, 0);
+ uint32_t interceptorPid = interceptedSocket.portId;
+
+ // Ask the kernel to tell us what interfaces are available.
+ android::nl::MessageFactory<rtgenmsg> req(RTM_GETLINK,
+ NLM_F_REQUEST | NLM_F_DUMP);
+ req->rtgen_family = AF_PACKET;
+ sockaddr_nl sa = {.nl_family = AF_NETLINK,
+ .nl_pad = 0,
+ .nl_pid = interceptorPid,
+ .nl_groups = 0};
+ EXPECT_TRUE(mSocket->send(req, sa));
+
+ // We'll likely get back several messages, as indicated by the MULTI flag.
+ unsigned received = 0;
+ for (const auto msg : *mSocket) {
+ ASSERT_NE(msg->nlmsg_type, NLMSG_ERROR);
+ ++received;
+ break;
+ if (msg->nlmsg_type == NLMSG_DONE) {
+ // TODO(202548749): NLMSG_DONE on NETLINK_ROUTE doesn't work?
+ break;
+ }
+ }
+ ASSERT_GE(received, 1);
+
+ // Close the socket and make sure it's stopped working.
+ aidlStatus = mNlInterceptorService->closeSocket(interceptedSocket);
+ EXPECT_TRUE(aidlStatus.isOk());
+ EXPECT_FALSE(mSocket->send(req, sa));
+}
+
+static bool isSocketReadable(const short revents) {
+ return 0 != (revents & POLLIN);
+}
+
+static bool isSocketBad(const short revents) {
+ return 0 != (revents & (POLLERR | POLLHUP | POLLNVAL));
+}
+
+void InterceptorAidlTest::multicastReceiver() {
+ pollfd fds[] = {
+ mSocket->preparePoll(POLLIN),
+ };
+ while (mRunning) {
+ if (poll(fds, 1, 300) < 0) {
+ PLOG(FATAL) << "poll failed";
+ return;
+ }
+ const auto nlsockEvents = fds[0].revents;
+ ASSERT_FALSE(isSocketBad(nlsockEvents));
+ if (!isSocketReadable(nlsockEvents)) continue;
+
+ const auto [msgMaybe, sa] = mSocket->receiveFrom();
+ ASSERT_TRUE(msgMaybe.has_value());
+ auto msg = *msgMaybe;
+
+ // Multicast messages have 0 for their pid and sequence number.
+ if (msg->nlmsg_pid == 0 && msg->nlmsg_seq == 0) {
+ mGotMulticast = true;
+ }
+ }
+}
+
+TEST_P(InterceptorAidlTest, subscribeGroupTest) {
+ // Ask IInterceptor for a socket.
+ AidlInterceptedSocket interceptedSocket;
+ auto aidlStatus = mNlInterceptorService->createSocket(
+ NETLINK_ROUTE, *(mSocket->getPid()), "subscribeGroupTest",
+ &interceptedSocket);
+ ASSERT_TRUE(aidlStatus.isOk());
+ ASSERT_TRUE(interceptedSocket.portId != 0);
+
+ // Listen for interface up/down events.
+ aidlStatus =
+ mNlInterceptorService->subscribeGroup(interceptedSocket, RTNLGRP_LINK);
+ ASSERT_TRUE(aidlStatus.isOk());
+
+ // Start a thread to receive a multicast
+ mRunning = true;
+ mGotMulticast = false;
+ std::thread successfulReceiver(&InterceptorAidlTest::multicastReceiver,
+ this);
+
+ // TODO(201695162): use futures with wait_for instead of a sleep_for().
+ std::this_thread::sleep_for(50ms);
+ // create a network interface and bring it up to trigger a multicast event.
+ ASSERT_TRUE(android::netdevice::add(mTestIfaceName, /*type=*/"dummy"));
+ ASSERT_TRUE(android::netdevice::up(mTestIfaceName));
+ std::this_thread::sleep_for(50ms);
+ EXPECT_TRUE(mGotMulticast);
+ mRunning = false;
+ successfulReceiver.join();
+
+ // Stop listening to interface up/down events.
+ aidlStatus = mNlInterceptorService->unsubscribeGroup(interceptedSocket,
+ RTNLGRP_LINK);
+ ASSERT_TRUE(aidlStatus.isOk());
+
+ // This time, we should hear nothing.
+ mGotMulticast = false;
+ mRunning = true;
+ std::thread unsuccessfulReceiver(&InterceptorAidlTest::multicastReceiver,
+ this);
+ std::this_thread::sleep_for(50ms);
+ ASSERT_TRUE(android::netdevice::down(mTestIfaceName));
+ ASSERT_TRUE(android::netdevice::del(mTestIfaceName));
+ std::this_thread::sleep_for(50ms);
+ EXPECT_FALSE(mGotMulticast);
+ mRunning = false;
+ unsuccessfulReceiver.join();
+
+ aidlStatus = mNlInterceptorService->closeSocket(interceptedSocket);
+ EXPECT_TRUE(aidlStatus.isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InterceptorAidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, InterceptorAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IInterceptor::descriptor)),
+ android::PrintInstanceNameToString);