Merge "gpuservice: move some libs from shared to static" into main
diff --git a/include/android/thermal.h b/include/android/thermal.h
index 32580ba..1f477f8 100644
--- a/include/android/thermal.h
+++ b/include/android/thermal.h
@@ -188,13 +188,13 @@
* Note that this only attempts to track the headroom of slow-moving sensors, such as
* the skin temperature sensor. This means that there is no benefit to calling this function
* more frequently than about once per second, and attempted to call significantly
- * more frequently may result in the function returning {@code NaN}.
+ * more frequently may result in the function returning `NaN`.
*
* In addition, in order to be able to provide an accurate forecast, the system does
* not attempt to forecast until it has multiple temperature samples from which to
* extrapolate. This should only take a few seconds from the time of the first call,
* but during this time, no forecasting will occur, and the current headroom will be
- * returned regardless of the value of {@code forecastSeconds}.
+ * returned regardless of the value of `forecastSeconds`.
*
* The value returned is a non-negative float that represents how much of the thermal envelope
* is in use (or is forecasted to be in use). A value of 1.0 indicates that the device is
diff --git a/libs/binder/tests/IBinderRpcBenchmark.aidl b/libs/binder/tests/IBinderRpcBenchmark.aidl
index 2baf680..1008778 100644
--- a/libs/binder/tests/IBinderRpcBenchmark.aidl
+++ b/libs/binder/tests/IBinderRpcBenchmark.aidl
@@ -18,4 +18,7 @@
@utf8InCpp String repeatString(@utf8InCpp String str);
IBinder repeatBinder(IBinder binder);
byte[] repeatBytes(in byte[] bytes);
+
+ IBinder gimmeBinder();
+ void waitGimmesDestroyed();
}
diff --git a/libs/binder/tests/binderRpcBenchmark.cpp b/libs/binder/tests/binderRpcBenchmark.cpp
index 9c96c41..4f10d74 100644
--- a/libs/binder/tests/binderRpcBenchmark.cpp
+++ b/libs/binder/tests/binderRpcBenchmark.cpp
@@ -74,6 +74,44 @@
*out = bytes;
return Status::ok();
}
+
+ class CountedBinder : public BBinder {
+ public:
+ CountedBinder(const sp<MyBinderRpcBenchmark>& parent) : mParent(parent) {
+ std::lock_guard<std::mutex> l(mParent->mCountMutex);
+ mParent->mBinderCount++;
+ // std::cout << "Count + is now " << mParent->mBinderCount << std::endl;
+ }
+ ~CountedBinder() {
+ {
+ std::lock_guard<std::mutex> l(mParent->mCountMutex);
+ mParent->mBinderCount--;
+ // std::cout << "Count - is now " << mParent->mBinderCount << std::endl;
+
+ // skip notify
+ if (mParent->mBinderCount != 0) return;
+ }
+ mParent->mCountCv.notify_one();
+ }
+
+ private:
+ sp<MyBinderRpcBenchmark> mParent;
+ };
+
+ Status gimmeBinder(sp<IBinder>* out) override {
+ *out = sp<CountedBinder>::make(sp<MyBinderRpcBenchmark>::fromExisting(this));
+ return Status::ok();
+ }
+ Status waitGimmesDestroyed() override {
+ std::unique_lock<std::mutex> l(mCountMutex);
+ mCountCv.wait(l, [&] { return mBinderCount == 0; });
+ return Status::ok();
+ }
+
+ friend class CountedBinder;
+ std::mutex mCountMutex;
+ std::condition_variable mCountCv;
+ size_t mBinderCount;
};
enum Transport {
@@ -212,6 +250,38 @@
->ArgsProduct({kTransportList,
{64, 1024, 2048, 4096, 8182, 16364, 32728, 65535, 65536, 65537}});
+void BM_collectProxies(benchmark::State& state) {
+ sp<IBinder> binder = getBinderForOptions(state);
+ sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
+ CHECK(iface != nullptr);
+
+ const size_t kNumIters = state.range(1);
+
+ while (state.KeepRunning()) {
+ std::vector<sp<IBinder>> out;
+ out.resize(kNumIters);
+
+ for (size_t i = 0; i < kNumIters; i++) {
+ Status ret = iface->gimmeBinder(&out[i]);
+ CHECK(ret.isOk()) << ret;
+ }
+
+ out.clear();
+
+ // we are using a thread up to wait, so make a call to
+ // force all refcounts to be updated first - current
+ // binder behavior means we really don't need to wait,
+ // so code which is waiting is really there to protect
+ // against any future changes that could delay destruction
+ android::IInterface::asBinder(iface)->pingBinder();
+
+ iface->waitGimmesDestroyed();
+ }
+
+ SetLabel(state);
+}
+BENCHMARK(BM_collectProxies)->ArgsProduct({kTransportList, {10, 100, 1000, 5000, 10000, 20000}});
+
void BM_repeatBinder(benchmark::State& state) {
sp<IBinder> binder = getBinderForOptions(state);
CHECK(binder != nullptr);
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 2ea4d16..9a27d23 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -204,27 +204,8 @@
aconfig_declarations: "libgui_flags",
}
-cc_library_shared {
- name: "libgui",
- vendor_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- double_loadable: true,
-
- defaults: ["libgui_bufferqueue-defaults"],
-
- static_libs: [
- "libgui_aidl_static",
- "libgui_window_info_static",
- "libguiflags",
- ],
- export_static_lib_headers: [
- "libgui_aidl_static",
- "libgui_window_info_static",
- ],
-
+filegroup {
+ name: "libgui-sources",
srcs: [
":framework_native_aidl_binder",
":framework_native_aidl_gui",
@@ -268,11 +249,40 @@
"bufferqueue/2.0/B2HProducerListener.cpp",
"bufferqueue/2.0/H2BGraphicBufferProducer.cpp",
],
+}
+cc_defaults {
+ name: "libgui-defaults",
+ defaults: ["libgui_bufferqueue-defaults"],
+ srcs: [":libgui-sources"],
+ static_libs: [
+ "libgui_aidl_static",
+ "libgui_window_info_static",
+ "libguiflags",
+ ],
shared_libs: [
"libbinder",
"libGLESv2",
],
+}
+
+cc_library_shared {
+ name: "libgui",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ private: true,
+ },
+ double_loadable: true,
+
+ defaults: [
+ "libgui-defaults",
+ ],
+
+ export_static_lib_headers: [
+ "libgui_aidl_static",
+ "libgui_window_info_static",
+ ],
export_shared_lib_headers: [
"libbinder",
@@ -346,6 +356,7 @@
"BufferQueueProducer.cpp",
"BufferQueueThreadState.cpp",
"BufferSlot.cpp",
+ "FrameRateUtils.cpp",
"FrameTimestamps.cpp",
"GLConsumerUtils.cpp",
"HdrMetadata.cpp",
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 207fa4f..dd0a028 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -26,6 +26,8 @@
#include <gui/BufferQueueConsumer.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
+#include <gui/Flags.h>
+#include <gui/FrameRateUtils.h>
#include <gui/GLConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/Surface.h>
@@ -39,6 +41,9 @@
#include <android-base/thread_annotations.h>
#include <chrono>
+#include <com_android_graphics_libgui_flags.h>
+
+using namespace com::android::graphics::libgui;
using namespace std::chrono_literals;
namespace {
@@ -139,6 +144,16 @@
}
}
+#if FLAG_BQ_SET_FRAME_RATE
+void BLASTBufferItemConsumer::onSetFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) {
+ sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+ if (bbq != nullptr) {
+ bbq->setFrameRate(frameRate, compatibility, changeFrameRateStrategy);
+ }
+}
+#endif
+
void BLASTBufferItemConsumer::resizeFrameEventHistory(size_t newSize) {
Mutex::Autolock lock(mMutex);
mFrameEventHistory.resize(newSize);
@@ -890,6 +905,10 @@
status_t setFrameRate(float frameRate, int8_t compatibility,
int8_t changeFrameRateStrategy) override {
+ if (flags::bq_setframerate()) {
+ return Surface::setFrameRate(frameRate, compatibility, changeFrameRateStrategy);
+ }
+
std::lock_guard _lock{mMutex};
if (mDestroyed) {
return DEAD_OBJECT;
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 66cad03..ab0f6d2 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -22,6 +22,7 @@
#include <gui/BufferQueueConsumer.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
+#include <gui/Flags.h>
namespace android {
@@ -98,6 +99,16 @@
}
}
+#if FLAG_BQ_SET_FRAME_RATE
+void BufferQueue::ProxyConsumerListener::onSetFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) {
+ sp<ConsumerListener> listener(mConsumerListener.promote());
+ if (listener != nullptr) {
+ listener->onSetFrameRate(frameRate, compatibility, changeFrameRateStrategy);
+ }
+}
+#endif
+
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
bool consumerIsSurfaceFlinger) {
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 920b83d..67dff6d 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -32,6 +32,8 @@
#include <gui/BufferItem.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
+#include <gui/Flags.h>
+#include <gui/FrameRateUtils.h>
#include <gui/GLConsumer.h>
#include <gui/IConsumerListener.h>
#include <gui/IProducerListener.h>
@@ -1751,4 +1753,27 @@
return NO_ERROR;
}
+#if FLAG_BQ_SET_FRAME_RATE
+status_t BufferQueueProducer::setFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) {
+ ATRACE_CALL();
+ BQ_LOGV("setFrameRate: %.2f", frameRate);
+
+ if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy,
+ "BufferQueueProducer::setFrameRate")) {
+ return BAD_VALUE;
+ }
+
+ sp<IConsumerListener> listener;
+ {
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
+ listener = mCore->mConsumerListener;
+ }
+ if (listener != nullptr) {
+ listener->onSetFrameRate(frameRate, compatibility, changeFrameRateStrategy);
+ }
+ return NO_ERROR;
+}
+#endif
+
} // namespace android
diff --git a/libs/gui/FrameRateUtils.cpp b/libs/gui/FrameRateUtils.cpp
new file mode 100644
index 0000000..6993bfa
--- /dev/null
+++ b/libs/gui/FrameRateUtils.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 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 <gui/Flags.h>
+#include <gui/FrameRateUtils.h>
+#include <system/window.h>
+#include <utils/Log.h>
+
+#include <cmath>
+
+namespace android {
+// Returns true if the frameRate is valid.
+//
+// @param frameRate the frame rate in Hz
+// @param compatibility a ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_*
+// @param changeFrameRateStrategy a ANATIVEWINDOW_CHANGE_FRAME_RATE_*
+// @param functionName calling function or nullptr. Used for logging
+// @param privileged whether caller has unscoped surfaceflinger access
+bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy,
+ const char* inFunctionName, bool privileged) {
+ const char* functionName = inFunctionName != nullptr ? inFunctionName : "call";
+ int floatClassification = std::fpclassify(frameRate);
+ if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) {
+ ALOGE("%s failed - invalid frame rate %f", functionName, frameRate);
+ return false;
+ }
+
+ if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT &&
+ compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE &&
+ (!privileged ||
+ (compatibility != ANATIVEWINDOW_FRAME_RATE_EXACT &&
+ compatibility != ANATIVEWINDOW_FRAME_RATE_NO_VOTE))) {
+ ALOGE("%s failed - invalid compatibility value %d privileged: %s", functionName,
+ compatibility, privileged ? "yes" : "no");
+ return false;
+ }
+
+ if (__builtin_available(android 31, *)) {
+ if (changeFrameRateStrategy != ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS &&
+ changeFrameRateStrategy != ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS) {
+ ALOGE("%s failed - invalid change frame rate strategy value %d", functionName,
+ changeFrameRateStrategy);
+ if (FLAG_BQ_SET_FRAME_RATE) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+} // namespace android
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 918ff2d..d0c09e4 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -27,11 +27,12 @@
#include <binder/Parcel.h>
#include <binder/IInterface.h>
-#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
-#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
#include <gui/BufferQueueDefs.h>
+#include <gui/Flags.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/IProducerListener.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -78,6 +79,7 @@
CANCEL_BUFFERS,
QUERY_MULTIPLE,
GET_LAST_QUEUED_BUFFER2,
+ SET_FRAME_RATE,
};
class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -761,6 +763,21 @@
}
return result;
}
+#if FLAG_BQ_SET_FRAME_RATE
+ virtual status_t setFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) override {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+ data.writeFloat(frameRate);
+ data.writeInt32(compatibility);
+ data.writeInt32(changeFrameRateStrategy);
+ status_t result = remote()->transact(SET_FRAME_RATE, data, &reply);
+ if (result == NO_ERROR) {
+ result = reply.readInt32();
+ }
+ return result;
+ }
+#endif
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -956,6 +973,14 @@
return INVALID_OPERATION;
}
+#if FLAG_BQ_SET_FRAME_RATE
+status_t IGraphicBufferProducer::setFrameRate(float /*frameRate*/, int8_t /*compatibility*/,
+ int8_t /*changeFrameRateStrategy*/) {
+ // No-op for IGBP other than BufferQueue.
+ return INVALID_OPERATION;
+}
+#endif
+
status_t IGraphicBufferProducer::exportToParcel(Parcel* parcel) {
status_t res = OK;
res = parcel->writeUint32(USE_BUFFER_QUEUE);
@@ -1497,6 +1522,17 @@
reply->writeInt32(result);
return NO_ERROR;
}
+#if FLAG_BQ_SET_FRAME_RATE
+ case SET_FRAME_RATE: {
+ CHECK_INTERFACE(IGraphicBuffer, data, reply);
+ float frameRate = data.readFloat();
+ int8_t compatibility = data.readInt32();
+ int8_t changeFrameRateStrategy = data.readInt32();
+ status_t result = setFrameRate(frameRate, compatibility, changeFrameRateStrategy);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
+#endif
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index e1afb52..9847c05 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -22,6 +22,7 @@
#include <android/gui/ISurfaceComposerClient.h>
#include <android/native_window.h>
#include <binder/Parcel.h>
+#include <gui/FrameRateUtils.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/LayerState.h>
#include <gui/SurfaceControl.h>
@@ -863,34 +864,6 @@
return NO_ERROR;
}
-bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy,
- const char* inFunctionName, bool privileged) {
- const char* functionName = inFunctionName != nullptr ? inFunctionName : "call";
- int floatClassification = std::fpclassify(frameRate);
- if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) {
- ALOGE("%s failed - invalid frame rate %f", functionName, frameRate);
- return false;
- }
-
- if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT &&
- compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE &&
- (!privileged ||
- (compatibility != ANATIVEWINDOW_FRAME_RATE_EXACT &&
- compatibility != ANATIVEWINDOW_FRAME_RATE_NO_VOTE))) {
- ALOGE("%s failed - invalid compatibility value %d privileged: %s", functionName,
- compatibility, privileged ? "yes" : "no");
- return false;
- }
-
- if (changeFrameRateStrategy != ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS &&
- changeFrameRateStrategy != ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS) {
- ALOGE("%s failed - invalid change frame rate strategy value %d", functionName,
- changeFrameRateStrategy);
- }
-
- return true;
-}
-
// ----------------------------------------------------------------------------
namespace gui {
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 53a2f64..a87f053 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -43,6 +43,7 @@
#include <gui/AidlStatusUtil.h>
#include <gui/BufferItem.h>
+#include <gui/Flags.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h>
@@ -50,8 +51,11 @@
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
+#include <com_android_graphics_libgui_flags.h>
+
namespace android {
+using namespace com::android::graphics::libgui;
using gui::aidl_utils::statusTFromBinderStatus;
using ui::Dataspace;
@@ -2565,8 +2569,22 @@
mSurfaceListener->onBuffersDiscarded(discardedBufs);
}
-[[deprecated]] status_t Surface::setFrameRate(float /*frameRate*/, int8_t /*compatibility*/,
- int8_t /*changeFrameRateStrategy*/) {
+status_t Surface::setFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) {
+#if FLAG_BQ_SET_FRAME_RATE
+ if (flags::bq_setframerate()) {
+ status_t err = mGraphicBufferProducer->setFrameRate(frameRate, compatibility,
+ changeFrameRateStrategy);
+ ALOGE_IF(err, "IGraphicBufferProducer::setFrameRate(%.2f) returned %s", frameRate,
+ strerror(-err));
+ return err;
+ }
+#else
+ static_cast<void>(frameRate);
+ static_cast<void>(compatibility);
+ static_cast<void>(changeFrameRateStrategy);
+#endif
+
ALOGI("Surface::setFrameRate is deprecated, setFrameRate hint is dropped as destination is not "
"SurfaceFlinger");
// ISurfaceComposer no longer supports setFrameRate, we will return NO_ERROR when the api is
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 4db960e..e0882ac 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -26,6 +26,7 @@
#include <android/gui/IWindowInfosListener.h>
#include <android/gui/TrustedPresentationThresholds.h>
#include <android/os/IInputConstants.h>
+#include <gui/FrameRateUtils.h>
#include <gui/TraceUtils.h>
#include <utils/Errors.h>
#include <utils/Log.h>
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index a49a859..02d7c4d 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -17,9 +17,10 @@
#ifndef ANDROID_GUI_BLAST_BUFFER_QUEUE_H
#define ANDROID_GUI_BLAST_BUFFER_QUEUE_H
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/BufferItemConsumer.h>
#include <gui/BufferItem.h>
+#include <gui/BufferItemConsumer.h>
+#include <gui/Flags.h>
+#include <gui/IGraphicBufferProducer.h>
#include <gui/SurfaceComposerClient.h>
#include <utils/Condition.h>
@@ -58,6 +59,10 @@
protected:
void onSidebandStreamChanged() override EXCLUDES(mMutex);
+#if FLAG_BQ_SET_FRAME_RATE
+ void onSetFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) override;
+#endif
private:
const wp<BLASTBufferQueue> mBLASTBufferQueue;
diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
index 690587f..2756277 100644
--- a/libs/gui/include/gui/BufferQueue.h
+++ b/libs/gui/include/gui/BufferQueue.h
@@ -19,9 +19,10 @@
#include <gui/BufferItem.h>
#include <gui/BufferQueueDefs.h>
+#include <gui/Flags.h>
+#include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
-#include <gui/IConsumerListener.h>
namespace android {
@@ -69,6 +70,10 @@
void addAndGetFrameTimestamps(
const NewFrameEventsEntry* newTimestamps,
FrameEventHistoryDelta* outDelta) override;
+#if FLAG_BQ_SET_FRAME_RATE
+ void onSetFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) override;
+#endif
private:
// mConsumerListener is a weak reference to the IConsumerListener. This is
// the raison d'etre of ProxyConsumerListener.
diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h
index 1d13dab..38805d0 100644
--- a/libs/gui/include/gui/BufferQueueProducer.h
+++ b/libs/gui/include/gui/BufferQueueProducer.h
@@ -18,6 +18,7 @@
#define ANDROID_GUI_BUFFERQUEUEPRODUCER_H
#include <gui/BufferQueueDefs.h>
+#include <gui/Flags.h>
#include <gui/IGraphicBufferProducer.h>
namespace android {
@@ -201,6 +202,11 @@
// See IGraphicBufferProducer::setAutoPrerotation
virtual status_t setAutoPrerotation(bool autoPrerotation);
+#if FLAG_BQ_SET_FRAME_RATE
+ // See IGraphicBufferProducer::setFrameRate
+ status_t setFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) override;
+#endif
protected:
// see IGraphicsBufferProducer::setMaxDequeuedBufferCount, but with the ability to retrieve the
diff --git a/services/inputflinger/host/main.cpp b/libs/gui/include/gui/Flags.h
similarity index 64%
rename from services/inputflinger/host/main.cpp
rename to libs/gui/include/gui/Flags.h
index 0a517cc..a2cff56 100644
--- a/services/inputflinger/host/main.cpp
+++ b/libs/gui/include/gui/Flags.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright 2023 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.
@@ -14,13 +14,9 @@
* limitations under the License.
*/
-#include <binder/BinderService.h>
-#include "InputFlinger.h"
+#pragma once
-using namespace android;
-
-int main(int, char**) {
- ProcessState::self()->setThreadPoolMaxThreadCount(4);
- BinderService<InputFlinger>::publishAndJoinThreadPool(true);
- return 0;
-}
+// TODO(281695725): replace this with build time flags, whenever they are available
+#ifndef FLAG_BQ_SET_FRAME_RATE
+#define FLAG_BQ_SET_FRAME_RATE false
+#endif
\ No newline at end of file
diff --git a/services/inputflinger/host/main.cpp b/libs/gui/include/gui/FrameRateUtils.h
similarity index 64%
copy from services/inputflinger/host/main.cpp
copy to libs/gui/include/gui/FrameRateUtils.h
index 0a517cc..16896ef 100644
--- a/services/inputflinger/host/main.cpp
+++ b/libs/gui/include/gui/FrameRateUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright 2023 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.
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-#include <binder/BinderService.h>
-#include "InputFlinger.h"
+#pragma once
-using namespace android;
+#include <stdint.h>
-int main(int, char**) {
- ProcessState::self()->setThreadPoolMaxThreadCount(4);
- BinderService<InputFlinger>::publishAndJoinThreadPool(true);
- return 0;
-}
+namespace android {
+
+bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy,
+ const char* inFunctionName, bool privileged = false);
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h
index 0ab2399..e183bf2 100644
--- a/libs/gui/include/gui/IConsumerListener.h
+++ b/libs/gui/include/gui/IConsumerListener.h
@@ -19,6 +19,8 @@
#include <binder/IInterface.h>
#include <binder/SafeInterface.h>
+#include <gui/Flags.h>
+
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -90,6 +92,12 @@
// WARNING: This method can only be called when the BufferQueue is in the consumer's process.
virtual void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/,
FrameEventHistoryDelta* /*outDelta*/) {}
+
+#if FLAG_BQ_SET_FRAME_RATE
+ // Notifies the consumer of a setFrameRate call from the producer side.
+ virtual void onSetFrameRate(float /*frameRate*/, int8_t /*compatibility*/,
+ int8_t /*changeFrameRateStrategy*/) {}
+#endif
};
#ifndef NO_BINDER
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index 98df834..3562906 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -31,6 +31,7 @@
#include <ui/Rect.h>
#include <ui/Region.h>
+#include <gui/Flags.h>
#include <gui/FrameTimestamps.h>
#include <gui/HdrMetadata.h>
@@ -676,6 +677,12 @@
// the width and height used for dequeueBuffer will be additionally swapped.
virtual status_t setAutoPrerotation(bool autoPrerotation);
+#if FLAG_BQ_SET_FRAME_RATE
+ // Sets the apps intended frame rate.
+ virtual status_t setFrameRate(float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy);
+#endif
+
struct RequestBufferOutput : public Flattenable<RequestBufferOutput> {
RequestBufferOutput() = default;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 8c36058..102a3c1 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -476,16 +476,6 @@
return compare_type(lhs.token, rhs.token);
}
-// Returns true if the frameRate is valid.
-//
-// @param frameRate the frame rate in Hz
-// @param compatibility a ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_*
-// @param changeFrameRateStrategy a ANATIVEWINDOW_CHANGE_FRAME_RATE_*
-// @param functionName calling function or nullptr. Used for logging
-// @param privileged whether caller has unscoped surfaceflinger access
-bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy,
- const char* functionName, bool privileged = false);
-
}; // namespace android
#endif // ANDROID_SF_LAYER_STATE_H
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 462ce6e..38c0eed 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -15,9 +15,13 @@
name: "libgui_test",
test_suites: ["device-tests"],
- cflags: [
+ defaults: ["libgui-defaults"],
+
+ cppflags: [
"-Wall",
"-Werror",
+ "-Wno-extra",
+ "-DFLAG_BQ_SET_FRAME_RATE=true",
],
srcs: [
@@ -28,6 +32,7 @@
"CompositorTiming_test.cpp",
"CpuConsumer_test.cpp",
"EndToEndNativeInputTest.cpp",
+ "FrameRateUtilsTest.cpp",
"DisplayInfo_test.cpp",
"DisplayedContentSampling_test.cpp",
"FillBuffer.cpp",
@@ -53,19 +58,12 @@
"android.hardware.configstore@1.0",
"android.hardware.configstore-utils",
"libSurfaceFlingerProp",
- "libbase",
- "liblog",
- "libEGL",
"libGLESv1_CM",
- "libGLESv2",
- "libbinder",
- "libcutils",
- "libgui",
- "libhidlbase",
"libinput",
- "libui",
- "libutils",
- "libnativewindow",
+ ],
+
+ static_libs: [
+ "libgmock",
],
header_libs: ["libsurfaceflinger_headers"],
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 0168877..17aa5f1 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -37,14 +37,18 @@
#include <system/window.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <future>
#include <thread>
+#include <com_android_graphics_libgui_flags.h>
+
using namespace std::chrono_literals;
namespace android {
+using namespace com::android::graphics::libgui;
class BufferQueueTest : public ::testing::Test {
@@ -1261,6 +1265,31 @@
ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
}
+TEST_F(BufferQueueTest, TestBqSetFrameRateFlagBuildTimeIsSet) {
+ if (flags::bq_setframerate()) {
+ ASSERT_EQ(true, FLAG_BQ_SET_FRAME_RATE);
+ }
+}
+
+struct BufferItemConsumerSetFrameRateListener : public BufferItemConsumer {
+ BufferItemConsumerSetFrameRateListener(const sp<IGraphicBufferConsumer>& consumer)
+ : BufferItemConsumer(consumer, GRALLOC_USAGE_SW_READ_OFTEN, 1) {}
+
+ MOCK_METHOD(void, onSetFrameRate, (float, int8_t, int8_t), (override));
+};
+
+TEST_F(BufferQueueTest, TestSetFrameRate) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ sp<BufferItemConsumerSetFrameRateListener> bufferConsumer =
+ sp<BufferItemConsumerSetFrameRateListener>::make(consumer);
+
+ EXPECT_CALL(*bufferConsumer, onSetFrameRate(12.34f, 1, 0)).Times(1);
+ producer->setFrameRate(12.34f, 1, 0);
+}
+
class Latch {
public:
explicit Latch(int expected) : mExpected(expected) {}
diff --git a/libs/gui/tests/FrameRateUtilsTest.cpp b/libs/gui/tests/FrameRateUtilsTest.cpp
new file mode 100644
index 0000000..5fe22b0
--- /dev/null
+++ b/libs/gui/tests/FrameRateUtilsTest.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2018 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 <gtest/gtest.h>
+
+#include <gui/FrameRateUtils.h>
+#include <inttypes.h>
+#include <system/window.h>
+
+#include <com_android_graphics_libgui_flags.h>
+
+namespace android {
+using namespace com::android::graphics::libgui;
+
+TEST(FrameRateUtilsTest, ValidateFrameRate) {
+ EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS, ""));
+ EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+
+ // Privileged APIs.
+ EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_FALSE(ValidateFrameRate(0.0f, ANATIVEWINDOW_FRAME_RATE_NO_VOTE,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+
+ constexpr bool kPrivileged = true;
+ EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "",
+ kPrivileged));
+ EXPECT_TRUE(ValidateFrameRate(0.0f, ANATIVEWINDOW_FRAME_RATE_NO_VOTE,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "",
+ kPrivileged));
+
+ // Invalid frame rate.
+ EXPECT_FALSE(ValidateFrameRate(-1, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_FALSE(ValidateFrameRate(1.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_FALSE(ValidateFrameRate(0.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+
+ // Invalid compatibility.
+ EXPECT_FALSE(
+ ValidateFrameRate(60.0f, -1, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_FALSE(ValidateFrameRate(60.0f, 2, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+
+ // Invalid change frame rate strategy.
+ if (flags::bq_setframerate()) {
+ EXPECT_FALSE(
+ ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, -1, ""));
+ EXPECT_FALSE(
+ ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, 2, ""));
+ }
+}
+
+} // namespace android
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 7451037..5d1d4af 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -240,9 +240,6 @@
"libinputservice_test",
"Bug-115739809",
"StructLayout_test",
- // currently unused, but still must build correctly
- "inputflinger",
- "libinputflingerhost",
// rust targets
"libinput_rust_test",
diff --git a/services/inputflinger/host/Android.bp b/services/inputflinger/host/Android.bp
deleted file mode 100644
index 4d2839f..0000000
--- a/services/inputflinger/host/Android.bp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2015 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 "frameworks_native_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_library_shared {
- name: "libinputflingerhost",
- cpp_std: "c++20",
- srcs: [
- "InputFlinger.cpp",
- "InputDriver.cpp",
- "InputHost.cpp",
- ],
-
- header_libs: ["jni_headers"],
- shared_libs: [
- "libbase",
- "libbinder",
- "libcrypto",
- "libcutils",
- "libinput",
- "liblog",
- "libutils",
- "libhardware",
- ],
- static_libs: [
- "libarect",
- ],
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- // TODO: Move inputflinger to its own process and mark it hidden
- //-fvisibility=hidden
- ],
-
- export_header_lib_headers: ["jni_headers"],
- export_include_dirs: ["."],
-}
-
-//#######################################################################
-// build input flinger executable
-cc_binary {
- name: "inputflinger",
-
- srcs: ["main.cpp"],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "libbase",
- "libbinder",
- "libinputflingerhost",
- "libutils",
- "libinput",
- ],
- static_libs: [
- "libarect",
- "libui-types",
- ],
-}
diff --git a/services/inputflinger/host/InputDriver.cpp b/services/inputflinger/host/InputDriver.cpp
deleted file mode 100644
index de99fc7..0000000
--- a/services/inputflinger/host/InputDriver.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Copyright (C) 2015 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 <functional>
-#include <stdint.h>
-#include <sys/types.h>
-#include <unordered_map>
-#include <vector>
-
-#define LOG_TAG "InputDriver"
-
-#define LOG_NDEBUG 0
-
-#include "InputDriver.h"
-#include "InputHost.h"
-
-#include <hardware/input.h>
-#include <input/InputDevice.h>
-#include <input/PropertyMap.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#define INDENT2 " "
-
-struct input_property_map {
- std::unique_ptr<android::PropertyMap> propertyMap;
-};
-
-struct input_property {
- android::String8 key;
- android::String8 value;
-};
-
-struct input_device_identifier {
- const char* name;
- const char* uniqueId;
- input_bus_t bus;
- int32_t vendorId;
- int32_t productId;
- int32_t version;
-};
-
-struct input_device_definition {
- std::vector<input_report_definition*> reportDefs;
-};
-
-struct input_device_handle {
- input_device_identifier_t* id;
- input_device_definition_t* def;
-};
-
-struct input_int_usage {
- input_usage_t usage;
- int32_t min;
- int32_t max;
- float resolution;
-};
-
-struct input_collection {
- int32_t arity;
- std::vector<input_int_usage> intUsages;
- std::vector<input_usage_t> boolUsages;
-};
-
-struct InputCollectionIdHasher {
- std::size_t operator()(const input_collection_id& id) const {
- return std::hash<int>()(static_cast<int>(id));
- }
-};
-
-struct input_report_definition {
- std::unordered_map<input_collection_id_t, input_collection, InputCollectionIdHasher> collections;
-};
-
-
-namespace android {
-
-static input_host_callbacks_t kCallbacks = {
- .create_device_identifier = create_device_identifier,
- .create_device_definition = create_device_definition,
- .create_input_report_definition = create_input_report_definition,
- .create_output_report_definition = create_output_report_definition,
- .free_report_definition = free_report_definition,
- .input_device_definition_add_report = input_device_definition_add_report,
- .input_report_definition_add_collection = input_report_definition_add_collection,
- .input_report_definition_declare_usage_int = input_report_definition_declare_usage_int,
- .input_report_definition_declare_usages_bool = input_report_definition_declare_usages_bool,
- .register_device = register_device,
- .input_allocate_report = input_allocate_report,
- .input_report_set_usage_int = input_report_set_usage_int,
- .input_report_set_usage_bool = input_report_set_usage_bool,
- .report_event = report_event,
- .input_get_device_property_map = input_get_device_property_map,
- .input_get_device_property = input_get_device_property,
- .input_get_property_key = input_get_property_key,
- .input_get_property_value = input_get_property_value,
- .input_free_device_property = input_free_device_property,
- .input_free_device_property_map = input_free_device_property_map,
-};
-
-InputDriver::InputDriver(const char* name) : mName(String8(name)) {
- const hw_module_t* module;
- int err = input_open(&module, name);
- LOG_ALWAYS_FATAL_IF(err != 0, "Input module %s not found", name);
- mHal = reinterpret_cast<const input_module_t*>(module);
-}
-
-void InputDriver::init() {
- mHal->init(mHal, static_cast<input_host_t*>(this), kCallbacks);
-}
-
-input_device_identifier_t* InputDriver::createDeviceIdentifier(
- const char* name, int32_t productId, int32_t vendorId,
- input_bus_t bus, const char* uniqueId) {
- auto identifier = new ::input_device_identifier {
- .name = name,
- .uniqueId = uniqueId,
- .bus = bus,
- .vendorId = vendorId,
- .productId = productId,
- };
- // TODO: store this identifier somewhere
- return identifier;
-}
-
-input_device_definition_t* InputDriver::createDeviceDefinition() {
- return new ::input_device_definition;
-}
-
-input_report_definition_t* InputDriver::createInputReportDefinition() {
- return new ::input_report_definition;
-}
-
-input_report_definition_t* InputDriver::createOutputReportDefinition() {
- return new ::input_report_definition;
-}
-
-void InputDriver::freeReportDefinition(input_report_definition_t* reportDef) {
- delete reportDef;
-}
-
-void InputDriver::inputDeviceDefinitionAddReport(input_device_definition_t* d,
- input_report_definition_t* r) {
- d->reportDefs.push_back(r);
-}
-
-void InputDriver::inputReportDefinitionAddCollection(input_report_definition_t* report,
- input_collection_id_t id, int32_t arity) {
- report->collections[id] = {.arity = arity};
-}
-
-void InputDriver::inputReportDefinitionDeclareUsageInt(input_report_definition_t* report,
- input_collection_id_t id, input_usage_t usage, int32_t min, int32_t max,
- float resolution) {
- if (report->collections.find(id) != report->collections.end()) {
- report->collections[id].intUsages.push_back({
- .usage = usage, .min = min, .max = max, .resolution = resolution});
- }
-}
-
-void InputDriver::inputReportDefinitionDeclareUsagesBool(input_report_definition_t* report,
- input_collection_id_t id, input_usage_t* usage, size_t usageCount) {
- if (report->collections.find(id) != report->collections.end()) {
- for (size_t i = 0; i < usageCount; ++i) {
- report->collections[id].boolUsages.push_back(usage[i]);
- }
- }
-}
-
-input_device_handle_t* InputDriver::registerDevice(input_device_identifier_t* id,
- input_device_definition_t* d) {
- ALOGD("Registering device %s with %zu input reports", id->name, d->reportDefs.size());
- // TODO: save this device handle
- return new input_device_handle{ .id = id, .def = d };
-}
-
-void InputDriver::unregisterDevice(input_device_handle_t* handle) {
- delete handle;
-}
-
-input_report_t* InputDriver::inputAllocateReport(input_report_definition_t* r) {
- ALOGD("Allocating input report for definition %p", r);
- return nullptr;
-}
-
-void InputDriver::inputReportSetUsageInt(input_report_t* r, input_collection_id_t id,
- input_usage_t usage, int32_t value, int32_t arity_index) {
-}
-
-void InputDriver::inputReportSetUsageBool(input_report_t* r, input_collection_id_t id,
- input_usage_t usage, bool value, int32_t arity_index) {
-}
-
-void InputDriver::reportEvent(input_device_handle_t* d, input_report_t* report) {
- ALOGD("report_event %p for handle %p", report, d);
-}
-
-input_property_map_t* InputDriver::inputGetDevicePropertyMap(input_device_identifier_t* id) {
- InputDeviceIdentifier idi;
- idi.name = id->name;
- idi.uniqueId = id->uniqueId;
- idi.bus = id->bus;
- idi.vendor = id->vendorId;
- idi.product = id->productId;
- idi.version = id->version;
-
- std::string configFile =
- getInputDeviceConfigurationFilePathByDeviceIdentifier(idi,
- InputDeviceConfigurationFileType::
- CONFIGURATION);
- if (configFile.empty()) {
- ALOGD("No input device configuration file found for device '%s'.",
- idi.name.c_str());
- } else {
- std::unique_ptr<input_property_map_t> propMap = std::make_unique<input_property_map_t>();
- android::base::Result<std::unique_ptr<PropertyMap>> result =
- PropertyMap::load(configFile.c_str());
- if (!result.ok()) {
- ALOGE("Error loading input device configuration file for device '%s'. "
- "Using default configuration.",
- idi.name.c_str());
- return nullptr;
- }
- propMap->propertyMap = std::move(*result);
- return propMap.release();
- }
- return nullptr;
-}
-
-input_property_t* InputDriver::inputGetDeviceProperty(input_property_map_t* map, const char* key) {
- if (map != nullptr) {
- std::optional<std::string> value = map->propertyMap->getString(key);
- if (!value.has_value()) {
- return nullptr;
- }
- auto prop = std::make_unique<input_property_t>();
- prop->key = key;
- prop->value = value->c_str();
- return prop.release();
- }
- return nullptr;
-}
-
-const char* InputDriver::inputGetPropertyKey(input_property_t* property) {
- if (property != nullptr) {
- return property->key.c_str();
- }
- return nullptr;
-}
-
-const char* InputDriver::inputGetPropertyValue(input_property_t* property) {
- if (property != nullptr) {
- return property->value.c_str();
- }
- return nullptr;
-}
-
-void InputDriver::inputFreeDeviceProperty(input_property_t* property) {
- if (property != nullptr) {
- delete property;
- }
-}
-
-void InputDriver::inputFreeDevicePropertyMap(input_property_map_t* map) {
- if (map != nullptr) {
- delete map;
- }
-}
-
-void InputDriver::dump(String8& result) {
- result.appendFormat(INDENT2 "HAL Input Driver (%s)\n", mName.c_str());
-}
-
-} // namespace android
-
-// HAL wrapper functions
-
-namespace android {
-
-::input_device_identifier_t* create_device_identifier(input_host_t* host,
- const char* name, int32_t product_id, int32_t vendor_id,
- input_bus_t bus, const char* unique_id) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->createDeviceIdentifier(name, product_id, vendor_id, bus, unique_id);
-}
-
-input_device_definition_t* create_device_definition(input_host_t* host) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->createDeviceDefinition();
-}
-
-input_report_definition_t* create_input_report_definition(input_host_t* host) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->createInputReportDefinition();
-}
-
-input_report_definition_t* create_output_report_definition(input_host_t* host) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->createOutputReportDefinition();
-}
-
-void free_report_definition(input_host_t* host, input_report_definition_t* report_def) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->freeReportDefinition(report_def);
-}
-
-void input_device_definition_add_report(input_host_t* host,
- input_device_definition_t* d, input_report_definition_t* r) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputDeviceDefinitionAddReport(d, r);
-}
-
-void input_report_definition_add_collection(input_host_t* host,
- input_report_definition_t* report, input_collection_id_t id, int32_t arity) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputReportDefinitionAddCollection(report, id, arity);
-}
-
-void input_report_definition_declare_usage_int(input_host_t* host,
- input_report_definition_t* report, input_collection_id_t id,
- input_usage_t usage, int32_t min, int32_t max, float resolution) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputReportDefinitionDeclareUsageInt(report, id, usage, min, max, resolution);
-}
-
-void input_report_definition_declare_usages_bool(input_host_t* host,
- input_report_definition_t* report, input_collection_id_t id,
- input_usage_t* usage, size_t usage_count) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputReportDefinitionDeclareUsagesBool(report, id, usage, usage_count);
-}
-
-input_device_handle_t* register_device(input_host_t* host,
- input_device_identifier_t* id, input_device_definition_t* d) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->registerDevice(id, d);
-}
-
-void unregister_device(input_host_t* host, input_device_handle_t* handle) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->unregisterDevice(handle);
-}
-
-input_report_t* input_allocate_report(input_host_t* host, input_report_definition_t* r) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->inputAllocateReport(r);
-}
-
-void input_report_set_usage_int(input_host_t* host, input_report_t* r,
- input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputReportSetUsageInt(r, id, usage, value, arity_index);
-}
-
-void input_report_set_usage_bool(input_host_t* host, input_report_t* r,
- input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputReportSetUsageBool(r, id, usage, value, arity_index);
-}
-
-void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->reportEvent(d, report);
-}
-
-input_property_map_t* input_get_device_property_map(input_host_t* host,
- input_device_identifier_t* id) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->inputGetDevicePropertyMap(id);
-}
-
-input_property_t* input_get_device_property(input_host_t* host, input_property_map_t* map,
- const char* key) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->inputGetDeviceProperty(map, key);
-}
-
-const char* input_get_property_key(input_host_t* host, input_property_t* property) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->inputGetPropertyKey(property);
-}
-
-const char* input_get_property_value(input_host_t* host, input_property_t* property) {
- auto driver = static_cast<InputDriverInterface*>(host);
- return driver->inputGetPropertyValue(property);
-}
-
-void input_free_device_property(input_host_t* host, input_property_t* property) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputFreeDeviceProperty(property);
-}
-
-void input_free_device_property_map(input_host_t* host, input_property_map_t* map) {
- auto driver = static_cast<InputDriverInterface*>(host);
- driver->inputFreeDevicePropertyMap(map);
-}
-
-} // namespace android
diff --git a/services/inputflinger/host/InputDriver.h b/services/inputflinger/host/InputDriver.h
deleted file mode 100644
index b4c9094..0000000
--- a/services/inputflinger/host/InputDriver.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2015 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 <stdint.h>
-#include <sys/types.h>
-
-#include "InputHost.h"
-
-#include <hardware/input.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-// Declare a concrete type for the HAL
-struct input_host {
-};
-
-namespace android {
-
-class InputDriverInterface : public input_host_t, public virtual RefBase {
-protected:
- InputDriverInterface() = default;
- virtual ~InputDriverInterface() = default;
-
-public:
- virtual void init() = 0;
-
- virtual input_device_identifier_t* createDeviceIdentifier(
- const char* name, int32_t productId, int32_t vendorId,
- input_bus_t bus, const char* uniqueId) = 0;
- virtual input_device_definition_t* createDeviceDefinition() = 0;
- virtual input_report_definition_t* createInputReportDefinition() = 0;
- virtual input_report_definition_t* createOutputReportDefinition() = 0;
- virtual void freeReportDefinition(input_report_definition_t* reportDef) = 0;
-
- virtual void inputDeviceDefinitionAddReport(input_device_definition_t* d,
- input_report_definition_t* r) = 0;
- virtual void inputReportDefinitionAddCollection(input_report_definition_t* report,
- input_collection_id_t id, int32_t arity) = 0;
- virtual void inputReportDefinitionDeclareUsageInt(input_report_definition_t* report,
- input_collection_id_t id, input_usage_t usage, int32_t min, int32_t max,
- float resolution) = 0;
- virtual void inputReportDefinitionDeclareUsagesBool(input_report_definition_t* report,
- input_collection_id_t id, input_usage_t* usage, size_t usageCount) = 0;
-
- virtual input_device_handle_t* registerDevice(input_device_identifier_t* id,
- input_device_definition_t* d) = 0;
- virtual void unregisterDevice(input_device_handle_t* handle) = 0;
-
- virtual input_report_t* inputAllocateReport(input_report_definition_t* r) = 0;
- virtual void inputReportSetUsageInt(input_report_t* r, input_collection_id_t id,
- input_usage_t usage, int32_t value, int32_t arity_index) = 0;
- virtual void inputReportSetUsageBool(input_report_t* r, input_collection_id_t id,
- input_usage_t usage, bool value, int32_t arity_index) = 0;
- virtual void reportEvent(input_device_handle_t* d, input_report_t* report) = 0;
-
- virtual input_property_map_t* inputGetDevicePropertyMap(input_device_identifier_t* id) = 0;
- virtual input_property_t* inputGetDeviceProperty(input_property_map_t* map,
- const char* key) = 0;
- virtual const char* inputGetPropertyKey(input_property_t* property) = 0;
- virtual const char* inputGetPropertyValue(input_property_t* property) = 0;
- virtual void inputFreeDeviceProperty(input_property_t* property) = 0;
- virtual void inputFreeDevicePropertyMap(input_property_map_t* map) = 0;
-
- virtual void dump(String8& result) = 0;
-};
-
-class InputDriver : public InputDriverInterface {
-public:
- explicit InputDriver(const char* name);
- virtual ~InputDriver() = default;
-
- virtual void init() override;
-
- virtual input_device_identifier_t* createDeviceIdentifier(
- const char* name, int32_t productId, int32_t vendorId,
- input_bus_t bus, const char* uniqueId) override;
- virtual input_device_definition_t* createDeviceDefinition() override;
- virtual input_report_definition_t* createInputReportDefinition() override;
- virtual input_report_definition_t* createOutputReportDefinition() override;
- virtual void freeReportDefinition(input_report_definition_t* reportDef) override;
-
- virtual void inputDeviceDefinitionAddReport(input_device_definition_t* d,
- input_report_definition_t* r) override;
- virtual void inputReportDefinitionAddCollection(input_report_definition_t* report,
- input_collection_id_t id, int32_t arity) override;
- virtual void inputReportDefinitionDeclareUsageInt(input_report_definition_t* report,
- input_collection_id_t id, input_usage_t usage, int32_t min, int32_t max,
- float resolution) override;
- virtual void inputReportDefinitionDeclareUsagesBool(input_report_definition_t* report,
- input_collection_id_t id, input_usage_t* usage, size_t usageCount) override;
-
- virtual input_device_handle_t* registerDevice(input_device_identifier_t* id,
- input_device_definition_t* d) override;
- virtual void unregisterDevice(input_device_handle_t* handle) override;
-
- virtual input_report_t* inputAllocateReport(input_report_definition_t* r) override;
- virtual void inputReportSetUsageInt(input_report_t* r, input_collection_id_t id,
- input_usage_t usage, int32_t value, int32_t arity_index) override;
- virtual void inputReportSetUsageBool(input_report_t* r, input_collection_id_t id,
- input_usage_t usage, bool value, int32_t arity_index) override;
- virtual void reportEvent(input_device_handle_t* d, input_report_t* report) override;
-
- virtual input_property_map_t* inputGetDevicePropertyMap(input_device_identifier_t* id) override;
- virtual input_property_t* inputGetDeviceProperty(input_property_map_t* map,
- const char* key) override;
- virtual const char* inputGetPropertyKey(input_property_t* property) override;
- virtual const char* inputGetPropertyValue(input_property_t* property) override;
- virtual void inputFreeDeviceProperty(input_property_t* property) override;
- virtual void inputFreeDevicePropertyMap(input_property_map_t* map) override;
-
- virtual void dump(String8& result) override;
-
-private:
- String8 mName;
- const input_module_t* mHal;
-};
-
-
-extern "C" {
-
-input_device_identifier_t* create_device_identifier(input_host_t* host,
- const char* name, int32_t product_id, int32_t vendor_id,
- input_bus_t bus, const char* unique_id);
-
-input_device_definition_t* create_device_definition(input_host_t* host);
-
-input_report_definition_t* create_input_report_definition(input_host_t* host);
-
-input_report_definition_t* create_output_report_definition(input_host_t* host);
-
-void free_report_definition(input_host_t* host, input_report_definition_t* report_def);
-
-void input_device_definition_add_report(input_host_t* host,
- input_device_definition_t* d, input_report_definition_t* r);
-
-void input_report_definition_add_collection(input_host_t* host,
- input_report_definition_t* report, input_collection_id_t id, int32_t arity);
-
-void input_report_definition_declare_usage_int(input_host_t* host,
- input_report_definition_t* report, input_collection_id_t id,
- input_usage_t usage, int32_t min, int32_t max, float resolution);
-
-void input_report_definition_declare_usages_bool(input_host_t* host,
- input_report_definition_t* report, input_collection_id_t id,
- input_usage_t* usage, size_t usage_count);
-
-
-input_device_handle_t* register_device(input_host_t* host,
- input_device_identifier_t* id, input_device_definition_t* d);
-
-void unregister_device(input_host_t* host, input_device_handle_t* handle);
-
-input_report_t* input_allocate_report(input_host_t* host, input_report_definition_t* r);
-
-void input_report_set_usage_int(input_host_t* host, input_report_t* r,
- input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index);
-
-void input_report_set_usage_bool(input_host_t* host, input_report_t* r,
- input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index);
-
-void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report);
-
-input_property_map_t* input_get_device_property_map(input_host_t* host,
- input_device_identifier_t* id);
-
-input_property_t* input_get_device_property(input_host_t* host, input_property_map_t* map,
- const char* key);
-
-const char* input_get_property_key(input_host_t* host, input_property_t* property);
-
-const char* input_get_property_value(input_host_t* host, input_property_t* property);
-
-void input_free_device_property(input_host_t* host, input_property_t* property);
-
-void input_free_device_property_map(input_host_t* host, input_property_map_t* map);
-}
-
-} // namespace android
diff --git a/services/inputflinger/host/InputFlinger.cpp b/services/inputflinger/host/InputFlinger.cpp
deleted file mode 100644
index d974c43..0000000
--- a/services/inputflinger/host/InputFlinger.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2013 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 "InputFlinger"
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/PermissionCache.h>
-#include <hardware/input.h>
-#include <log/log.h>
-#include <private/android_filesystem_config.h>
-
-#include "InputFlinger.h"
-#include "InputDriver.h"
-
-namespace android {
-
-const String16 sAccessInputFlingerPermission("android.permission.ACCESS_INPUT_FLINGER");
-const String16 sDumpPermission("android.permission.DUMP");
-
-
-InputFlinger::InputFlinger() :
- BnInputFlinger() {
- ALOGI("InputFlinger is starting");
- mHost = new InputHost();
- mHost->registerInputDriver(new InputDriver(INPUT_INSTANCE_EVDEV));
-}
-
-InputFlinger::~InputFlinger() {
-}
-
-status_t InputFlinger::dump(int fd, const Vector<String16>& args) {
- String8 result;
- const IPCThreadState* ipc = IPCThreadState::self();
- const int pid = ipc->getCallingPid();
- const int uid = ipc->getCallingUid();
- if ((uid != AID_SHELL)
- && !PermissionCache::checkPermission(sDumpPermission, pid, uid)) {
- result.appendFormat("Permission Denial: "
- "can't dump InputFlinger from pid=%d, uid=%d\n", pid, uid);
- } else {
- dumpInternal(result);
- }
- write(fd, result.c_str(), result.size());
- return OK;
-}
-
-void InputFlinger::dumpInternal(String8& result) {
- result.append("INPUT FLINGER (dumpsys inputflinger)\n");
- mHost->dump(result);
-}
-
-}; // namespace android
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
deleted file mode 100644
index 388988b..0000000
--- a/services/inputflinger/host/InputFlinger.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 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 <stdint.h>
-#include <sys/types.h>
-
-#include "InputHost.h"
-
-#include <android/os/BnInputFlinger.h>
-#include <binder/Binder.h>
-#include <cutils/compiler.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-#include <utils/StrongPointer.h>
-
-using android::gui::FocusRequest;
-using android::os::BnInputFlinger;
-
-namespace android {
-
-class InputFlinger : public BnInputFlinger {
-public:
- static char const* getServiceName() ANDROID_API {
- return "inputflinger";
- }
-
- InputFlinger() ANDROID_API;
-
- status_t dump(int fd, const Vector<String16>& args) override;
- binder::Status createInputChannel(const std::string&, InputChannel*) override {
- return binder::Status::ok();
- }
- binder::Status removeInputChannel(const sp<IBinder>&) override { return binder::Status::ok(); }
- binder::Status setFocusedWindow(const FocusRequest&) override { return binder::Status::ok(); }
-
-private:
- ~InputFlinger() override;
-
- void dumpInternal(String8& result);
-
- sp<InputHostInterface> mHost;
-};
-
-} // namespace android
diff --git a/services/inputflinger/host/InputHost.cpp b/services/inputflinger/host/InputHost.cpp
deleted file mode 100644
index 094200a..0000000
--- a/services/inputflinger/host/InputHost.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 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 <vector>
-
-#include "InputDriver.h"
-#include "InputHost.h"
-
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#define INDENT " "
-
-namespace android {
-
-void InputHost::registerInputDriver(InputDriverInterface* driver) {
- LOG_ALWAYS_FATAL_IF(driver == nullptr, "Cannot register a nullptr as an InputDriver!");
- driver->init();
- mDrivers.push_back(driver);
-}
-
-void InputHost::dump(String8& result) {
- result.append(INDENT "Input Drivers:\n");
- for (size_t i = 0; i < mDrivers.size(); i++) {
- mDrivers[i]->dump(result);
- }
-}
-
-} // namespace android
diff --git a/services/inputflinger/host/InputHost.h b/services/inputflinger/host/InputHost.h
deleted file mode 100644
index bdc4225..0000000
--- a/services/inputflinger/host/InputHost.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 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 <vector>
-
-#include <hardware/input.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/StrongPointer.h>
-
-#include "InputDriver.h"
-
-namespace android {
-
-class InputDriverInterface;
-
-class InputHostInterface : public virtual RefBase {
-protected:
- InputHostInterface() = default;
- virtual ~InputHostInterface() = default;
-
-public:
-
- virtual void registerInputDriver(InputDriverInterface* driver) = 0;
-
- virtual void dump(String8& result) = 0;
-};
-
-class InputHost : public InputHostInterface {
-public:
- InputHost() = default;
-
- virtual void registerInputDriver(InputDriverInterface* driver) override;
-
- virtual void dump(String8& result) override;
-
-private:
- std::vector<sp<InputDriverInterface>> mDrivers;
-};
-
-} // namespace android
diff --git a/services/inputflinger/host/inputflinger.rc b/services/inputflinger/host/inputflinger.rc
deleted file mode 100644
index 4130ddc..0000000
--- a/services/inputflinger/host/inputflinger.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service inputflinger /system/bin/inputflinger
- class main
- user system
- group input wakelock
-# onrestart restart zygote
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 06c5e4c..2dc7332 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -148,18 +148,6 @@
"libvulkan",
],
sanitize: {
- // By using the address sanitizer, we not only uncover any issues
- // with the test, but also any issues with the code under test.
- //
- // Note: If you get an runtime link error like:
- //
- // CANNOT LINK EXECUTABLE "/data/local/tmp/libcompositionengine_test": library "libclang_rt.asan-aarch64-android.so" not found
- //
- // it is because the address sanitizer shared objects are not installed
- // by default in the system image.
- //
- // You can either "make dist tests" before flashing, or set this
- // option to false temporarily.
- address: true,
+ hwaddress: true,
},
}
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index 57ebee9..2bf8bc9 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -466,12 +466,18 @@
Rect RequestedLayerState::getBufferCrop() const {
// this is the crop rectangle that applies to the buffer
// itself (as opposed to the window)
- if (!bufferCrop.isEmpty()) {
- // if the buffer crop is defined, we use that
- return bufferCrop;
+ if (!bufferCrop.isEmpty() && externalTexture != nullptr) {
+ // if the buffer crop is defined and there's a valid buffer, intersect buffer size and crop
+ // since the crop should never exceed the size of the buffer.
+ Rect sizeAndCrop;
+ externalTexture->getBounds().intersect(bufferCrop, &sizeAndCrop);
+ return sizeAndCrop;
} else if (externalTexture != nullptr) {
// otherwise we use the whole buffer
return externalTexture->getBounds();
+ } else if (!bufferCrop.isEmpty()) {
+ // if the buffer crop is defined, we use that
+ return bufferCrop;
} else {
// if we don't have a buffer yet, we use an empty/invalid crop
return Rect();
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index 23eb31f..6b5327a 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -41,7 +41,7 @@
bool isLayerActive(const LayerInfo& info, nsecs_t threshold) {
// Layers with an explicit frame rate or frame rate category are always kept active,
- // but ignore NoVote/NoPreference.
+ // but ignore NoVote.
if (info.getSetFrameRateVote().isValid() && !info.getSetFrameRateVote().isNoVote()) {
return true;
}
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index 551d744..0784251 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -292,6 +292,8 @@
if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
if (mLayerVote.category != FrameRateCategory::Default) {
+ ATRACE_FORMAT_INSTANT("ExplicitCategory (%s)",
+ ftl::enum_string(mLayerVote.category).c_str());
ALOGV("%s uses frame rate category: %d", mName.c_str(),
static_cast<int>(mLayerVote.category));
votes.push_back({LayerHistory::LayerVoteType::ExplicitCategory, Fps(),
@@ -300,6 +302,7 @@
if (mLayerVote.fps.isValid() ||
mLayerVote.type != LayerHistory::LayerVoteType::ExplicitDefault) {
+ ATRACE_FORMAT_INSTANT("Vote %s", ftl::enum_string(mLayerVote.type).c_str());
ALOGV("%s voted %d ", mName.c_str(), static_cast<int>(mLayerVote.type));
votes.push_back(mLayerVote);
}
@@ -341,11 +344,13 @@
auto refreshRate = calculateRefreshRateIfPossible(selector, now);
if (refreshRate.has_value()) {
+ ATRACE_FORMAT_INSTANT("calculated (%s)", to_string(*refreshRate).c_str());
ALOGV("%s calculated refresh rate: %s", mName.c_str(), to_string(*refreshRate).c_str());
votes.push_back({LayerHistory::LayerVoteType::Heuristic, refreshRate.value()});
return votes;
}
+ ATRACE_FORMAT_INSTANT("Max (can't resolve refresh rate)");
ALOGV("%s Max (can't resolve refresh rate)", mName.c_str());
votes.push_back({LayerHistory::LayerVoteType::Max, Fps()});
return votes;
@@ -486,8 +491,7 @@
}
bool LayerInfo::FrameRate::isNoVote() const {
- return vote.type == FrameRateCompatibility::NoVote ||
- category == FrameRateCategory::NoPreference;
+ return vote.type == FrameRateCompatibility::NoVote;
}
bool LayerInfo::FrameRate::isValid() const {
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h
index 1e08ec8..7fe407f 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.h
+++ b/services/surfaceflinger/Scheduler/LayerInfo.h
@@ -73,7 +73,7 @@
FrameRateCategory category = FrameRateCategory::Default;
// Returns true if the layer explicitly should contribute to frame rate scoring.
- bool isNoVote() const { return RefreshRateSelector::isNoVote(type, category); }
+ bool isNoVote() const { return RefreshRateSelector::isNoVote(type); }
};
using RefreshRateVotes = ftl::SmallVector<LayerInfo::LayerVote, 2>;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 3ee6a4d..5a00972 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -599,7 +599,8 @@
layer.name.c_str(), ftl::enum_string(layer.vote).c_str(), layer.weight,
layer.desiredRefreshRate.getValue(),
ftl::enum_string(layer.frameRateCategory).c_str());
- if (layer.isNoVote() || layer.vote == LayerVoteType::Min) {
+ if (layer.isNoVote() || layer.frameRateCategory == FrameRateCategory::NoPreference ||
+ layer.vote == LayerVoteType::Min) {
continue;
}
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.h b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
index 9bcbc0e..5d32414 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
@@ -187,14 +187,12 @@
bool operator!=(const LayerRequirement& other) const { return !(*this == other); }
- bool isNoVote() const { return RefreshRateSelector::isNoVote(vote, frameRateCategory); }
+ bool isNoVote() const { return RefreshRateSelector::isNoVote(vote); }
};
// Returns true if the layer explicitly instructs to not contribute to refresh rate selection.
// In other words, true if the layer should be ignored.
- static bool isNoVote(LayerVoteType vote, FrameRateCategory category) {
- return vote == LayerVoteType::NoVote || category == FrameRateCategory::NoPreference;
- }
+ static bool isNoVote(LayerVoteType vote) { return vote == LayerVoteType::NoVote; }
// Global state describing signals that affect refresh rate choice.
struct GlobalSignals {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 312a412..66a3a8e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5820,6 +5820,20 @@
StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n",
pid, uid);
} else {
+ Dumper hwclayersDump = [this](const DumpArgs&, bool, std::string& result)
+ FTL_FAKE_GUARD(mStateLock) -> void const {
+ if (mLayerLifecycleManagerEnabled) {
+ mScheduler
+ ->schedule([this, &result]() FTL_FAKE_GUARD(kMainThreadContext)
+ FTL_FAKE_GUARD(mStateLock) {
+ dumpHwcLayersMinidump(result);
+ })
+ .get();
+ } else {
+ dumpHwcLayersMinidumpLockedLegacy(result);
+ }
+ };
+
static const std::unordered_map<std::string, Dumper> dumpers = {
{"--comp-displays"s, dumper(&SurfaceFlinger::dumpCompositionDisplays)},
{"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
@@ -5828,7 +5842,7 @@
{"--events"s, dumper(&SurfaceFlinger::dumpEvents)},
{"--frametimeline"s, argsDumper(&SurfaceFlinger::dumpFrameTimeline)},
{"--hdrinfo"s, dumper(&SurfaceFlinger::dumpHdrInfo)},
- {"--hwclayers"s, dumper(&SurfaceFlinger::dumpHwcLayersMinidumpLockedLegacy)},
+ {"--hwclayers"s, std::move(hwclayersDump)},
{"--latency"s, argsDumper(&SurfaceFlinger::dumpStatsLocked)},
{"--latency-clear"s, argsDumper(&SurfaceFlinger::clearStatsLocked)},
{"--list"s, dumper(&SurfaceFlinger::listLayersLocked)},
@@ -7743,6 +7757,7 @@
ATRACE_CALL();
auto layers = getLayerSnapshots();
+
for (auto& [_, layerFE] : layers) {
frontend::LayerSnapshot* snapshot = layerFE->mSnapshot.get();
captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure);
@@ -7794,18 +7809,26 @@
pickBestDataspace(requestedDataspace, display, captureResults.capturedHdrLayers,
renderArea->getHintForSeamlessTransition());
sdrWhitePointNits = state.sdrWhitePointNits;
- displayBrightnessNits = state.displayBrightnessNits;
- // Only clamp the display brightness if this is not a seamless transition. Otherwise
- // for seamless transitions it's important to match the current display state as the
- // buffer will be shown under these same conditions, and we want to avoid any flickers
- if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) {
- // Restrict the amount of HDR "headroom" in the screenshot to avoid over-dimming
- // the SDR portion. 2.0 chosen by experimentation
- constexpr float kMaxScreenshotHeadroom = 2.0f;
- displayBrightnessNits =
- std::min(sdrWhitePointNits * kMaxScreenshotHeadroom, displayBrightnessNits);
- }
+ // TODO(b/298219334): Clean this up once we verify this doesn't break anything
+ static constexpr bool kScreenshotsDontDim = true;
+
+ if (kScreenshotsDontDim && !captureResults.capturedHdrLayers) {
+ displayBrightnessNits = sdrWhitePointNits;
+ } else {
+ displayBrightnessNits = state.displayBrightnessNits;
+ // Only clamp the display brightness if this is not a seamless transition. Otherwise
+ // for seamless transitions it's important to match the current display state as the
+ // buffer will be shown under these same conditions, and we want to avoid any
+ // flickers
+ if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) {
+ // Restrict the amount of HDR "headroom" in the screenshot to avoid over-dimming
+ // the SDR portion. 2.0 chosen by experimentation
+ constexpr float kMaxScreenshotHeadroom = 2.0f;
+ displayBrightnessNits = std::min(sdrWhitePointNits * kMaxScreenshotHeadroom,
+ displayBrightnessNits);
+ }
+ }
if (requestedDataspace == ui::Dataspace::UNKNOWN) {
renderIntent = state.renderIntent;
}
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index ff644ba..acfde71 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -372,6 +372,17 @@
mLifecycleManager.applyTransactions(transactions);
}
+ void setBufferCrop(uint32_t id, const Rect& bufferCrop) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eBufferCropChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.bufferCrop = bufferCrop;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
void setDataspace(uint32_t id, ui::Dataspace dataspace) {
std::vector<TransactionState> transactions;
transactions.emplace_back();
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index b7996ce..c432ad0 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -494,14 +494,14 @@
time += HI_FPS_PERIOD;
}
- ASSERT_TRUE(summarizeLayerHistory(time).empty());
+ EXPECT_EQ(1, summarizeLayerHistory(time).size());
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
// layer became inactive
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_TRUE(summarizeLayerHistory(time).empty());
- EXPECT_EQ(0, activeLayerCount());
+ EXPECT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 1227b99..767dd4f 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -802,4 +802,33 @@
aidl::android::hardware::graphics::composer3::Composition::REFRESH_RATE_INDICATOR);
}
+TEST_F(LayerSnapshotTest, setBufferCrop) {
+ // validate no buffer but has crop
+ Rect crop = Rect(0, 0, 50, 50);
+ setBufferCrop(1, crop);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot(1)->geomContentCrop, crop);
+
+ setBuffer(1,
+ std::make_shared<renderengine::mock::FakeExternalTexture>(100U /*width*/,
+ 100U /*height*/,
+ 42ULL /* bufferId */,
+ HAL_PIXEL_FORMAT_RGBA_8888,
+ 0 /*usage*/));
+ // validate a buffer crop within the buffer bounds
+ setBufferCrop(1, crop);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot(1)->geomContentCrop, crop);
+
+ // validate a buffer crop outside the buffer bounds
+ crop = Rect(0, 0, 150, 150);
+ setBufferCrop(1, crop);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100));
+
+ // validate no buffer crop
+ setBufferCrop(1, Rect());
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100));
+}
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index 264b172..0b67137 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -1410,11 +1410,6 @@
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_30_60_90_120) {
auto selector = createSelector(makeModes(kMode30, kMode60, kMode90, kMode120), kModeId60);
- std::vector<LayerRequirement> layers = {{.vote = LayerVoteType::ExplicitDefault, .weight = 1.f},
- {.vote = LayerVoteType::ExplicitCategory,
- .weight = 1.f}};
- auto& lr = layers[0];
-
struct Case {
// Params
Fps desiredFrameRate = 0_Hz;
@@ -1431,7 +1426,7 @@
{0_Hz, FrameRateCategory::High, 90_Hz},
{0_Hz, FrameRateCategory::Normal, 60_Hz},
{0_Hz, FrameRateCategory::Low, 30_Hz},
- {0_Hz, FrameRateCategory::NoPreference, 60_Hz},
+ {0_Hz, FrameRateCategory::NoPreference, 30_Hz},
// Cases that have both desired frame rate and frame rate category requirements.
{24_Hz, FrameRateCategory::High, 120_Hz},
@@ -1444,34 +1439,41 @@
};
for (auto testCase : testCases) {
+ std::vector<LayerRequirement> layers;
ALOGI("**** %s: Testing desiredFrameRate=%s, frameRateCategory=%s", __func__,
to_string(testCase.desiredFrameRate).c_str(),
ftl::enum_string(testCase.frameRateCategory).c_str());
- lr.desiredRefreshRate = testCase.desiredFrameRate;
-
- std::stringstream ss;
- ss << to_string(testCase.desiredFrameRate)
- << ", category=" << ftl::enum_string(testCase.frameRateCategory);
- lr.name = ss.str();
+ if (testCase.desiredFrameRate.isValid()) {
+ std::stringstream ss;
+ ss << to_string(testCase.desiredFrameRate) << "ExplicitDefault";
+ LayerRequirement layer = {.name = ss.str(),
+ .vote = LayerVoteType::ExplicitDefault,
+ .desiredRefreshRate = testCase.desiredFrameRate,
+ .weight = 1.f};
+ layers.push_back(layer);
+ }
if (testCase.frameRateCategory != FrameRateCategory::Default) {
- layers[1].frameRateCategory = testCase.frameRateCategory;
+ std::stringstream ss;
+ ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory) << ")";
+ LayerRequirement layer = {.name = ss.str(),
+ .vote = LayerVoteType::ExplicitCategory,
+ .frameRateCategory = testCase.frameRateCategory,
+ .weight = 1.f};
+ layers.push_back(layer);
}
EXPECT_EQ(testCase.expectedFrameRate, selector.getBestFrameRateMode(layers)->getPeakFps())
- << "did not get expected frame rate for " << lr.name;
+ << "Did not get expected frame rate for frameRate="
+ << to_string(testCase.desiredFrameRate)
+ << " category=" << ftl::enum_string(testCase.frameRateCategory);
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_60_120) {
auto selector = createSelector(makeModes(kMode60, kMode120), kModeId60);
- std::vector<LayerRequirement> layers = {{.vote = LayerVoteType::ExplicitDefault, .weight = 1.f},
- {.vote = LayerVoteType::ExplicitCategory,
- .weight = 1.f}};
- auto& lr = layers[0];
-
struct Case {
// Params
Fps desiredFrameRate = 0_Hz;
@@ -1501,23 +1503,35 @@
};
for (auto testCase : testCases) {
+ std::vector<LayerRequirement> layers;
ALOGI("**** %s: Testing desiredFrameRate=%s, frameRateCategory=%s", __func__,
to_string(testCase.desiredFrameRate).c_str(),
ftl::enum_string(testCase.frameRateCategory).c_str());
- lr.desiredRefreshRate = testCase.desiredFrameRate;
-
- std::stringstream ss;
- ss << to_string(testCase.desiredFrameRate)
- << ", category=" << ftl::enum_string(testCase.frameRateCategory);
- lr.name = ss.str();
+ if (testCase.desiredFrameRate.isValid()) {
+ std::stringstream ss;
+ ss << to_string(testCase.desiredFrameRate) << "ExplicitDefault";
+ LayerRequirement layer = {.name = ss.str(),
+ .vote = LayerVoteType::ExplicitDefault,
+ .desiredRefreshRate = testCase.desiredFrameRate,
+ .weight = 1.f};
+ layers.push_back(layer);
+ }
if (testCase.frameRateCategory != FrameRateCategory::Default) {
- layers[1].frameRateCategory = testCase.frameRateCategory;
+ std::stringstream ss;
+ ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory) << ")";
+ LayerRequirement layer = {.name = ss.str(),
+ .vote = LayerVoteType::ExplicitCategory,
+ .frameRateCategory = testCase.frameRateCategory,
+ .weight = 1.f};
+ layers.push_back(layer);
}
EXPECT_EQ(testCase.expectedFrameRate, selector.getBestFrameRateMode(layers)->getPeakFps())
- << "did not get expected frame rate for " << lr.name;
+ << "Did not get expected frame rate for frameRate="
+ << to_string(testCase.desiredFrameRate)
+ << " category=" << ftl::enum_string(testCase.frameRateCategory);
}
}
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index 608fa76..9899d42 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -19,6 +19,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <gui/FrameRateUtils.h>
#include <gui/LayerMetadata.h>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
@@ -325,48 +326,6 @@
std::make_shared<EffectLayerFactory>()),
PrintToStringParamName);
-TEST_F(SetFrameRateTest, ValidateFrameRate) {
- EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
- EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
- EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS, ""));
- EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
-
- // Privileged APIs.
- EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
- EXPECT_FALSE(ValidateFrameRate(0.0f, ANATIVEWINDOW_FRAME_RATE_NO_VOTE,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
-
- constexpr bool kPrivileged = true;
- EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "",
- kPrivileged));
- EXPECT_TRUE(ValidateFrameRate(0.0f, ANATIVEWINDOW_FRAME_RATE_NO_VOTE,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "",
- kPrivileged));
-
- // Invalid frame rate.
- EXPECT_FALSE(ValidateFrameRate(-1, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
- EXPECT_FALSE(ValidateFrameRate(1.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
- EXPECT_FALSE(ValidateFrameRate(0.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
-
- // Invalid compatibility.
- EXPECT_FALSE(
- ValidateFrameRate(60.0f, -1, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
- EXPECT_FALSE(ValidateFrameRate(60.0f, 2, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
-
- // Invalid change frame rate strategy.
- EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, -1, ""));
- EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, 2, ""));
-}
-
TEST_P(SetFrameRateTest, SetOnParentActivatesTree) {
const auto& layerFactory = GetParam();