Merge "Expose EDID fields in DeviceProductInfo"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 3a79357..814a4ed 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1672,7 +1672,7 @@
// information. This information MUST NOT identify user-installed packages (UIDs are OK, package
// names are not), and MUST NOT contain logs of user application traffic.
// TODO(b/148168577) rename this and other related fields/methods to "connectivity" instead.
-static void DumpstateTelephonyOnly() {
+static void DumpstateTelephonyOnly(const std::string& calling_package) {
DurationReporter duration_reporter("DUMPSTATE");
const CommandOptions DUMPSYS_COMPONENTS_OPTIONS = CommandOptions::WithTimeout(60).Build();
@@ -1695,11 +1695,18 @@
RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
- // TODO(b/146521742) build out an argument to include bound services here for user builds
- RunDumpsys("DUMPSYS", {"carrier_config"}, CommandOptions::WithTimeout(90).Build(),
- SEC_TO_MSEC(10));
- RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
- SEC_TO_MSEC(10));
+ if (include_sensitive_info) {
+ // Carrier apps' services will be dumped below in dumpsys activity service all-non-platform.
+ RunDumpsys("DUMPSYS", {"carrier_config"}, CommandOptions::WithTimeout(90).Build(),
+ SEC_TO_MSEC(10));
+ } else {
+ // If the caller is a carrier app and has a carrier service, dump it here since we aren't
+ // running dumpsys activity service all-non-platform below. Due to the increased output, we
+ // give a higher timeout as well.
+ RunDumpsys("DUMPSYS", {"carrier_config", "--requesting-package", calling_package},
+ CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(30));
+ }
+ RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
RunDumpsys("DUMPSYS", {"netpolicy"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
RunDumpsys("DUMPSYS", {"network_management"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
@@ -2587,7 +2594,7 @@
if (options_->telephony_only) {
MaybeCheckUserConsent(calling_uid, calling_package);
- DumpstateTelephonyOnly();
+ DumpstateTelephonyOnly(calling_package);
DumpstateBoard();
} else if (options_->wifi_only) {
MaybeCheckUserConsent(calling_uid, calling_package);
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 3713e87..e1a7bb8 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -701,11 +701,13 @@
if (delete_dir_contents_and_dir(path) != 0) {
res = error("Failed to delete " + path);
}
- destroy_app_current_profiles(packageName, userId);
- // TODO(calin): If the package is still installed by other users it's probably
- // beneficial to keep the reference profile around.
- // Verify if it's ok to do that.
- destroy_app_reference_profile(packageName);
+ if ((flags & FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
+ destroy_app_current_profiles(packageName, userId);
+ // TODO(calin): If the package is still installed by other users it's probably
+ // beneficial to keep the reference profile around.
+ // Verify if it's ok to do that.
+ destroy_app_reference_profile(packageName);
+ }
}
if (flags & FLAG_STORAGE_EXTERNAL) {
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 7c989f6..6459805 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -61,11 +61,15 @@
static std::vector<apex::ApexFile> ActivateApexPackages() {
// The logic here is (partially) copied and adapted from
- // system/apex/apexd/apexd_main.cpp.
+ // system/apex/apexd/apexd.cpp.
//
- // Only scan the APEX directory under /system (within the chroot dir).
- // Cast call to void to suppress warn_unused_result.
- static_cast<void>(apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir));
+ // Only scan the APEX directory under /system, /system_ext and /vendor (within the chroot dir).
+ std::vector<const char*> apex_dirs{apex::kApexPackageSystemDir, apex::kApexPackageSystemExtDir,
+ apex::kApexPackageVendorDir};
+ for (const auto& dir : apex_dirs) {
+ // Cast call to void to suppress warn_unused_result.
+ static_cast<void>(apex::scanPackagesDirAndActivate(dir));
+ }
return apex::getActivePackages();
}
diff --git a/include/android/sensor.h b/include/android/sensor.h
index e63ac4b..eb40779 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -244,6 +244,9 @@
ASENSOR_TYPE_ACCELEROMETER_UNCALIBRATED = 35,
/**
* {@link ASENSOR_TYPE_HINGE_ANGLE}
+ * reporting-mode: on-change
+ *
+ * The hinge angle sensor value is returned in degrees.
*/
ASENSOR_TYPE_HINGE_ANGLE = 36,
};
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
index 7a77f6d..779ed41 100644
--- a/libs/binder/Static.cpp
+++ b/libs/binder/Static.cpp
@@ -64,13 +64,9 @@
int mFD;
};
-static LogTextOutput gLogTextOutput;
-static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);
-static FdTextOutput gStderrTextOutput(STDERR_FILENO);
-
-TextOutput& alog(gLogTextOutput);
-TextOutput& aout(gStdoutTextOutput);
-TextOutput& aerr(gStderrTextOutput);
+TextOutput& alog(*new LogTextOutput());
+TextOutput& aout(*new FdTextOutput(STDOUT_FILENO));
+TextOutput& aerr(*new FdTextOutput(STDERR_FILENO));
// ------------ ProcessState.cpp
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
index e6b743b..33e4586 100644
--- a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
@@ -238,7 +238,9 @@
// ourselves. The defaults are harmless.
AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump);
#ifdef HAS_BINDER_SHELL_COMMAND
- AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand);
+ if (AIBinder_Class_setHandleShellCommand != nullptr) {
+ AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand);
+ }
#endif
return clazz;
}
diff --git a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
new file mode 100644
index 0000000..ac46cb8
--- /dev/null
+++ b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_parcel.h>
+
+__BEGIN_DECLS
+
+/**
+ * Gets whether or not FDs are allowed by this AParcel
+ *
+ * \return true if FDs are allowed, false if they are not. That is
+ * if this returns false then AParcel_writeParcelFileDescriptor will
+ * return STATUS_FDS_NOT_ALLOWED.
+ */
+bool AParcel_getAllowFds(const AParcel*);
+
+__END_DECLS
\ No newline at end of file
diff --git a/libs/binder/ndk/include_platform/android/binder_shell.h b/libs/binder/ndk/include_platform/android/binder_shell.h
index 17b38b0..07d89e6 100644
--- a/libs/binder/ndk/include_platform/android/binder_shell.h
+++ b/libs/binder/ndk/include_platform/android/binder_shell.h
@@ -48,8 +48,7 @@
* \param handleShellCommand function to call when a shell transaction is
* received
*/
-void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz,
- AIBinder_handleShellCommand handleShellCommand)
- __INTRODUCED_IN(30);
+__attribute__((weak)) void AIBinder_Class_setHandleShellCommand(
+ AIBinder_Class* clazz, AIBinder_handleShellCommand handleShellCommand) __INTRODUCED_IN(30);
__END_DECLS
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 7e72f22..a9eba47 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -114,3 +114,8 @@
local:
*;
};
+
+LIBBINDER_NDK_PLATFORM {
+ global:
+ AParcel_getAllowFds;
+};
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index f0ea237..703ceae 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -15,6 +15,7 @@
*/
#include <android/binder_parcel.h>
+#include <android/binder_parcel_platform.h>
#include "parcel_internal.h"
#include "ibinder_internal.h"
@@ -645,4 +646,8 @@
return ReadArray<int8_t>(parcel, arrayData, allocator);
}
+bool AParcel_getAllowFds(const AParcel* parcel) {
+ return parcel->get()->allowFds();
+}
+
// @END
diff --git a/libs/cputimeinstate/cputimeinstate.cpp b/libs/cputimeinstate/cputimeinstate.cpp
index b6b81bb..fbc485c 100644
--- a/libs/cputimeinstate/cputimeinstate.cpp
+++ b/libs/cputimeinstate/cputimeinstate.cpp
@@ -156,7 +156,7 @@
static bool attachTracepointProgram(const std::string &eventType, const std::string &eventName) {
std::string path = StringPrintf(BPF_FS_PATH "prog_time_in_state_tracepoint_%s_%s",
eventType.c_str(), eventName.c_str());
- int prog_fd = bpf_obj_get(path.c_str());
+ int prog_fd = bpfFdGet(path.c_str(), BPF_F_RDONLY);
if (prog_fd < 0) return false;
return bpf_attach_tracepoint(prog_fd, eventType.c_str(), eventName.c_str()) >= 0;
}
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 02416e4..acd833f 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -180,9 +180,9 @@
}
mPendingReleaseItem.item = std::move(mSubmitted.front());
mSubmitted.pop();
- if (mNextTransaction == nullptr) {
- processNextBufferLocked();
- }
+
+ processNextBufferLocked();
+
mCallbackCV.notify_all();
decStrong((void*)transactionCallbackThunk);
}
@@ -201,7 +201,7 @@
SurfaceComposerClient::Transaction localTransaction;
bool applyTransaction = true;
SurfaceComposerClient::Transaction* t = &localTransaction;
- if (mNextTransaction != nullptr) {
+ if (mNextTransaction != nullptr && mUseNextTransaction) {
t = mNextTransaction;
mNextTransaction = nullptr;
applyTransaction = false;
@@ -263,9 +263,10 @@
std::unique_lock _lock{mMutex};
if (mNextTransaction != nullptr) {
- while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS) {
+ while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
mCallbackCV.wait(_lock);
}
+ mUseNextTransaction = true;
}
// add to shadow queue
mNumFrameAvailable++;
@@ -274,6 +275,7 @@
void BLASTBufferQueue::setNextTransaction(SurfaceComposerClient::Transaction* t) {
std::lock_guard _lock{mMutex};
+ mUseNextTransaction = false;
mNextTransaction = t;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7017b7c..ff8b719 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -526,21 +526,6 @@
mDesiredPresentTime = -1;
}
-void SurfaceComposerClient::doDropReferenceTransaction(const sp<IBinder>& handle) {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- Vector<ComposerState> composerStates;
- Vector<DisplayState> displayStates;
-
- ComposerState s;
- s.state.surface = handle;
- s.state.what |= layer_state_t::eReparent;
- s.state.parentHandleForChild = nullptr;
-
- composerStates.add(s);
- sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
- sf->setTransactionState(composerStates, displayStates, 0, applyToken, {}, -1, {}, false, {});
-}
-
void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
@@ -1558,7 +1543,7 @@
}
ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err));
if (err == NO_ERROR) {
- return new SurfaceControl(this, handle, gbp, true /* owned */, transformHint);
+ return new SurfaceControl(this, handle, gbp, transformHint);
}
}
return nullptr;
@@ -1589,7 +1574,7 @@
}
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
- *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */, transformHint);
+ *outSurface = new SurfaceControl(this, handle, gbp, transformHint);
}
}
return err;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 6292388..a332a1f 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -46,34 +46,22 @@
// ============================================================================
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
- const sp<IGraphicBufferProducer>& gbp, bool owned,
+ const sp<IGraphicBufferProducer>& gbp,
uint32_t transform)
: mClient(client),
mHandle(handle),
mGraphicBufferProducer(gbp),
- mOwned(owned),
mTransformHint(transform) {}
SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
mClient = other->mClient;
mHandle = other->mHandle;
mGraphicBufferProducer = other->mGraphicBufferProducer;
- mOwned = false;
mTransformHint = other->mTransformHint;
}
SurfaceControl::~SurfaceControl()
{
- // Avoid reparenting the server-side surface to null if we are not the owner of it,
- // meaning that we retrieved it from another process.
- if (mHandle != nullptr && mOwned) {
- SurfaceComposerClient::doDropReferenceTransaction(mHandle);
- }
- release();
-}
-
-void SurfaceControl::release()
-{
// Trigger an IPC now, to make sure things
// happen without delay, since these resources are quite heavy.
mClient.clear();
@@ -157,7 +145,6 @@
sp<IBinder> SurfaceControl::getHandle() const
{
- Mutex::Autolock lock(mLock);
return mHandle;
}
@@ -206,7 +193,7 @@
return new SurfaceControl(new SurfaceComposerClient(
interface_cast<ISurfaceComposerClient>(client)),
handle.get(), interface_cast<IGraphicBufferProducer>(gbp),
- false /* owned */, transformHint);
+ transformHint);
}
// ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 1b22df2..64c21e0 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -123,6 +123,8 @@
sp<BLASTBufferItemConsumer> mBufferItemConsumer;
SurfaceComposerClient::Transaction* mNextTransaction GUARDED_BY(mMutex);
+
+ bool mUseNextTransaction = false;
};
} // namespace android
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index d0bb6a3..27877bb 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -184,12 +184,6 @@
static bool getProtectedContentSupport();
/**
- * Called from SurfaceControl d'tor to 'destroy' the surface (or rather, reparent it
- * to null), but without needing an sp<SurfaceControl> to avoid infinite ressurection.
- */
- static void doDropReferenceTransaction(const sp<IBinder>& handle);
-
- /**
* Uncaches a buffer in ISurfaceComposer. It must be uncached via a transaction so that it is
* in order with other transactions that use buffers.
*/
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index 7bc7c68..ac2bbcc 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -58,10 +58,6 @@
static bool isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
- // Release the handles assosciated with the SurfaceControl, without reparenting
- // them off-screen. At the moment if this isn't executed before ~SurfaceControl
- // is called then the destructor will reparent the layer off-screen for you.
- void release();
// Reparent off-screen and release. This is invoked by the destructor.
void destroy();
@@ -89,7 +85,7 @@
explicit SurfaceControl(const sp<SurfaceControl>& other);
SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
- const sp<IGraphicBufferProducer>& gbp, bool owned, uint32_t transformHint = 0);
+ const sp<IGraphicBufferProducer>& gbp, uint32_t transformHint = 0);
private:
// can't be copied
@@ -109,7 +105,6 @@
sp<IGraphicBufferProducer> mGraphicBufferProducer;
mutable Mutex mLock;
mutable sp<Surface> mSurfaceData;
- bool mOwned;
uint32_t mTransformHint;
};
diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp
index b1a84bd..eb66c8f 100644
--- a/libs/renderengine/gl/filters/BlurFilter.cpp
+++ b/libs/renderengine/gl/filters/BlurFilter.cpp
@@ -132,8 +132,7 @@
}
string BlurFilter::getVertexShader() const {
- return R"SHADER(
- #version 310 es
+ return R"SHADER(#version 310 es
in vec2 aPosition;
in highp vec2 aUV;
@@ -147,8 +146,7 @@
}
string BlurFilter::getMixFragShader() const {
- string shader = R"SHADER(
- #version 310 es
+ string shader = R"SHADER(#version 310 es
precision mediump float;
in highp vec2 vUV;
diff --git a/libs/renderengine/gl/filters/GaussianBlurFilter.cpp b/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
index 4d7bf44..a0d7af8 100644
--- a/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
+++ b/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
@@ -43,7 +43,7 @@
mVPosLoc = mVerticalProgram.getAttributeLocation("aPosition");
mVUvLoc = mVerticalProgram.getAttributeLocation("aUV");
mVTextureLoc = mVerticalProgram.getUniformLocation("uTexture");
- mVIncrementLoc = mVerticalProgram.getUniformLocation("uIncrement");
+ mVGaussianOffsetLoc = mVerticalProgram.getUniformLocation("uGaussianOffsets");
mVNumSamplesLoc = mVerticalProgram.getUniformLocation("uSamples");
mVGaussianWeightLoc = mVerticalProgram.getUniformLocation("uGaussianWeights");
@@ -51,7 +51,7 @@
mHPosLoc = mHorizontalProgram.getAttributeLocation("aPosition");
mHUvLoc = mHorizontalProgram.getAttributeLocation("aUV");
mHTextureLoc = mHorizontalProgram.getUniformLocation("uTexture");
- mHIncrementLoc = mHorizontalProgram.getUniformLocation("uIncrement");
+ mHGaussianOffsetLoc = mHorizontalProgram.getUniformLocation("uGaussianOffsets");
mHNumSamplesLoc = mHorizontalProgram.getUniformLocation("uSamples");
mHGaussianWeightLoc = mHorizontalProgram.getUniformLocation("uGaussianWeights");
}
@@ -60,6 +60,36 @@
mVerticalPassFbo.allocateBuffers(mBlurredFbo.getBufferWidth(), mBlurredFbo.getBufferHeight());
}
+static void calculateLinearGaussian(uint32_t samples, double dimension,
+ GLfloat* gaussianLinearOffsets, GLfloat* gaussianWeights,
+ GLfloat* gaussianLinearWeights) {
+ // The central point in the symmetric bell curve is not offset.
+ // This decision allows one less sampling in the GPU.
+ gaussianLinearWeights[0] = gaussianWeights[0];
+ gaussianLinearOffsets[0] = 0.0;
+
+ // Calculate the linear weights.
+ // This is a vector reduction where an element of the packed reduced array
+ // contains the sum of two adjacent members of the original packed array.
+ // We start preserving the element 1 of the array and then perform sum for
+ // every other (i+=2) element of the gaussianWeights array.
+ gaussianLinearWeights[1] = gaussianWeights[1];
+ const auto start = 1 + ((samples - 1) & 0x1);
+ for (size_t i = start; i < samples; i += 2) {
+ gaussianLinearWeights[start + i / 2] = gaussianWeights[i] + gaussianWeights[i + 1];
+ }
+
+ // Calculate the texture coordinates offsets as an average of the initial offsets,
+ // weighted by the Gaussian weights as described in the original article.
+ gaussianLinearOffsets[1] = 1.0 / dimension;
+ for (size_t i = start; i < samples; i += 2) {
+ GLfloat offset_1 = float(i) / dimension;
+ GLfloat offset_2 = float(i + 1) / dimension;
+ gaussianLinearOffsets[start + i / 2] =
+ (offset_1 * gaussianWeights[i] + offset_2 * gaussianWeights[i + 1]) /
+ gaussianLinearWeights[start + i / 2];
+ }
+}
status_t GaussianBlurFilter::prepare() {
ATRACE_NAME("GaussianBlurFilter::prepare");
@@ -88,27 +118,47 @@
mVerticalPassFbo.bind();
mVerticalProgram.useProgram();
- // Precompute gaussian bell curve, and send it to the shader to avoid
- // unnecessary computations.
- auto samples = min(mRadius, kNumSamples);
+ // Precompute gaussian bell curve, and send it to the shader to avoid unnecessary computations.
+ double radiusD = fmax(1.0, mRadius * kFboScale);
+ auto samples = int(fmin(radiusD, kNumSamples));
GLfloat gaussianWeights[kNumSamples] = {};
- for (size_t i = 0; i < samples; i++) {
- float normalized = float(i) / samples;
+
+ gaussianWeights[0] = 1.0f;
+ auto totalWeight = gaussianWeights[0];
+
+ // Gaussian weights calculation.
+ for (size_t i = 1; i < samples; i++) {
+ const double normalized = i / radiusD;
gaussianWeights[i] = (float)exp(-K * normalized * normalized);
+ totalWeight += 2.0 * gaussianWeights[i];
}
- // set uniforms
+ // Gaussian weights normalization to avoid work in the GPU.
+ for (size_t i = 0; i < samples; i++) {
+ gaussianWeights[i] /= totalWeight;
+ }
+
auto width = mVerticalPassFbo.getBufferWidth();
auto height = mVerticalPassFbo.getBufferHeight();
- auto radiusF = fmax(1.0f, mRadius * kFboScale);
glViewport(0, 0, width, height);
+
+ // Allocate space for the corrected Gaussian weights and offsets.
+ // We could use less space, but let's keep the code simple.
+ GLfloat gaussianLinearWeights[kNumSamples] = {};
+ GLfloat gaussianLinearOffsets[kNumSamples] = {};
+
+ // Calculate the weights and offsets for the vertical pass.
+ // This only need to be called every time mRadius or height changes, so it could be optimized.
+ calculateLinearGaussian(samples, double(height), gaussianLinearOffsets, gaussianWeights,
+ gaussianLinearWeights);
+ // set uniforms
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mBlurredFbo.getTextureName());
glUniform1i(mVTextureLoc, 0);
- glUniform2f(mVIncrementLoc, radiusF / (width * 2.0f), radiusF / (height * 2.0f));
- glUniform1i(mVNumSamplesLoc, samples);
- glUniform1fv(mVGaussianWeightLoc, kNumSamples, gaussianWeights);
- mEngine.checkErrors("Setting vertical-diagonal pass uniforms");
+ glUniform1i(mVNumSamplesLoc, 1 + (samples + 1) / 2);
+ glUniform1fv(mVGaussianWeightLoc, kNumSamples, gaussianLinearWeights);
+ glUniform1fv(mVGaussianOffsetLoc, kNumSamples, gaussianLinearOffsets);
+ mEngine.checkErrors("Setting vertical pass uniforms");
drawMesh(mVUvLoc, mVPosLoc);
@@ -116,14 +166,18 @@
mBlurredFbo.bind();
mHorizontalProgram.useProgram();
+ // Calculate the weights and offsets for the horizontal pass.
+ // This only needs to be called every time mRadius or width change, so it could be optimized.
+ calculateLinearGaussian(samples, double(width), gaussianLinearOffsets, gaussianWeights,
+ gaussianLinearWeights);
// set uniforms
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mVerticalPassFbo.getTextureName());
glUniform1i(mHTextureLoc, 0);
- glUniform2f(mHIncrementLoc, radiusF / (width * 2.0f), radiusF / (height * 2.0f));
- glUniform1i(mHNumSamplesLoc, samples);
- glUniform1fv(mHGaussianWeightLoc, kNumSamples, gaussianWeights);
- mEngine.checkErrors("Setting vertical pass uniforms");
+ glUniform1i(mHNumSamplesLoc, 1 + (samples + 1) / 2);
+ glUniform1fv(mHGaussianWeightLoc, kNumSamples, gaussianLinearWeights);
+ glUniform1fv(mHGaussianOffsetLoc, kNumSamples, gaussianLinearOffsets);
+ mEngine.checkErrors("Setting horizontal pass uniforms");
drawMesh(mHUvLoc, mHPosLoc);
@@ -142,43 +196,37 @@
stringstream shader;
shader << "#version 310 es\n"
<< "#define DIRECTION " << (horizontal ? "1" : "0") << "\n"
- << "#define NUM_SAMPLES " << kNumSamples <<
+ << "#define NUM_SAMPLES " << 1 + (kNumSamples + 1) / 2 <<
R"SHADER(
precision mediump float;
uniform sampler2D uTexture;
- uniform vec2 uIncrement;
uniform float[NUM_SAMPLES] uGaussianWeights;
+ uniform float[NUM_SAMPLES] uGaussianOffsets;
uniform int uSamples;
highp in vec2 vUV;
out vec4 fragColor;
- vec3 gaussianBlur(sampler2D texture, highp vec2 uv, float inc, vec2 direction) {
- float totalWeight = 0.0;
- vec3 blurred = vec3(0.0);
- float fSamples = 1.0 / float(uSamples);
-
- for (int i = -uSamples; i <= uSamples; i++) {
- float weight = uGaussianWeights[abs(i)];
- float normalized = float(i) * fSamples;
- float radInc = inc * normalized;
- blurred += weight * (texture(texture, radInc * direction + uv, 0.0)).rgb;
- totalWeight += weight;
- }
-
- return blurred / totalWeight;
- }
-
void main() {
#if DIRECTION == 1
- vec3 color = gaussianBlur(uTexture, vUV, uIncrement.x, vec2(1.0, 0.0));
+ const vec2 direction = vec2(1.0, 0.0);
#else
- vec3 color = gaussianBlur(uTexture, vUV, uIncrement.y, vec2(0.0, 1.0));
+ const vec2 direction = vec2(0.0, 1.0);
#endif
- fragColor = vec4(color, 1.0);
- }
+ // Iteration zero outside loop to avoid sampling the central point twice.
+ vec4 blurred = uGaussianWeights[0] * (texture(uTexture, vUV, 0.0));
+
+ // Iterate one side of the bell to halve the loop iterations.
+ for (int i = 1; i <= uSamples; i++) {
+ vec2 offset = uGaussianOffsets[i] * direction;
+ blurred += uGaussianWeights[i] * (texture(uTexture, vUV + offset, 0.0));
+ blurred += uGaussianWeights[i] * (texture(uTexture, vUV - offset, 0.0));
+ }
+
+ fragColor = vec4(blurred.rgb, 1.0);
+ }
)SHADER";
return shader.str();
}
diff --git a/libs/renderengine/gl/filters/GaussianBlurFilter.h b/libs/renderengine/gl/filters/GaussianBlurFilter.h
index 8580522..44f5fde 100644
--- a/libs/renderengine/gl/filters/GaussianBlurFilter.h
+++ b/libs/renderengine/gl/filters/GaussianBlurFilter.h
@@ -28,9 +28,12 @@
namespace renderengine {
namespace gl {
+// Class that implements a Gaussian Filter that uses Linear Sampling
+// to halve the number of samples and reduce runtime by 40% as described in:
+// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling
class GaussianBlurFilter : public BlurFilter {
public:
- static constexpr uint32_t kNumSamples = 12;
+ static constexpr uint32_t kNumSamples = 22;
explicit GaussianBlurFilter(GLESRenderEngine& engine);
status_t prepare() override;
@@ -47,7 +50,7 @@
GLuint mVPosLoc;
GLuint mVUvLoc;
GLuint mVTextureLoc;
- GLuint mVIncrementLoc;
+ GLuint mVGaussianOffsetLoc;
GLuint mVNumSamplesLoc;
GLuint mVGaussianWeightLoc;
@@ -56,7 +59,7 @@
GLuint mHPosLoc;
GLuint mHUvLoc;
GLuint mHTextureLoc;
- GLuint mHIncrementLoc;
+ GLuint mHGaussianOffsetLoc;
GLuint mHNumSamplesLoc;
GLuint mHGaussianWeightLoc;
};
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 1c08ab1..ae82cd4 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -43,12 +43,14 @@
mSources(0),
mIsExternal(false),
mHasMic(false),
- mDropUntilNextSync(false) {}
+ mDropUntilNextSync(false) {
+ mDeviceContext = std::make_unique<InputDeviceContext>(*this);
+}
InputDevice::~InputDevice() {}
bool InputDevice::isEnabled() {
- return getEventHub()->isDeviceEnabled(mId);
+ return mDeviceContext->isDeviceEnabled();
}
void InputDevice::setEnabled(bool enabled, nsecs_t when) {
@@ -64,11 +66,11 @@
}
if (enabled) {
- getEventHub()->enableDevice(mId);
+ mDeviceContext->enableDevice();
reset(when);
} else {
reset(when);
- getEventHub()->disableDevice(mId);
+ mDeviceContext->disableDevice();
}
// Must change generation to flag this device as changed
bumpGeneration();
@@ -119,6 +121,7 @@
void InputDevice::populateMappers() {
uint32_t classes = mClasses;
std::vector<std::unique_ptr<InputMapper>>& mappers = mMappers;
+ std::unique_ptr<InputDeviceContext>& contextPtr = mDeviceContext;
// External devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -132,17 +135,17 @@
// Switch-like devices.
if (classes & INPUT_DEVICE_CLASS_SWITCH) {
- mappers.push_back(std::make_unique<SwitchInputMapper>(this));
+ mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
}
// Scroll wheel-like devices.
if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
- mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(this));
+ mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(*contextPtr));
}
// Vibrator-like devices.
if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
- mappers.push_back(std::make_unique<VibratorInputMapper>(this));
+ mappers.push_back(std::make_unique<VibratorInputMapper>(*contextPtr));
}
// Keyboard-like devices.
@@ -163,29 +166,29 @@
if (keyboardSource != 0) {
mappers.push_back(
- std::make_unique<KeyboardInputMapper>(this, keyboardSource, keyboardType));
+ std::make_unique<KeyboardInputMapper>(*contextPtr, keyboardSource, keyboardType));
}
// Cursor-like devices.
if (classes & INPUT_DEVICE_CLASS_CURSOR) {
- mappers.push_back(std::make_unique<CursorInputMapper>(this));
+ mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr));
}
// Touchscreens and touchpad devices.
if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
- mappers.push_back(std::make_unique<MultiTouchInputMapper>(this));
+ mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
} else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
- mappers.push_back(std::make_unique<SingleTouchInputMapper>(this));
+ mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
}
// Joystick-like devices.
if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
- mappers.push_back(std::make_unique<JoystickInputMapper>(this));
+ mappers.push_back(std::make_unique<JoystickInputMapper>(*contextPtr));
}
// External stylus-like devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
- mappers.push_back(std::make_unique<ExternalStylusInputMapper>(this));
+ mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
}
}
@@ -195,14 +198,14 @@
if (!isIgnored()) {
if (!changes) { // first time only
- mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
+ mDeviceContext->getConfiguration(&mConfiguration);
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
sp<KeyCharacterMap> keyboardLayout =
mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
- if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
+ if (mDeviceContext->setKeyboardLayoutOverlay(keyboardLayout)) {
bumpGeneration();
}
}
@@ -421,4 +424,12 @@
[](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
}
+InputDeviceContext::InputDeviceContext(InputDevice& device)
+ : mDevice(device),
+ mContext(device.getContext()),
+ mEventHub(device.getContext()->getEventHub()),
+ mId(device.getId()) {}
+
+InputDeviceContext::~InputDeviceContext() {}
+
} // namespace android
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 010729a..3e23fa6 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -348,13 +348,11 @@
mDisableVirtualKeysTimeout = time;
}
-bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, InputDevice* device, int32_t keyCode,
- int32_t scanCode) {
+bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode) {
if (now < mDisableVirtualKeysTimeout) {
- ALOGI("Dropping virtual key from device %s because virtual keys are "
+ ALOGI("Dropping virtual key from device because virtual keys are "
"temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
- device->getName().c_str(), (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode,
- scanCode);
+ (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode, scanCode);
return true;
} else {
return false;
@@ -662,10 +660,10 @@
mReader->disableVirtualKeysUntilLocked(time);
}
-bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, InputDevice* device,
- int32_t keyCode, int32_t scanCode) {
+bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, int32_t keyCode,
+ int32_t scanCode) {
// lock is already held by the input loop
- return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
+ return mReader->shouldDropVirtualKeyLocked(now, keyCode, scanCode);
}
void InputReader::ContextImpl::fadePointer() {
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index d06cc20..0814d1f 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -31,6 +31,7 @@
namespace android {
+class InputDeviceContext;
class InputMapper;
/* Represents the state of a single input device. */
@@ -96,30 +97,12 @@
inline const PropertyMap& getConfiguration() { return mConfiguration; }
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
- bool hasKey(int32_t code) { return getEventHub()->hasScanCode(mId, code); }
-
- bool hasAbsoluteAxis(int32_t code) {
- RawAbsoluteAxisInfo info;
- getEventHub()->getAbsoluteAxisInfo(mId, code, &info);
- return info.valid;
- }
-
- bool isKeyPressed(int32_t code) {
- return getEventHub()->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
- }
-
- int32_t getAbsoluteAxisValue(int32_t code) {
- int32_t value;
- getEventHub()->getAbsoluteAxisValue(mId, code, &value);
- return value;
- }
-
std::optional<int32_t> getAssociatedDisplayId();
// construct and add a mapper to the input device
template <class T, typename... Args>
T& addMapper(Args... args) {
- T* mapper = new T(this, args...);
+ T* mapper = new T(*mDeviceContext, args...);
mMappers.emplace_back(mapper);
return *mapper;
}
@@ -133,6 +116,7 @@
std::string mAlias;
uint32_t mClasses;
+ std::unique_ptr<InputDeviceContext> mDeviceContext;
std::vector<std::unique_ptr<InputMapper>> mMappers;
uint32_t mSources;
@@ -168,6 +152,115 @@
}
};
+/* Provides access to EventHub methods, but limits access to the current InputDevice.
+ * Essentially an implementation of EventHubInterface, but for a specific device id.
+ * Helps hide implementation details of InputDevice and EventHub. Used by mappers to
+ * check the status of the associated hardware device
+ */
+class InputDeviceContext {
+public:
+ InputDeviceContext(InputDevice& device);
+ ~InputDeviceContext();
+
+ inline InputReaderContext* getContext() { return mContext; }
+ inline int32_t getId() { return mId; }
+
+ inline uint32_t getDeviceClasses() const { return mEventHub->getDeviceClasses(mId); }
+ inline InputDeviceIdentifier getDeviceIdentifier() const {
+ return mEventHub->getDeviceIdentifier(mId);
+ }
+ inline int32_t getDeviceControllerNumber() const {
+ return mEventHub->getDeviceControllerNumber(mId);
+ }
+ inline void getConfiguration(PropertyMap* outConfiguration) const {
+ return mEventHub->getConfiguration(mId, outConfiguration);
+ }
+ inline status_t getAbsoluteAxisInfo(int32_t code, RawAbsoluteAxisInfo* axisInfo) const {
+ return mEventHub->getAbsoluteAxisInfo(mId, code, axisInfo);
+ }
+ inline bool hasRelativeAxis(int32_t code) const {
+ return mEventHub->hasRelativeAxis(mId, code);
+ }
+ inline bool hasInputProperty(int property) const {
+ return mEventHub->hasInputProperty(mId, property);
+ }
+ inline status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t metaState,
+ int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const {
+ return mEventHub->mapKey(mId, scanCode, usageCode, metaState, outKeycode, outMetaState,
+ outFlags);
+ }
+ inline status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
+ return mEventHub->mapAxis(mId, scanCode, outAxisInfo);
+ }
+ inline std::vector<TouchVideoFrame> getVideoFrames() { return mEventHub->getVideoFrames(mId); }
+ inline int32_t getScanCodeState(int32_t scanCode) const {
+ return mEventHub->getScanCodeState(mId, scanCode);
+ }
+ inline int32_t getKeyCodeState(int32_t keyCode) const {
+ return mEventHub->getKeyCodeState(mId, keyCode);
+ }
+ inline int32_t getSwitchState(int32_t sw) const { return mEventHub->getSwitchState(mId, sw); }
+ inline status_t getAbsoluteAxisValue(int32_t code, int32_t* outValue) const {
+ return mEventHub->getAbsoluteAxisValue(mId, code, outValue);
+ }
+ inline bool markSupportedKeyCodes(size_t numCodes, const int32_t* keyCodes,
+ uint8_t* outFlags) const {
+ return mEventHub->markSupportedKeyCodes(mId, numCodes, keyCodes, outFlags);
+ }
+ inline bool hasScanCode(int32_t scanCode) const {
+ return mEventHub->hasScanCode(mId, scanCode);
+ }
+ inline bool hasLed(int32_t led) const { return mEventHub->hasLed(mId, led); }
+ inline void setLedState(int32_t led, bool on) { return mEventHub->setLedState(mId, led, on); }
+ inline void getVirtualKeyDefinitions(std::vector<VirtualKeyDefinition>& outVirtualKeys) const {
+ return mEventHub->getVirtualKeyDefinitions(mId, outVirtualKeys);
+ }
+ inline sp<KeyCharacterMap> getKeyCharacterMap() const {
+ return mEventHub->getKeyCharacterMap(mId);
+ }
+ inline bool setKeyboardLayoutOverlay(const sp<KeyCharacterMap>& map) {
+ return mEventHub->setKeyboardLayoutOverlay(mId, map);
+ }
+ inline void vibrate(nsecs_t duration) { return mEventHub->vibrate(mId, duration); }
+ inline void cancelVibrate() { return mEventHub->cancelVibrate(mId); }
+
+ inline bool hasAbsoluteAxis(int32_t code) const {
+ RawAbsoluteAxisInfo info;
+ mEventHub->getAbsoluteAxisInfo(mId, code, &info);
+ return info.valid;
+ }
+ inline bool isKeyPressed(int32_t code) const {
+ return mEventHub->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
+ }
+ inline int32_t getAbsoluteAxisValue(int32_t code) const {
+ int32_t value;
+ mEventHub->getAbsoluteAxisValue(mId, code, &value);
+ return value;
+ }
+ inline bool isDeviceEnabled() { return mEventHub->isDeviceEnabled(mId); }
+ inline status_t enableDevice() { return mEventHub->enableDevice(mId); }
+ inline status_t disableDevice() { return mEventHub->disableDevice(mId); }
+
+ inline const std::string getName() { return mDevice.getName(); }
+ inline const std::string getDescriptor() { return mDevice.getDescriptor(); }
+ inline bool isExternal() { return mDevice.isExternal(); }
+ inline std::optional<uint8_t> getAssociatedDisplayPort() const {
+ return mDevice.getAssociatedDisplayPort();
+ }
+ inline std::optional<DisplayViewport> getAssociatedViewport() const {
+ return mDevice.getAssociatedViewport();
+ }
+ inline void cancelTouch(nsecs_t when) { mDevice.cancelTouch(when); }
+ inline void bumpGeneration() { mDevice.bumpGeneration(); }
+ inline const PropertyMap& getConfiguration() { return mDevice.getConfiguration(); }
+
+private:
+ InputDevice& mDevice;
+ InputReaderContext* mContext;
+ EventHubInterface* mEventHub;
+ int32_t mId;
+};
+
} // namespace android
#endif //_UI_INPUTREADER_INPUT_DEVICE_H
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 02957cd..cf1af04 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -101,8 +101,7 @@
virtual void updateGlobalMetaState() override;
virtual int32_t getGlobalMetaState() override;
virtual void disableVirtualKeysUntil(nsecs_t time) override;
- virtual bool shouldDropVirtualKey(nsecs_t now, InputDevice* device, int32_t keyCode,
- int32_t scanCode) override;
+ virtual bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override;
virtual void fadePointer() override;
virtual void requestTimeoutAtTime(nsecs_t when) override;
virtual int32_t bumpGeneration() override;
@@ -168,8 +167,7 @@
nsecs_t mDisableVirtualKeysTimeout;
void disableVirtualKeysUntilLocked(nsecs_t time);
- bool shouldDropVirtualKeyLocked(nsecs_t now, InputDevice* device, int32_t keyCode,
- int32_t scanCode);
+ bool shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode);
nsecs_t mNextTimeout;
void requestTimeoutAtTimeLocked(nsecs_t when);
diff --git a/services/inputflinger/reader/include/InputReaderContext.h b/services/inputflinger/reader/include/InputReaderContext.h
index 3472346..e14fbbe 100644
--- a/services/inputflinger/reader/include/InputReaderContext.h
+++ b/services/inputflinger/reader/include/InputReaderContext.h
@@ -42,8 +42,7 @@
virtual int32_t getGlobalMetaState() = 0;
virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
- virtual bool shouldDropVirtualKey(nsecs_t now, InputDevice* device, int32_t keyCode,
- int32_t scanCode) = 0;
+ virtual bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) = 0;
virtual void fadePointer() = 0;
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 69a75ba..78f3382 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -30,7 +30,7 @@
clearRelativeAxes();
}
-void CursorMotionAccumulator::reset(InputDevice* device) {
+void CursorMotionAccumulator::reset(InputDeviceContext& deviceContext) {
clearRelativeAxes();
}
@@ -58,7 +58,8 @@
// --- CursorInputMapper ---
-CursorInputMapper::CursorInputMapper(InputDevice* device) : InputMapper(device) {}
+CursorInputMapper::CursorInputMapper(InputDeviceContext& deviceContext)
+ : InputMapper(deviceContext) {}
CursorInputMapper::~CursorInputMapper() {}
@@ -113,7 +114,7 @@
InputMapper::configure(when, config, changes);
if (!changes) { // first time only
- mCursorScrollAccumulator.configure(getDevice());
+ mCursorScrollAccumulator.configure(getDeviceContext());
// Configure basic parameters.
configureParameters();
@@ -167,7 +168,8 @@
}
bumpGeneration();
if (changes) {
- getDevice()->notifyReset(when);
+ NotifyDeviceResetArgs args(getContext()->getNextSequenceNum(), when, getDeviceId());
+ getListener()->notifyDeviceReset(&args);
}
}
@@ -218,7 +220,8 @@
void CursorInputMapper::configureParameters() {
mParameters.mode = Parameters::MODE_POINTER;
String8 cursorModeString;
- if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
+ if (getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.mode"),
+ cursorModeString)) {
if (cursorModeString == "navigation") {
mParameters.mode = Parameters::MODE_NAVIGATION;
} else if (cursorModeString != "pointer" && cursorModeString != "default") {
@@ -227,8 +230,8 @@
}
mParameters.orientationAware = false;
- getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
- mParameters.orientationAware);
+ getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
+ mParameters.orientationAware);
mParameters.hasAssociatedDisplay = false;
if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
@@ -266,9 +269,9 @@
mWheelXVelocityControl.reset();
mWheelYVelocityControl.reset();
- mCursorButtonAccumulator.reset(getDevice());
- mCursorMotionAccumulator.reset(getDevice());
- mCursorScrollAccumulator.reset(getDevice());
+ mCursorButtonAccumulator.reset(getDeviceContext());
+ mCursorMotionAccumulator.reset(getDeviceContext());
+ mCursorScrollAccumulator.reset(getDeviceContext());
InputMapper::reset(when);
}
@@ -369,7 +372,7 @@
// the device in your pocket.
// TODO: Use the input device configuration to control this behavior more finely.
uint32_t policyFlags = 0;
- if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
+ if ((buttonsPressed || moved || scrolled) && getDeviceContext().isExternal()) {
policyFlags |= POLICY_FLAG_WAKE;
}
@@ -379,7 +382,7 @@
// Send motion event.
if (downChanged || moved || scrolled || buttonsChanged) {
- int32_t metaState = mContext->getGlobalMetaState();
+ int32_t metaState = getContext()->getGlobalMetaState();
int32_t buttonState = lastButtonState;
int32_t motionEventAction;
if (downChanged) {
@@ -395,8 +398,8 @@
while (!released.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
buttonState &= ~actionButton;
- NotifyMotionArgs releaseArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs releaseArgs(getContext()->getNextSequenceNum(), when,
+ getDeviceId(), mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
metaState, buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
@@ -407,7 +410,7 @@
}
}
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, motionEventAction, 0, 0, metaState,
currentButtonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, &pointerCoords,
@@ -420,7 +423,7 @@
while (!pressed.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
buttonState |= actionButton;
- NotifyMotionArgs pressArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
+ NotifyMotionArgs pressArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
metaState, buttonState, MotionClassification::NONE,
@@ -436,9 +439,10 @@
// Send hover move after UP to tell the application that the mouse is hovering now.
if (motionEventAction == AMOTION_EVENT_ACTION_UP && (mSource == AINPUT_SOURCE_MOUSE)) {
- NotifyMotionArgs hoverArgs(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
- displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
- 0, metaState, currentButtonState, MotionClassification::NONE,
+ NotifyMotionArgs hoverArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
+ mSource, displayId, policyFlags,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
+ currentButtonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
&pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
yCursorPosition, downTime, /* videoFrames */ {});
@@ -450,7 +454,7 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
+ NotifyMotionArgs scrollArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
currentButtonState, MotionClassification::NONE,
@@ -471,7 +475,7 @@
int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
- return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+ return getDeviceContext().getScanCodeState(scanCode);
} else {
return AKEY_STATE_UNKNOWN;
}
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index d56f9be..94ab306 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -36,7 +36,7 @@
class CursorMotionAccumulator {
public:
CursorMotionAccumulator();
- void reset(InputDevice* device);
+ void reset(InputDeviceContext& deviceContext);
void process(const RawEvent* rawEvent);
void finishSync();
@@ -53,7 +53,7 @@
class CursorInputMapper : public InputMapper {
public:
- explicit CursorInputMapper(InputDevice* device);
+ explicit CursorInputMapper(InputDeviceContext& deviceContext);
virtual ~CursorInputMapper();
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
index 9aa0770..37e4047 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
@@ -23,7 +23,8 @@
namespace android {
-ExternalStylusInputMapper::ExternalStylusInputMapper(InputDevice* device) : InputMapper(device) {}
+ExternalStylusInputMapper::ExternalStylusInputMapper(InputDeviceContext& deviceContext)
+ : InputMapper(deviceContext) {}
uint32_t ExternalStylusInputMapper::getSources() {
return AINPUT_SOURCE_STYLUS;
@@ -46,13 +47,12 @@
void ExternalStylusInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
uint32_t changes) {
getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPressureAxis);
- mTouchButtonAccumulator.configure(getDevice());
+ mTouchButtonAccumulator.configure(getDeviceContext());
}
void ExternalStylusInputMapper::reset(nsecs_t when) {
- InputDevice* device = getDevice();
- mSingleTouchMotionAccumulator.reset(device);
- mTouchButtonAccumulator.reset(device);
+ mSingleTouchMotionAccumulator.reset(getDeviceContext());
+ mTouchButtonAccumulator.reset(getDeviceContext());
InputMapper::reset(when);
}
@@ -86,7 +86,7 @@
mStylusState.buttons = mTouchButtonAccumulator.getButtonState();
- mContext->dispatchExternalStylusState(mStylusState);
+ getContext()->dispatchExternalStylusState(mStylusState);
}
} // namespace android
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
index 34f339a..1d42b30 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
@@ -27,7 +27,7 @@
class ExternalStylusInputMapper : public InputMapper {
public:
- explicit ExternalStylusInputMapper(InputDevice* device);
+ explicit ExternalStylusInputMapper(InputDeviceContext& deviceContext);
virtual ~ExternalStylusInputMapper() = default;
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/InputMapper.cpp b/services/inputflinger/reader/mapper/InputMapper.cpp
index d941528..92af612 100644
--- a/services/inputflinger/reader/mapper/InputMapper.cpp
+++ b/services/inputflinger/reader/mapper/InputMapper.cpp
@@ -22,7 +22,7 @@
namespace android {
-InputMapper::InputMapper(InputDevice* device) : mDevice(device), mContext(device->getContext()) {}
+InputMapper::InputMapper(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
InputMapper::~InputMapper() {}
@@ -74,11 +74,11 @@
void InputMapper::fadePointer() {}
status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
- return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
+ return getDeviceContext().getAbsoluteAxisInfo(axis, axisInfo);
}
void InputMapper::bumpGeneration() {
- mDevice->bumpGeneration();
+ getDeviceContext().bumpGeneration();
}
void InputMapper::dumpRawAbsoluteAxisInfo(std::string& dump, const RawAbsoluteAxisInfo& axis,
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index a559ef8..09888bf 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -39,16 +39,15 @@
*/
class InputMapper {
public:
- explicit InputMapper(InputDevice* device);
+ explicit InputMapper(InputDeviceContext& deviceContext);
virtual ~InputMapper();
- inline InputDevice* getDevice() { return mDevice; }
- inline int32_t getDeviceId() { return mDevice->getId(); }
- inline const std::string getDeviceName() { return mDevice->getName(); }
- inline InputReaderContext* getContext() { return mContext; }
- inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
- inline InputListenerInterface* getListener() { return mContext->getListener(); }
- inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
+ inline int32_t getDeviceId() { return mDeviceContext.getId(); }
+ inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
+ inline const std::string getDeviceName() { return mDeviceContext.getName(); }
+ inline InputReaderContext* getContext() { return mDeviceContext.getContext(); }
+ inline InputReaderPolicyInterface* getPolicy() { return getContext()->getPolicy(); }
+ inline InputListenerInterface* getListener() { return getContext()->getListener(); }
virtual uint32_t getSources() = 0;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
@@ -76,8 +75,7 @@
virtual std::optional<int32_t> getAssociatedDisplayId() { return std::nullopt; }
protected:
- InputDevice* mDevice;
- InputReaderContext* mContext;
+ InputDeviceContext& mDeviceContext;
status_t getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo);
void bumpGeneration();
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
index 50adf73..57c85b6 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
@@ -20,7 +20,8 @@
namespace android {
-JoystickInputMapper::JoystickInputMapper(InputDevice* device) : InputMapper(device) {}
+JoystickInputMapper::JoystickInputMapper(InputDeviceContext& deviceContext)
+ : InputMapper(deviceContext) {}
JoystickInputMapper::~JoystickInputMapper() {}
@@ -112,7 +113,8 @@
if (!changes) { // first time only
// Collect all axes.
for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
- if (!(getAbsAxisUsage(abs, getDevice()->getClasses()) & INPUT_DEVICE_CLASS_JOYSTICK)) {
+ if (!(getAbsAxisUsage(abs, getDeviceContext().getDeviceClasses()) &
+ INPUT_DEVICE_CLASS_JOYSTICK)) {
continue; // axis must be claimed by a different device
}
@@ -121,7 +123,7 @@
if (rawAxisInfo.valid) {
// Map axis.
AxisInfo axisInfo;
- bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
+ bool explicitlyMapped = !getDeviceContext().mapAxis(abs, &axisInfo);
if (!explicitlyMapped) {
// Axis is not explicitly mapped, will choose a generic axis later.
axisInfo.mode = AxisInfo::MODE_NORMAL;
@@ -304,7 +306,7 @@
return;
}
- int32_t metaState = mContext->getGlobalMetaState();
+ int32_t metaState = getContext()->getGlobalMetaState();
int32_t buttonState = 0;
PointerProperties pointerProperties;
@@ -331,7 +333,7 @@
// TODO: Use the input device configuration to control this behavior more finely.
uint32_t policyFlags = 0;
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(),
AINPUT_SOURCE_JOYSTICK, ADISPLAY_ID_NONE, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.h b/services/inputflinger/reader/mapper/JoystickInputMapper.h
index b46d27d..823a096 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.h
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.h
@@ -23,7 +23,7 @@
class JoystickInputMapper : public InputMapper {
public:
- explicit JoystickInputMapper(InputDevice* device);
+ explicit JoystickInputMapper(InputDeviceContext& deviceContext);
virtual ~JoystickInputMapper();
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 348a7ad..9ab707f 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -87,8 +87,9 @@
// --- KeyboardInputMapper ---
-KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType)
- : InputMapper(device), mSource(source), mKeyboardType(keyboardType) {}
+KeyboardInputMapper::KeyboardInputMapper(InputDeviceContext& deviceContext, uint32_t source,
+ int32_t keyboardType)
+ : InputMapper(deviceContext), mSource(source), mKeyboardType(keyboardType) {}
KeyboardInputMapper::~KeyboardInputMapper() {}
@@ -114,7 +115,7 @@
InputMapper::populateDeviceInfo(info);
info->setKeyboardType(mKeyboardType);
- info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
+ info->setKeyCharacterMap(getDeviceContext().getKeyCharacterMap());
}
void KeyboardInputMapper::dump(std::string& dump) {
@@ -129,10 +130,10 @@
std::optional<DisplayViewport> KeyboardInputMapper::findViewport(
nsecs_t when, const InputReaderConfiguration* config) {
- const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort();
+ const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
if (displayPort) {
// Find the viewport that contains the same port
- return mDevice->getAssociatedViewport();
+ return getDeviceContext().getAssociatedViewport();
}
// No associated display defined, try to find default display if orientationAware.
@@ -171,7 +172,7 @@
void KeyboardInputMapper::configureParameters() {
mParameters.orientationAware = false;
- const PropertyMap& config = getDevice()->getConfiguration();
+ const PropertyMap& config = getDeviceContext().getConfiguration();
config.tryGetProperty(String8("keyboard.orientationAware"), mParameters.orientationAware);
if (mParameters.orientationAware) {
@@ -271,8 +272,8 @@
int32_t keyMetaState;
uint32_t policyFlags;
- if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState, &keyCode,
- &keyMetaState, &policyFlags)) {
+ if (getDeviceContext().mapKey(scanCode, usageCode, mMetaState, &keyCode, &keyMetaState,
+ &policyFlags)) {
keyCode = AKEYCODE_UNKNOWN;
keyMetaState = mMetaState;
policyFlags = 0;
@@ -292,11 +293,11 @@
} else {
// key down
if ((policyFlags & POLICY_FLAG_VIRTUAL) &&
- mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {
+ getContext()->shouldDropVirtualKey(when, keyCode, scanCode)) {
return;
}
if (policyFlags & POLICY_FLAG_GESTURE) {
- mDevice->cancelTouch(when);
+ getDeviceContext().cancelTouch(when);
}
KeyDown keyDown;
@@ -338,7 +339,7 @@
// prevented (e.g. TV remotes), the key layout file should specify the policy flags for each
// wake key individually.
// TODO: Use the input device configuration to control this behavior more finely.
- if (down && getDevice()->isExternal() && !mParameters.doNotWakeByDefault &&
+ if (down && getDeviceContext().isExternal() && !mParameters.doNotWakeByDefault &&
!isMediaKey(keyCode)) {
policyFlags |= POLICY_FLAG_WAKE;
}
@@ -347,8 +348,9 @@
policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
}
- NotifyKeyArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource, getDisplayId(),
- policyFlags, down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
+ NotifyKeyArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
+ getDisplayId(), policyFlags,
+ down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
getListener()->notifyKey(&args);
}
@@ -364,16 +366,16 @@
}
int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
+ return getDeviceContext().getKeyCodeState(keyCode);
}
int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+ return getDeviceContext().getScanCodeState(scanCode);
}
bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
- return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
+ return getDeviceContext().markSupportedKeyCodes(numCodes, keyCodes, outFlags);
}
int32_t KeyboardInputMapper::getMetaState() {
@@ -407,7 +409,7 @@
}
void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
- ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
+ ledState.avail = getDeviceContext().hasLed(led);
ledState.on = false;
}
@@ -422,7 +424,7 @@
if (ledState.avail) {
bool desiredState = (mMetaState & modifier) != 0;
if (reset || ledState.on != desiredState) {
- getEventHub()->setLedState(getDeviceId(), led, desiredState);
+ getDeviceContext().setLedState(led, desiredState);
ledState.on = desiredState;
}
}
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index badbcb2..0bdeded 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -23,7 +23,7 @@
class KeyboardInputMapper : public InputMapper {
public:
- KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
+ KeyboardInputMapper(InputDeviceContext& deviceContext, uint32_t source, int32_t keyboardType);
virtual ~KeyboardInputMapper();
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index f42ddcf..d195a07 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -38,17 +38,17 @@
delete[] mSlots;
}
-void MultiTouchMotionAccumulator::configure(InputDevice* device, size_t slotCount,
+void MultiTouchMotionAccumulator::configure(InputDeviceContext& deviceContext, size_t slotCount,
bool usingSlotsProtocol) {
mSlotCount = slotCount;
mUsingSlotsProtocol = usingSlotsProtocol;
- mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
+ mHaveStylus = deviceContext.hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
delete[] mSlots;
mSlots = new Slot[slotCount];
}
-void MultiTouchMotionAccumulator::reset(InputDevice* device) {
+void MultiTouchMotionAccumulator::reset(InputDeviceContext& deviceContext) {
// Unfortunately there is no way to read the initial contents of the slots.
// So when we reset the accumulator, we must assume they are all zeroes.
if (mUsingSlotsProtocol) {
@@ -62,8 +62,7 @@
// This can cause the touch point to "jump", but at least there will be
// no stuck touches.
int32_t initialSlot;
- status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(), ABS_MT_SLOT,
- &initialSlot);
+ status_t status = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT, &initialSlot);
if (status) {
ALOGD("Could not retrieve current multitouch slot index. status=%d", status);
initialSlot = -1;
@@ -218,12 +217,13 @@
// --- MultiTouchInputMapper ---
-MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : TouchInputMapper(device) {}
+MultiTouchInputMapper::MultiTouchInputMapper(InputDeviceContext& deviceContext)
+ : TouchInputMapper(deviceContext) {}
MultiTouchInputMapper::~MultiTouchInputMapper() {}
void MultiTouchInputMapper::reset(nsecs_t when) {
- mMultiTouchMotionAccumulator.reset(getDevice());
+ mMultiTouchMotionAccumulator.reset(getDeviceContext());
mPointerIdBits.clear();
@@ -353,9 +353,10 @@
getDeviceName().c_str(), slotCount, MAX_SLOTS);
slotCount = MAX_SLOTS;
}
- mMultiTouchMotionAccumulator.configure(getDevice(), slotCount, true /*usingSlotsProtocol*/);
+ mMultiTouchMotionAccumulator.configure(getDeviceContext(), slotCount,
+ true /*usingSlotsProtocol*/);
} else {
- mMultiTouchMotionAccumulator.configure(getDevice(), MAX_POINTERS,
+ mMultiTouchMotionAccumulator.configure(getDeviceContext(), MAX_POINTERS,
false /*usingSlotsProtocol*/);
}
}
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.h b/services/inputflinger/reader/mapper/MultiTouchInputMapper.h
index a45c3cb..89ef41d 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.h
@@ -70,8 +70,8 @@
MultiTouchMotionAccumulator();
~MultiTouchMotionAccumulator();
- void configure(InputDevice* device, size_t slotCount, bool usingSlotsProtocol);
- void reset(InputDevice* device);
+ void configure(InputDeviceContext& deviceContext, size_t slotCount, bool usingSlotsProtocol);
+ void reset(InputDeviceContext& deviceContext);
void process(const RawEvent* rawEvent);
void finishSync();
bool hasStylus() const;
@@ -91,7 +91,7 @@
class MultiTouchInputMapper : public TouchInputMapper {
public:
- explicit MultiTouchInputMapper(InputDevice* device);
+ explicit MultiTouchInputMapper(InputDeviceContext& deviceContext);
virtual ~MultiTouchInputMapper();
virtual void reset(nsecs_t when) override;
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
index e113cca..a1cce56 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
@@ -22,8 +22,8 @@
namespace android {
-RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device)
- : InputMapper(device), mOrientation(DISPLAY_ORIENTATION_0) {
+RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDeviceContext& deviceContext)
+ : InputMapper(deviceContext), mOrientation(DISPLAY_ORIENTATION_0) {
mSource = AINPUT_SOURCE_ROTARY_ENCODER;
}
@@ -38,11 +38,11 @@
if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) {
float res = 0.0f;
- if (!mDevice->getConfiguration().tryGetProperty(String8("device.res"), res)) {
+ if (!getDeviceContext().getConfiguration().tryGetProperty(String8("device.res"), res)) {
ALOGW("Rotary Encoder device configuration file didn't specify resolution!\n");
}
- if (!mDevice->getConfiguration().tryGetProperty(String8("device.scalingFactor"),
- mScalingFactor)) {
+ if (!getDeviceContext().getConfiguration().tryGetProperty(String8("device.scalingFactor"),
+ mScalingFactor)) {
ALOGW("Rotary Encoder device configuration file didn't specify scaling factor,"
"default to 1.0!\n");
mScalingFactor = 1.0f;
@@ -62,7 +62,7 @@
uint32_t changes) {
InputMapper::configure(when, config, changes);
if (!changes) {
- mRotaryEncoderScrollAccumulator.configure(getDevice());
+ mRotaryEncoderScrollAccumulator.configure(getDeviceContext());
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
std::optional<DisplayViewport> internalViewport =
@@ -76,7 +76,7 @@
}
void RotaryEncoderInputMapper::reset(nsecs_t when) {
- mRotaryEncoderScrollAccumulator.reset(getDevice());
+ mRotaryEncoderScrollAccumulator.reset(getDeviceContext());
InputMapper::reset(when);
}
@@ -106,7 +106,7 @@
// Moving the rotary encoder should wake the device (if specified).
uint32_t policyFlags = 0;
- if (scrolled && getDevice()->isExternal()) {
+ if (scrolled && getDeviceContext().isExternal()) {
policyFlags |= POLICY_FLAG_WAKE;
}
@@ -116,12 +116,12 @@
// Send motion event.
if (scrolled) {
- int32_t metaState = mContext->getGlobalMetaState();
+ int32_t metaState = getContext()->getGlobalMetaState();
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll * mScalingFactor);
- NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
- displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
- metaState, /* buttonState */ 0, MotionClassification::NONE,
+ NotifyMotionArgs scrollArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
+ mSource, displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0,
+ 0, metaState, /* buttonState */ 0, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
&pointerCoords, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, /* videoFrames */ {});
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
index 38c7258..7a77b12 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
@@ -24,7 +24,7 @@
class RotaryEncoderInputMapper : public InputMapper {
public:
- explicit RotaryEncoderInputMapper(InputDevice* device);
+ explicit RotaryEncoderInputMapper(InputDeviceContext& deviceContext);
virtual ~RotaryEncoderInputMapper();
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
index 440d282..4fff9be 100644
--- a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
@@ -18,12 +18,13 @@
namespace android {
-SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) : TouchInputMapper(device) {}
+SingleTouchInputMapper::SingleTouchInputMapper(InputDeviceContext& deviceContext)
+ : TouchInputMapper(deviceContext) {}
SingleTouchInputMapper::~SingleTouchInputMapper() {}
void SingleTouchInputMapper::reset(nsecs_t when) {
- mSingleTouchMotionAccumulator.reset(getDevice());
+ mSingleTouchMotionAccumulator.reset(getDeviceContext());
TouchInputMapper::reset(when);
}
diff --git a/services/inputflinger/reader/mapper/SingleTouchInputMapper.h b/services/inputflinger/reader/mapper/SingleTouchInputMapper.h
index 8438eee..f5befb3 100644
--- a/services/inputflinger/reader/mapper/SingleTouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/SingleTouchInputMapper.h
@@ -24,7 +24,7 @@
class SingleTouchInputMapper : public TouchInputMapper {
public:
- explicit SingleTouchInputMapper(InputDevice* device);
+ explicit SingleTouchInputMapper(InputDeviceContext& deviceContext);
virtual ~SingleTouchInputMapper();
virtual void reset(nsecs_t when) override;
diff --git a/services/inputflinger/reader/mapper/SwitchInputMapper.cpp b/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
index 16095b9..52b2449 100644
--- a/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
@@ -20,8 +20,8 @@
namespace android {
-SwitchInputMapper::SwitchInputMapper(InputDevice* device)
- : InputMapper(device), mSwitchValues(0), mUpdatedSwitchMask(0) {}
+SwitchInputMapper::SwitchInputMapper(InputDeviceContext& deviceContext)
+ : InputMapper(deviceContext), mSwitchValues(0), mUpdatedSwitchMask(0) {}
SwitchInputMapper::~SwitchInputMapper() {}
@@ -56,7 +56,7 @@
void SwitchInputMapper::sync(nsecs_t when) {
if (mUpdatedSwitchMask) {
uint32_t updatedSwitchValues = mSwitchValues & mUpdatedSwitchMask;
- NotifySwitchArgs args(mContext->getNextSequenceNum(), when, 0 /*policyFlags*/,
+ NotifySwitchArgs args(getContext()->getNextSequenceNum(), when, 0 /*policyFlags*/,
updatedSwitchValues, mUpdatedSwitchMask);
getListener()->notifySwitch(&args);
@@ -65,7 +65,7 @@
}
int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
- return getEventHub()->getSwitchState(getDeviceId(), switchCode);
+ return getDeviceContext().getSwitchState(switchCode);
}
void SwitchInputMapper::dump(std::string& dump) {
diff --git a/services/inputflinger/reader/mapper/SwitchInputMapper.h b/services/inputflinger/reader/mapper/SwitchInputMapper.h
index e65d4e2..4d74163 100644
--- a/services/inputflinger/reader/mapper/SwitchInputMapper.h
+++ b/services/inputflinger/reader/mapper/SwitchInputMapper.h
@@ -23,7 +23,7 @@
class SwitchInputMapper : public InputMapper {
public:
- explicit SwitchInputMapper(InputDevice* device);
+ explicit SwitchInputMapper(InputDeviceContext& deviceContext);
virtual ~SwitchInputMapper();
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 3b20173..e832804 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -156,8 +156,8 @@
// --- TouchInputMapper ---
-TouchInputMapper::TouchInputMapper(InputDevice* device)
- : InputMapper(device),
+TouchInputMapper::TouchInputMapper(InputDeviceContext& deviceContext)
+ : InputMapper(deviceContext),
mSource(0),
mDeviceMode(DEVICE_MODE_DISABLED),
mSurfaceWidth(-1),
@@ -348,8 +348,8 @@
configureParameters();
// Configure common accumulators.
- mCursorScrollAccumulator.configure(getDevice());
- mTouchButtonAccumulator.configure(getDevice());
+ mCursorScrollAccumulator.configure(getDeviceContext());
+ mTouchButtonAccumulator.configure(getDeviceContext());
// Configure absolute axis information.
configureRawPointerAxes();
@@ -386,13 +386,14 @@
if (changes && resetNeeded) {
// Send reset, unless this is the first time the device has been configured,
// in which case the reader will call reset itself after all mappers are ready.
- getDevice()->notifyReset(when);
+ NotifyDeviceResetArgs args(getContext()->getNextSequenceNum(), when, getDeviceId());
+ getListener()->notifyDeviceReset(&args);
}
}
void TouchInputMapper::resolveExternalStylusPresence() {
std::vector<InputDeviceInfo> devices;
- mContext->getExternalStylusDevices(devices);
+ getContext()->getExternalStylusDevices(devices);
mExternalStylusConnected = !devices.empty();
if (!mExternalStylusConnected) {
@@ -404,13 +405,13 @@
// Use the pointer presentation mode for devices that do not support distinct
// multitouch. The spot-based presentation relies on being able to accurately
// locate two or more fingers on the touch pad.
- mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
+ mParameters.gestureMode = getDeviceContext().hasInputProperty(INPUT_PROP_SEMI_MT)
? Parameters::GESTURE_MODE_SINGLE_TOUCH
: Parameters::GESTURE_MODE_MULTI_TOUCH;
String8 gestureModeString;
- if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
- gestureModeString)) {
+ if (getDeviceContext().getConfiguration().tryGetProperty(String8("touch.gestureMode"),
+ gestureModeString)) {
if (gestureModeString == "single-touch") {
mParameters.gestureMode = Parameters::GESTURE_MODE_SINGLE_TOUCH;
} else if (gestureModeString == "multi-touch") {
@@ -420,14 +421,14 @@
}
}
- if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
+ if (getDeviceContext().hasInputProperty(INPUT_PROP_DIRECT)) {
// The device is a touch screen.
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
+ } else if (getDeviceContext().hasInputProperty(INPUT_PROP_POINTER)) {
// The device is a pointing device like a track pad.
mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
- } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X) ||
- getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
+ } else if (getDeviceContext().hasRelativeAxis(REL_X) ||
+ getDeviceContext().hasRelativeAxis(REL_Y)) {
// The device is a cursor device with a touch pad attached.
// By default don't use the touch pad to move the pointer.
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
@@ -436,12 +437,11 @@
mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
}
- mParameters.hasButtonUnderPad =
- getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
+ mParameters.hasButtonUnderPad = getDeviceContext().hasInputProperty(INPUT_PROP_BUTTONPAD);
String8 deviceTypeString;
- if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
- deviceTypeString)) {
+ if (getDeviceContext().getConfiguration().tryGetProperty(String8("touch.deviceType"),
+ deviceTypeString)) {
if (deviceTypeString == "touchScreen") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
} else if (deviceTypeString == "touchPad") {
@@ -456,8 +456,8 @@
}
mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
- mParameters.orientationAware);
+ getDeviceContext().getConfiguration().tryGetProperty(String8("touch.orientationAware"),
+ mParameters.orientationAware);
mParameters.hasAssociatedDisplay = false;
mParameters.associatedDisplayIsExternal = false;
@@ -466,22 +466,22 @@
mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
mParameters.hasAssociatedDisplay = true;
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
- mParameters.associatedDisplayIsExternal = getDevice()->isExternal();
+ mParameters.associatedDisplayIsExternal = getDeviceContext().isExternal();
String8 uniqueDisplayId;
- getDevice()->getConfiguration().tryGetProperty(String8("touch.displayId"),
- uniqueDisplayId);
+ getDeviceContext().getConfiguration().tryGetProperty(String8("touch.displayId"),
+ uniqueDisplayId);
mParameters.uniqueDisplayId = uniqueDisplayId.c_str();
}
}
- if (getDevice()->getAssociatedDisplayPort()) {
+ if (getDeviceContext().getAssociatedDisplayPort()) {
mParameters.hasAssociatedDisplay = true;
}
// Initial downs on external touch devices should wake the device.
// Normally we don't do this for internal touch screens to prevent them from waking
// up in your pocket but you can enable it using the input device configuration.
- mParameters.wake = getDevice()->isExternal();
- getDevice()->getConfiguration().tryGetProperty(String8("touch.wake"), mParameters.wake);
+ mParameters.wake = getDeviceContext().isExternal();
+ getDeviceContext().getConfiguration().tryGetProperty(String8("touch.wake"), mParameters.wake);
}
void TouchInputMapper::dumpParameters(std::string& dump) {
@@ -559,10 +559,10 @@
*/
std::optional<DisplayViewport> TouchInputMapper::findViewport() {
if (mParameters.hasAssociatedDisplay) {
- const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort();
+ const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
if (displayPort) {
// Find the viewport that contains the same port
- return mDevice->getAssociatedViewport();
+ return getDeviceContext().getAssociatedViewport();
}
if (mDeviceMode == DEVICE_MODE_POINTER) {
@@ -1045,7 +1045,7 @@
void TouchInputMapper::configureVirtualKeys() {
std::vector<VirtualKeyDefinition> virtualKeyDefinitions;
- getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
+ getDeviceContext().getVirtualKeyDefinitions(virtualKeyDefinitions);
mVirtualKeys.clear();
@@ -1065,8 +1065,8 @@
int32_t keyCode;
int32_t dummyKeyMetaState;
uint32_t flags;
- if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, 0, &keyCode,
- &dummyKeyMetaState, &flags)) {
+ if (getDeviceContext().mapKey(virtualKey.scanCode, 0, 0, &keyCode, &dummyKeyMetaState,
+ &flags)) {
ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
continue; // drop the key
}
@@ -1109,7 +1109,7 @@
}
void TouchInputMapper::parseCalibration() {
- const PropertyMap& in = getDevice()->getConfiguration();
+ const PropertyMap& in = getDeviceContext().getConfiguration();
Calibration& out = mCalibration;
// Size
@@ -1353,14 +1353,14 @@
}
void TouchInputMapper::updateAffineTransformation() {
- mAffineTransform = getPolicy()->getTouchAffineTransformation(mDevice->getDescriptor(),
+ mAffineTransform = getPolicy()->getTouchAffineTransformation(getDeviceContext().getDescriptor(),
mSurfaceOrientation);
}
void TouchInputMapper::reset(nsecs_t when) {
- mCursorButtonAccumulator.reset(getDevice());
- mCursorScrollAccumulator.reset(getDevice());
- mTouchButtonAccumulator.reset(getDevice());
+ mCursorButtonAccumulator.reset(getDeviceContext());
+ mCursorScrollAccumulator.reset(getDeviceContext());
+ mTouchButtonAccumulator.reset(getDeviceContext());
mPointerVelocityControl.reset();
mWheelXVelocityControl.reset();
@@ -1782,8 +1782,8 @@
mCurrentVirtualKey.keyCode = virtualKey->keyCode;
mCurrentVirtualKey.scanCode = virtualKey->scanCode;
mCurrentVirtualKey.ignored =
- mContext->shouldDropVirtualKey(when, getDevice(), virtualKey->keyCode,
- virtualKey->scanCode);
+ getContext()->shouldDropVirtualKey(when, virtualKey->keyCode,
+ virtualKey->scanCode);
if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
@@ -1816,7 +1816,7 @@
// is displayed.
if (mConfig.virtualKeyQuietTime > 0 &&
!mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
- mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
+ getContext()->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
}
return false;
}
@@ -1826,12 +1826,12 @@
int32_t keyCode = mCurrentVirtualKey.keyCode;
int32_t scanCode = mCurrentVirtualKey.scanCode;
nsecs_t downTime = mCurrentVirtualKey.downTime;
- int32_t metaState = mContext->getGlobalMetaState();
+ int32_t metaState = getContext()->getGlobalMetaState();
policyFlags |= POLICY_FLAG_VIRTUAL;
- NotifyKeyArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), AINPUT_SOURCE_KEYBOARD,
- mViewport.displayId, policyFlags, keyEventAction, keyEventFlags, keyCode,
- scanCode, metaState, downTime);
+ NotifyKeyArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(),
+ AINPUT_SOURCE_KEYBOARD, mViewport.displayId, policyFlags, keyEventAction,
+ keyEventFlags, keyCode, scanCode, metaState, downTime);
getListener()->notifyKey(&args);
}
@@ -2503,7 +2503,7 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
const int32_t displayId = mPointerController->getDisplayId();
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, &pointerCoords,
@@ -3423,7 +3423,7 @@
mPointerSimple.down = false;
// Send up.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_UP, 0, 0, metaState,
mLastRawState.buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.lastProperties,
@@ -3437,7 +3437,7 @@
mPointerSimple.hovering = false;
// Send hover exit.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0,
metaState, mLastRawState.buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.lastProperties,
@@ -3453,7 +3453,7 @@
mPointerSimple.downTime = when;
// Send down.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_DOWN, 0, 0,
metaState, mCurrentRawState.buttonState,
MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
@@ -3464,7 +3464,7 @@
}
// Send move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState,
mCurrentRawState.buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.currentProperties,
@@ -3479,7 +3479,7 @@
mPointerSimple.hovering = true;
// Send hover enter.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0,
metaState, mCurrentRawState.buttonState,
MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
@@ -3490,7 +3490,7 @@
}
// Send hover move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, mCurrentRawState.buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.currentProperties,
@@ -3512,7 +3512,7 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
mCurrentRawState.buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.currentProperties,
@@ -3583,10 +3583,10 @@
}
const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
const int32_t deviceId = getDeviceId();
- std::vector<TouchVideoFrame> frames = mDevice->getEventHub()->getVideoFrames(deviceId);
+ std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
std::for_each(frames.begin(), frames.end(),
[this](TouchVideoFrame& frame) { frame.rotate(this->mSurfaceOrientation); });
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, deviceId, source, displayId,
+ NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, deviceId, source, displayId,
policyFlags, action, actionButton, flags, metaState, buttonState,
MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 4b1c0cb..3a61206 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -132,7 +132,7 @@
class TouchInputMapper : public InputMapper {
public:
- explicit TouchInputMapper(InputDevice* device);
+ explicit TouchInputMapper(InputDeviceContext& deviceContext);
virtual ~TouchInputMapper();
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
index a27fab4..1b584ea 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
@@ -20,8 +20,8 @@
namespace android {
-VibratorInputMapper::VibratorInputMapper(InputDevice* device)
- : InputMapper(device), mVibrating(false) {}
+VibratorInputMapper::VibratorInputMapper(InputDeviceContext& deviceContext)
+ : InputMapper(deviceContext), mVibrating(false) {}
VibratorInputMapper::~VibratorInputMapper() {}
@@ -100,12 +100,12 @@
#if DEBUG_VIBRATOR
ALOGD("nextStep: sending vibrate deviceId=%d, duration=%" PRId64, getDeviceId(), duration);
#endif
- getEventHub()->vibrate(getDeviceId(), duration);
+ getDeviceContext().vibrate(duration);
} else {
#if DEBUG_VIBRATOR
ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
#endif
- getEventHub()->cancelVibrate(getDeviceId());
+ getDeviceContext().cancelVibrate();
}
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
mNextStepTime = now + duration;
@@ -120,7 +120,7 @@
#if DEBUG_VIBRATOR
ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
#endif
- getEventHub()->cancelVibrate(getDeviceId());
+ getDeviceContext().cancelVibrate();
}
void VibratorInputMapper::dump(std::string& dump) {
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.h b/services/inputflinger/reader/mapper/VibratorInputMapper.h
index dc67890..f69fdde 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.h
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.h
@@ -23,7 +23,7 @@
class VibratorInputMapper : public InputMapper {
public:
- explicit VibratorInputMapper(InputDevice* device);
+ explicit VibratorInputMapper(InputDeviceContext& deviceContext);
virtual ~VibratorInputMapper();
virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp
index 0337d51..2d7d73b 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp
@@ -25,15 +25,15 @@
clearButtons();
}
-void CursorButtonAccumulator::reset(InputDevice* device) {
- mBtnLeft = device->isKeyPressed(BTN_LEFT);
- mBtnRight = device->isKeyPressed(BTN_RIGHT);
- mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
- mBtnBack = device->isKeyPressed(BTN_BACK);
- mBtnSide = device->isKeyPressed(BTN_SIDE);
- mBtnForward = device->isKeyPressed(BTN_FORWARD);
- mBtnExtra = device->isKeyPressed(BTN_EXTRA);
- mBtnTask = device->isKeyPressed(BTN_TASK);
+void CursorButtonAccumulator::reset(InputDeviceContext& deviceContext) {
+ mBtnLeft = deviceContext.isKeyPressed(BTN_LEFT);
+ mBtnRight = deviceContext.isKeyPressed(BTN_RIGHT);
+ mBtnMiddle = deviceContext.isKeyPressed(BTN_MIDDLE);
+ mBtnBack = deviceContext.isKeyPressed(BTN_BACK);
+ mBtnSide = deviceContext.isKeyPressed(BTN_SIDE);
+ mBtnForward = deviceContext.isKeyPressed(BTN_FORWARD);
+ mBtnExtra = deviceContext.isKeyPressed(BTN_EXTRA);
+ mBtnTask = deviceContext.isKeyPressed(BTN_TASK);
}
void CursorButtonAccumulator::clearButtons() {
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h
index d912310..9e15906 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h
@@ -21,14 +21,14 @@
namespace android {
-class InputDevice;
+class InputDeviceContext;
struct RawEvent;
/* Keeps track of the state of mouse or touch pad buttons. */
class CursorButtonAccumulator {
public:
CursorButtonAccumulator();
- void reset(InputDevice* device);
+ void reset(InputDeviceContext& deviceContext);
void process(const RawEvent* rawEvent);
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
index d744096..0714694 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
@@ -25,12 +25,12 @@
clearRelativeAxes();
}
-void CursorScrollAccumulator::configure(InputDevice* device) {
- mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
- mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
+void CursorScrollAccumulator::configure(InputDeviceContext& deviceContext) {
+ mHaveRelWheel = deviceContext.hasRelativeAxis(REL_WHEEL);
+ mHaveRelHWheel = deviceContext.hasRelativeAxis(REL_HWHEEL);
}
-void CursorScrollAccumulator::reset(InputDevice* device) {
+void CursorScrollAccumulator::reset(InputDeviceContext& deviceContext) {
clearRelativeAxes();
}
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
index 85f331f..1649559 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
@@ -21,7 +21,7 @@
namespace android {
-class InputDevice;
+class InputDeviceContext;
struct RawEvent;
/* Keeps track of cursor scrolling motions. */
@@ -29,8 +29,8 @@
class CursorScrollAccumulator {
public:
CursorScrollAccumulator();
- void configure(InputDevice* device);
- void reset(InputDevice* device);
+ void configure(InputDeviceContext& deviceContext);
+ void reset(InputDeviceContext& deviceContext);
void process(const RawEvent* rawEvent);
void finishSync();
diff --git a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
index e9ba727..27b8e40 100644
--- a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
@@ -25,14 +25,14 @@
clearAbsoluteAxes();
}
-void SingleTouchMotionAccumulator::reset(InputDevice* device) {
- mAbsX = device->getAbsoluteAxisValue(ABS_X);
- mAbsY = device->getAbsoluteAxisValue(ABS_Y);
- mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
- mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
- mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
- mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
- mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
+void SingleTouchMotionAccumulator::reset(InputDeviceContext& deviceContext) {
+ mAbsX = deviceContext.getAbsoluteAxisValue(ABS_X);
+ mAbsY = deviceContext.getAbsoluteAxisValue(ABS_Y);
+ mAbsPressure = deviceContext.getAbsoluteAxisValue(ABS_PRESSURE);
+ mAbsToolWidth = deviceContext.getAbsoluteAxisValue(ABS_TOOL_WIDTH);
+ mAbsDistance = deviceContext.getAbsoluteAxisValue(ABS_DISTANCE);
+ mAbsTiltX = deviceContext.getAbsoluteAxisValue(ABS_TILT_X);
+ mAbsTiltY = deviceContext.getAbsoluteAxisValue(ABS_TILT_Y);
}
void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
diff --git a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h
index 75f8a96..4c011f1 100644
--- a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h
@@ -21,7 +21,7 @@
namespace android {
-class InputDevice;
+class InputDeviceContext;
struct RawEvent;
/* Keeps track of the state of single-touch protocol. */
@@ -30,7 +30,7 @@
SingleTouchMotionAccumulator();
void process(const RawEvent* rawEvent);
- void reset(InputDevice* device);
+ void reset(InputDeviceContext& deviceContext);
inline int32_t getAbsoluteX() const { return mAbsX; }
inline int32_t getAbsoluteY() const { return mAbsY; }
diff --git a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
index d2f06c8..86153d3 100644
--- a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
@@ -25,29 +25,31 @@
clearButtons();
}
-void TouchButtonAccumulator::configure(InputDevice* device) {
- mHaveBtnTouch = device->hasKey(BTN_TOUCH);
- mHaveStylus = device->hasKey(BTN_TOOL_PEN) || device->hasKey(BTN_TOOL_RUBBER) ||
- device->hasKey(BTN_TOOL_BRUSH) || device->hasKey(BTN_TOOL_PENCIL) ||
- device->hasKey(BTN_TOOL_AIRBRUSH);
+void TouchButtonAccumulator::configure(InputDeviceContext& deviceContext) {
+ mHaveBtnTouch = deviceContext.hasScanCode(BTN_TOUCH);
+ mHaveStylus = deviceContext.hasScanCode(BTN_TOOL_PEN) ||
+ deviceContext.hasScanCode(BTN_TOOL_RUBBER) ||
+ deviceContext.hasScanCode(BTN_TOOL_BRUSH) ||
+ deviceContext.hasScanCode(BTN_TOOL_PENCIL) ||
+ deviceContext.hasScanCode(BTN_TOOL_AIRBRUSH);
}
-void TouchButtonAccumulator::reset(InputDevice* device) {
- mBtnTouch = device->isKeyPressed(BTN_TOUCH);
- mBtnStylus = device->isKeyPressed(BTN_STYLUS);
+void TouchButtonAccumulator::reset(InputDeviceContext& deviceContext) {
+ mBtnTouch = deviceContext.isKeyPressed(BTN_TOUCH);
+ mBtnStylus = deviceContext.isKeyPressed(BTN_STYLUS);
// BTN_0 is what gets mapped for the HID usage Digitizers.SecondaryBarrelSwitch
- mBtnStylus2 = device->isKeyPressed(BTN_STYLUS2) || device->isKeyPressed(BTN_0);
- mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
- mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
- mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
- mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
- mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
- mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
- mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
- mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
- mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
- mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
- mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
+ mBtnStylus2 = deviceContext.isKeyPressed(BTN_STYLUS2) || deviceContext.isKeyPressed(BTN_0);
+ mBtnToolFinger = deviceContext.isKeyPressed(BTN_TOOL_FINGER);
+ mBtnToolPen = deviceContext.isKeyPressed(BTN_TOOL_PEN);
+ mBtnToolRubber = deviceContext.isKeyPressed(BTN_TOOL_RUBBER);
+ mBtnToolBrush = deviceContext.isKeyPressed(BTN_TOOL_BRUSH);
+ mBtnToolPencil = deviceContext.isKeyPressed(BTN_TOOL_PENCIL);
+ mBtnToolAirbrush = deviceContext.isKeyPressed(BTN_TOOL_AIRBRUSH);
+ mBtnToolMouse = deviceContext.isKeyPressed(BTN_TOOL_MOUSE);
+ mBtnToolLens = deviceContext.isKeyPressed(BTN_TOOL_LENS);
+ mBtnToolDoubleTap = deviceContext.isKeyPressed(BTN_TOOL_DOUBLETAP);
+ mBtnToolTripleTap = deviceContext.isKeyPressed(BTN_TOOL_TRIPLETAP);
+ mBtnToolQuadTap = deviceContext.isKeyPressed(BTN_TOOL_QUADTAP);
}
void TouchButtonAccumulator::clearButtons() {
diff --git a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
index 65b6bdc..22ebb72 100644
--- a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
@@ -21,15 +21,15 @@
namespace android {
-class InputDevice;
+class InputDeviceContext;
struct RawEvent;
/* Keeps track of the state of touch, stylus and tool buttons. */
class TouchButtonAccumulator {
public:
TouchButtonAccumulator();
- void configure(InputDevice* device);
- void reset(InputDevice* device);
+ void configure(InputDeviceContext& deviceContext);
+ void reset(InputDeviceContext& deviceContext);
void process(const RawEvent* rawEvent);
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 7cd8793..01bd9db 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -881,9 +881,7 @@
virtual void disableVirtualKeysUntil(nsecs_t) {
}
- virtual bool shouldDropVirtualKey(nsecs_t, InputDevice*, int32_t, int32_t) {
- return false;
- }
+ virtual bool shouldDropVirtualKey(nsecs_t, int32_t, int32_t) { return false; }
virtual void fadePointer() {
}
@@ -929,12 +927,14 @@
std::optional<DisplayViewport> mViewport;
public:
- FakeInputMapper(InputDevice* device, uint32_t sources) :
- InputMapper(device),
- mSources(sources), mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
+ FakeInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
+ : InputMapper(deviceContext),
+ mSources(sources),
+ mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
mMetaState(0),
- mConfigureWasCalled(false), mResetWasCalled(false), mProcessWasCalled(false) {
- }
+ mConfigureWasCalled(false),
+ mResetWasCalled(false),
+ mProcessWasCalled(false) {}
virtual ~FakeInputMapper() { }
@@ -1022,7 +1022,7 @@
mConfigureWasCalled = true;
// Find the associated viewport if exist.
- const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort();
+ const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
mViewport = config->getDisplayViewportByPort(*displayPort);
}
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 5246c78..532a2e5 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -33,6 +33,10 @@
"-fvisibility=hidden"
],
+ header_libs: [
+ "android.hardware.sensors@2.X-shared-utils",
+ ],
+
shared_libs: [
"libcutils",
"libhardware",
@@ -49,9 +53,12 @@
"libfmq",
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
+ "android.hardware.sensors@2.1",
],
- static_libs: ["android.hardware.sensors@1.0-convert"],
+ static_libs: [
+ "android.hardware.sensors@1.0-convert",
+ ],
generated_headers: ["framework-cppstream-protos"],
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 33f940f..3b68e0e 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -16,8 +16,10 @@
#include "SensorDevice.h"
-#include "android/hardware/sensors/2.0/ISensorsCallback.h"
#include "android/hardware/sensors/2.0/types.h"
+#include "android/hardware/sensors/2.1/ISensorsCallback.h"
+#include "android/hardware/sensors/2.1/types.h"
+#include "convertV2_1.h"
#include "SensorService.h"
#include <android-base/logging.h>
@@ -35,9 +37,15 @@
using namespace android::hardware::sensors;
using namespace android::hardware::sensors::V1_0;
using namespace android::hardware::sensors::V1_0::implementation;
-using android::hardware::sensors::V2_0::ISensorsCallback;
using android::hardware::sensors::V2_0::EventQueueFlagBits;
using android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
+using android::hardware::sensors::V2_1::ISensorsCallback;
+using android::hardware::sensors::V2_1::implementation::convertToOldSensorInfo;
+using android::hardware::sensors::V2_1::implementation::convertToNewSensorInfos;
+using android::hardware::sensors::V2_1::implementation::convertToNewEvents;
+using android::hardware::sensors::V2_1::implementation::ISensorsWrapperV1_0;
+using android::hardware::sensors::V2_1::implementation::ISensorsWrapperV2_0;
+using android::hardware::sensors::V2_1::implementation::ISensorsWrapperV2_1;
using android::hardware::hidl_vec;
using android::hardware::Return;
using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
@@ -87,11 +95,19 @@
struct SensorsCallback : public ISensorsCallback {
using Result = ::android::hardware::sensors::V1_0::Result;
- Return<void> onDynamicSensorsConnected(
+ using SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo;
+
+ Return<void> onDynamicSensorsConnected_2_1(
const hidl_vec<SensorInfo> &dynamicSensorsAdded) override {
return SensorDevice::getInstance().onDynamicSensorsConnected(dynamicSensorsAdded);
}
+ Return<void> onDynamicSensorsConnected(
+ const hidl_vec<V1_0::SensorInfo> &dynamicSensorsAdded) override {
+ return SensorDevice::getInstance().onDynamicSensorsConnected(
+ convertToNewSensorInfos(dynamicSensorsAdded));
+ }
+
Return<void> onDynamicSensorsDisconnected(
const hidl_vec<int32_t> &dynamicSensorHandlesRemoved) override {
return SensorDevice::getInstance().onDynamicSensorsDisconnected(
@@ -126,7 +142,7 @@
Info model;
for (size_t i=0 ; i < count; i++) {
sensor_t sensor;
- convertToSensor(list[i], &sensor);
+ convertToSensor(convertToOldSensorInfo(list[i]), &sensor);
// Sanity check and clamp power if it is 0 (or close)
if (sensor.power < minPowerMa) {
ALOGI("Reported power %f not deemed sane, clamping to %f",
@@ -160,7 +176,11 @@
}
bool SensorDevice::connectHidlService() {
- HalConnectionStatus status = connectHidlServiceV2_0();
+ HalConnectionStatus status = connectHidlServiceV2_1();
+ if (status == HalConnectionStatus::DOES_NOT_EXIST) {
+ status = connectHidlServiceV2_0();
+ }
+
if (status == HalConnectionStatus::DOES_NOT_EXIST) {
status = connectHidlServiceV1_0();
}
@@ -180,7 +200,7 @@
break;
}
- mSensors = new SensorServiceUtil::SensorsWrapperV1_0(sensors);
+ mSensors = new ISensorsWrapperV1_0(sensors);
mRestartWaiter->reset();
// Poke ISensor service. If it has lingering connection from previous generation of
// system server, it will kill itself. There is no intention to handle the poll result,
@@ -208,40 +228,55 @@
if (sensors == nullptr) {
connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
} else {
- mSensors = new SensorServiceUtil::SensorsWrapperV2_0(sensors);
+ mSensors = new ISensorsWrapperV2_0(sensors);
+ connectionStatus = initializeHidlServiceV2_X();
+ }
- mEventQueue = std::make_unique<EventMessageQueue>(
- SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
- true /* configureEventFlagWord */);
+ return connectionStatus;
+}
- mWakeLockQueue = std::make_unique<WakeLockQueue>(
- SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
- true /* configureEventFlagWord */);
+SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_1() {
+ HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
+ sp<V2_1::ISensors> sensors = V2_1::ISensors::getService();
- hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
- hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
+ if (sensors == nullptr) {
+ connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
+ } else {
+ mSensors = new ISensorsWrapperV2_1(sensors);
+ connectionStatus = initializeHidlServiceV2_X();
+ }
- hardware::EventFlag::deleteEventFlag(&mWakeLockQueueFlag);
- hardware::EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(),
- &mWakeLockQueueFlag);
+ return connectionStatus;
+}
- CHECK(mSensors != nullptr && mEventQueue != nullptr &&
- mWakeLockQueue != nullptr && mEventQueueFlag != nullptr &&
- mWakeLockQueueFlag != nullptr);
+SensorDevice::HalConnectionStatus SensorDevice::initializeHidlServiceV2_X() {
+ HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
- status_t status = checkReturnAndGetStatus(mSensors->initialize(
- *mEventQueue->getDesc(),
- *mWakeLockQueue->getDesc(),
- new SensorsCallback()));
+ mWakeLockQueue = std::make_unique<WakeLockQueue>(
+ SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
+ true /* configureEventFlagWord */);
- if (status != NO_ERROR) {
- connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
- ALOGE("Failed to initialize Sensors HAL (%s)", strerror(-status));
- } else {
- connectionStatus = HalConnectionStatus::CONNECTED;
- mSensorsHalDeathReceiver = new SensorsHalDeathReceivier();
- sensors->linkToDeath(mSensorsHalDeathReceiver, 0 /* cookie */);
- }
+ hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
+ hardware::EventFlag::createEventFlag(mSensors->getEventQueue()->getEventFlagWord(), &mEventQueueFlag);
+
+ hardware::EventFlag::deleteEventFlag(&mWakeLockQueueFlag);
+ hardware::EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(),
+ &mWakeLockQueueFlag);
+
+ CHECK(mSensors != nullptr && mWakeLockQueue != nullptr &&
+ mEventQueueFlag != nullptr && mWakeLockQueueFlag != nullptr);
+
+ status_t status = checkReturnAndGetStatus(mSensors->initialize(
+ *mWakeLockQueue->getDesc(),
+ new SensorsCallback()));
+
+ if (status != NO_ERROR) {
+ connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
+ ALOGE("Failed to initialize Sensors HAL (%s)", strerror(-status));
+ } else {
+ connectionStatus = HalConnectionStatus::CONNECTED;
+ mSensorsHalDeathReceiver = new SensorsHalDeathReceivier();
+ mSensors->linkToDeath(mSensorsHalDeathReceiver, 0 /* cookie */);
}
return connectionStatus;
@@ -473,7 +508,8 @@
const auto &events,
const auto &dynamicSensorsAdded) {
if (result == Result::OK) {
- convertToSensorEvents(events, dynamicSensorsAdded, buffer);
+ convertToSensorEvents(convertToNewEvents(events),
+ convertToNewSensorInfos(dynamicSensorsAdded), buffer);
err = (ssize_t)events.size();
} else {
err = statusFromResult(result);
@@ -507,7 +543,7 @@
ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead) {
ssize_t eventsRead = 0;
- size_t availableEvents = mEventQueue->availableToRead();
+ size_t availableEvents = mSensors->getEventQueue()->availableToRead();
if (availableEvents == 0) {
uint32_t eventFlagState = 0;
@@ -518,7 +554,7 @@
// additional latency in delivering events to applications.
mEventQueueFlag->wait(asBaseType(EventQueueFlagBits::READ_AND_PROCESS) |
asBaseType(INTERNAL_WAKE), &eventFlagState);
- availableEvents = mEventQueue->availableToRead();
+ availableEvents = mSensors->getEventQueue()->availableToRead();
if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mReconnecting) {
ALOGD("Event FMQ internal wake, returning from poll with no events");
@@ -528,7 +564,7 @@
size_t eventsToRead = std::min({availableEvents, maxNumEventsToRead, mEventBuffer.size()});
if (eventsToRead > 0) {
- if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
+ if (mSensors->getEventQueue()->read(mEventBuffer.data(), eventsToRead)) {
// Notify the Sensors HAL that sensor events have been read. This is required to support
// the use of writeBlocking by the Sensors HAL.
mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::EVENTS_READ));
@@ -557,7 +593,7 @@
CHECK(it == mConnectedDynamicSensors.end());
sensor_t *sensor = new sensor_t();
- convertToSensor(info, sensor);
+ convertToSensor(convertToOldSensorInfo(info), sensor);
mConnectedDynamicSensors.insert(
std::make_pair(sensor->handle, sensor));
@@ -858,7 +894,7 @@
injected_sensor_event->data[5]);
Event ev;
- convertFromSensorEvent(*injected_sensor_event, &ev);
+ V2_1::implementation::convertFromSensorEvent(*injected_sensor_event, &ev);
return checkReturnAndGetStatus(mSensors->injectSensorData(ev));
}
@@ -1021,10 +1057,9 @@
void SensorDevice::convertToSensorEvent(
const Event &src, sensors_event_t *dst) {
- ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
- src, dst);
+ V2_1::implementation::convertToSensorEvent(src, dst);
- if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
+ if (src.sensorType == V2_1::SensorType::DYNAMIC_SENSOR_META) {
const DynamicSensorInfo &dyn = src.u.dynamic;
dst->dynamic_sensor_meta.connected = dyn.connected;
@@ -1052,7 +1087,7 @@
}
for (size_t i = 0; i < src.size(); ++i) {
- convertToSensorEvent(src[i], &dst[i]);
+ V2_1::implementation::convertToSensorEvent(src[i], &dst[i]);
}
}
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 33aa7d6..24d03c6 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -19,7 +19,7 @@
#include "SensorDeviceUtils.h"
#include "SensorServiceUtils.h"
-#include "SensorsWrapper.h"
+#include "ISensorsWrapper.h"
#include <fmq/MessageQueue.h>
#include <sensor/SensorEventQueue.h>
@@ -112,7 +112,7 @@
using Result = ::android::hardware::sensors::V1_0::Result;
hardware::Return<void> onDynamicSensorsConnected(
- const hardware::hidl_vec<hardware::sensors::V1_0::SensorInfo> &dynamicSensorsAdded);
+ const hardware::hidl_vec<hardware::sensors::V2_1::SensorInfo> &dynamicSensorsAdded);
hardware::Return<void> onDynamicSensorsDisconnected(
const hardware::hidl_vec<int32_t> &dynamicSensorHandlesRemoved);
@@ -128,7 +128,7 @@
private:
friend class Singleton<SensorDevice>;
- sp<SensorServiceUtil::ISensorsWrapper> mSensors;
+ sp<::android::hardware::sensors::V2_1::implementation::ISensorsWrapperBase> mSensors;
Vector<sensor_t> mSensorList;
std::unordered_map<int32_t, sensor_t*> mConnectedDynamicSensors;
@@ -205,6 +205,8 @@
};
HalConnectionStatus connectHidlServiceV1_0();
HalConnectionStatus connectHidlServiceV2_0();
+ HalConnectionStatus connectHidlServiceV2_1();
+ HalConnectionStatus initializeHidlServiceV2_X();
ssize_t pollHal(sensors_event_t* buffer, size_t count);
ssize_t pollFmq(sensors_event_t* buffer, size_t count);
@@ -226,8 +228,8 @@
bool isClientDisabled(void* ident);
bool isClientDisabledLocked(void* ident);
- using Event = hardware::sensors::V1_0::Event;
- using SensorInfo = hardware::sensors::V1_0::SensorInfo;
+ using Event = hardware::sensors::V2_1::Event;
+ using SensorInfo = hardware::sensors::V2_1::SensorInfo;
void convertToSensorEvent(const Event &src, sensors_event_t *dst);
@@ -238,9 +240,7 @@
bool mIsDirectReportSupported;
- typedef hardware::MessageQueue<Event, hardware::kSynchronizedReadWrite> EventMessageQueue;
typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue;
- std::unique_ptr<EventMessageQueue> mEventQueue;
std::unique_ptr<WakeLockQueue> mWakeLockQueue;
hardware::EventFlag* mEventQueueFlag;
diff --git a/services/sensorservice/SensorsWrapper.h b/services/sensorservice/SensorsWrapper.h
deleted file mode 100644
index d1a7234..0000000
--- a/services/sensorservice/SensorsWrapper.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_SENSORS_WRAPPER_H
-#define ANDROID_SENSORS_WRAPPER_H
-
-#include "android/hardware/sensors/1.0/ISensors.h"
-#include "android/hardware/sensors/2.0/ISensors.h"
-#include "android/hardware/sensors/2.0/ISensorsCallback.h"
-
-#include <utils/LightRefBase.h>
-
-namespace android {
-namespace SensorServiceUtil {
-
-using ::android::hardware::MQDescriptorSync;
-using ::android::hardware::Return;
-using ::android::hardware::sensors::V1_0::Event;
-using ::android::hardware::sensors::V1_0::ISensors;
-using ::android::hardware::sensors::V1_0::OperationMode;
-using ::android::hardware::sensors::V1_0::RateLevel;
-using ::android::hardware::sensors::V1_0::Result;
-using ::android::hardware::sensors::V1_0::SharedMemInfo;
-using ::android::hardware::sensors::V2_0::ISensorsCallback;
-
-/*
- * The ISensorsWrapper interface includes all function from supported Sensors HAL versions. This
- * allows for the SensorDevice to use the ISensorsWrapper interface to interact with the Sensors
- * HAL regardless of the current version of the Sensors HAL that is loaded. Each concrete
- * instantiation of ISensorsWrapper must correspond to a specific Sensors HAL version. This design
- * is beneficial because only the functions that change between Sensors HAL versions must be newly
- * newly implemented, any previously implemented function that does not change may remain the same.
- *
- * Functions that exist across all versions of the Sensors HAL should be implemented as pure
- * virtual functions which forces the concrete instantiations to implement the functions.
- *
- * Functions that do not exist across all versions of the Sensors HAL should include a default
- * implementation that generates an error if called. The default implementation should never
- * be called and must be overridden by Sensors HAL versions that support the function.
- */
-class ISensorsWrapper : public VirtualLightRefBase {
-public:
- virtual bool supportsPolling() const = 0;
-
- virtual bool supportsMessageQueues() const = 0;
-
- virtual Return<void> getSensorsList(ISensors::getSensorsList_cb _hidl_cb) = 0;
-
- virtual Return<Result> setOperationMode(OperationMode mode) = 0;
-
- virtual Return<Result> activate(int32_t sensorHandle, bool enabled) = 0;
-
- virtual Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
- int64_t maxReportLatencyNs) = 0;
-
- virtual Return<Result> flush(int32_t sensorHandle) = 0;
-
- virtual Return<Result> injectSensorData(const Event& event) = 0;
-
- virtual Return<void> registerDirectChannel(const SharedMemInfo& mem,
- ISensors::registerDirectChannel_cb _hidl_cb) = 0;
-
- virtual Return<Result> unregisterDirectChannel(int32_t channelHandle) = 0;
-
- virtual Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle,
- RateLevel rate,
- ISensors::configDirectReport_cb _hidl_cb) = 0;
-
- virtual Return<void> poll(int32_t maxCount, ISensors::poll_cb _hidl_cb) {
- (void)maxCount;
- (void)_hidl_cb;
- // TODO (b/111070257): Generate an assert-level error since this should never be called
- // directly
- return Return<void>();
- }
-
- virtual Return<Result> initialize(const MQDescriptorSync<Event>& eventQueueDesc,
- const MQDescriptorSync<uint32_t>& wakeLockDesc,
- const ::android::sp<ISensorsCallback>& callback) {
- (void)eventQueueDesc;
- (void)wakeLockDesc;
- (void)callback;
- // TODO (b/111070257): Generate an assert-level error since this should never be called
- // directly
- return Result::INVALID_OPERATION;
- }
-};
-
-template<typename T>
-class SensorsWrapperBase : public ISensorsWrapper {
-public:
- SensorsWrapperBase(sp<T> sensors) :
- mSensors(sensors) { };
-
- Return<void> getSensorsList(ISensors::getSensorsList_cb _hidl_cb) override {
- return mSensors->getSensorsList(_hidl_cb);
- }
-
- Return<Result> setOperationMode(OperationMode mode) override {
- return mSensors->setOperationMode(mode);
- }
-
- Return<Result> activate(int32_t sensorHandle, bool enabled) override {
- return mSensors->activate(sensorHandle, enabled);
- }
-
- Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
- int64_t maxReportLatencyNs) override {
- return mSensors->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs);
- }
-
- Return<Result> flush(int32_t sensorHandle) override {
- return mSensors->flush(sensorHandle);
- }
-
- Return<Result> injectSensorData(const Event& event) override {
- return mSensors->injectSensorData(event);
- }
-
- Return<void> registerDirectChannel(const SharedMemInfo& mem,
- ISensors::registerDirectChannel_cb _hidl_cb) override {
- return mSensors->registerDirectChannel(mem, _hidl_cb);
- }
-
- Return<Result> unregisterDirectChannel(int32_t channelHandle) override {
- return mSensors->unregisterDirectChannel(channelHandle);
- }
-
- Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle,
- RateLevel rate,
- ISensors::configDirectReport_cb _hidl_cb) override {
- return mSensors->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
- }
-
-protected:
- sp<T> mSensors;
-};
-
-class SensorsWrapperV1_0 : public SensorsWrapperBase<hardware::sensors::V1_0::ISensors> {
-public:
- SensorsWrapperV1_0(sp<hardware::sensors::V1_0::ISensors> sensors) :
- SensorsWrapperBase(sensors) { };
-
- bool supportsPolling() const override {
- return true;
- }
-
- bool supportsMessageQueues() const override {
- return false;
- }
-
- Return<void> poll(int32_t maxCount,
- hardware::sensors::V1_0::ISensors::poll_cb _hidl_cb) override {
- return mSensors->poll(maxCount, _hidl_cb);
- }
-};
-
-class SensorsWrapperV2_0 : public SensorsWrapperBase<hardware::sensors::V2_0::ISensors> {
-public:
- SensorsWrapperV2_0(sp<hardware::sensors::V2_0::ISensors> sensors)
- : SensorsWrapperBase(sensors) { };
-
- bool supportsPolling() const override {
- return false;
- }
-
- bool supportsMessageQueues() const override {
- return true;
- }
-
- Return<Result> initialize(const MQDescriptorSync<Event>& eventQueueDesc,
- const MQDescriptorSync<uint32_t>& wakeLockDesc,
- const ::android::sp<ISensorsCallback>& callback) override {
- return mSensors->initialize(eventQueueDesc, wakeLockDesc, callback);
- }
-};
-
-}; // namespace SensorServiceUtil
-}; // namespace android
-
-#endif // ANDROID_SENSORS_WRAPPER_H
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index b313777..bc0111b 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -97,6 +97,7 @@
}
LayerHistory::Summary LayerHistory::summarize(nsecs_t now) {
+ ATRACE_CALL();
std::lock_guard lock(mLock);
partitionLayers(now);
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
index 345b8f9..b755798 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
@@ -61,21 +61,35 @@
}
bool LayerInfoV2::isFrequent(nsecs_t now) const {
+ // Find the first valid frame time
+ auto it = mFrameTimes.begin();
+ for (; it != mFrameTimes.end(); ++it) {
+ if (isFrameTimeValid(*it)) {
+ break;
+ }
+ }
+
// If we know nothing about this layer we consider it as frequent as it might be the start
// of an animation.
- if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) {
+ if (std::distance(it, mFrameTimes.end()) < FREQUENT_LAYER_WINDOW_SIZE) {
return true;
}
- // Layer is frequent if the earliest value in the window of most recent present times is
- // within threshold.
- const auto it = mFrameTimes.end() - FREQUENT_LAYER_WINDOW_SIZE;
- if (!isFrameTimeValid(*it)) {
- return true;
+ // Find the first active frame
+ for (; it != mFrameTimes.end(); ++it) {
+ if (it->queueTime >= getActiveLayerThreshold(now)) {
+ break;
+ }
}
- const nsecs_t threshold = now - MAX_FREQUENT_LAYER_PERIOD_NS.count();
- return it->queueTime >= threshold;
+ const auto numFrames = std::distance(it, mFrameTimes.end()) - 1;
+ if (numFrames <= 0) {
+ return false;
+ }
+
+ // Layer is considered frequent if the average frame rate is higher than the threshold
+ const auto totalTime = mFrameTimes.back().queueTime - it->queueTime;
+ return (1e9f * numFrames) / totalTime >= MIN_FPS_FOR_FREQUENT_LAYER;
}
bool LayerInfoV2::hasEnoughDataForHeuristic() const {
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.h b/services/surfaceflinger/Scheduler/LayerInfoV2.h
index 90f6310..25fb95a 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.h
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.h
@@ -47,7 +47,9 @@
// is within a threshold. If a layer is infrequent, its average refresh rate is disregarded in
// favor of a low refresh rate.
static constexpr size_t FREQUENT_LAYER_WINDOW_SIZE = 3;
- static constexpr std::chrono::nanoseconds MAX_FREQUENT_LAYER_PERIOD_NS = 250ms;
+ static constexpr float MIN_FPS_FOR_FREQUENT_LAYER = 10.0f;
+ static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS =
+ std::chrono::nanoseconds(static_cast<nsecs_t>(1e9f / MIN_FPS_FOR_FREQUENT_LAYER)) + 1ms;
friend class LayerHistoryTestV2;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index d1de737..b876ccd 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -23,8 +23,6 @@
#include <chrono>
#include <cmath>
-using namespace std::chrono_literals;
-
namespace android::scheduler {
using AllRefreshRatesMapType = RefreshRateConfigs::AllRefreshRatesMapType;
@@ -84,14 +82,31 @@
return *bestSoFar;
}
+std::pair<nsecs_t, nsecs_t> RefreshRateConfigs::getDisplayFrames(nsecs_t layerPeriod,
+ nsecs_t displayPeriod) const {
+ auto [displayFramesQuot, displayFramesRem] = std::div(layerPeriod, displayPeriod);
+ if (displayFramesRem <= MARGIN_FOR_PERIOD_CALCULATION ||
+ std::abs(displayFramesRem - displayPeriod) <= MARGIN_FOR_PERIOD_CALCULATION) {
+ displayFramesQuot++;
+ displayFramesRem = 0;
+ }
+
+ return {displayFramesQuot, displayFramesRem};
+}
+
const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2(
- const std::vector<LayerRequirement>& layers) const {
- constexpr nsecs_t MARGIN = std::chrono::nanoseconds(800us).count();
+ const std::vector<LayerRequirement>& layers, bool touchActive) const {
ATRACE_CALL();
ALOGV("getRefreshRateForContent %zu layers", layers.size());
std::lock_guard lock(mLock);
+ // For now if the touch is active return the peak refresh rate
+ // This should be optimized to consider other layers as well.
+ if (touchActive) {
+ return *mAvailableRefreshRates.back();
+ }
+
int noVoteLayers = 0;
int minVoteLayers = 0;
int maxVoteLayers = 0;
@@ -115,11 +130,6 @@
return *mAvailableRefreshRates.front();
}
- // If we have some Max layers and no Explicit we should return Max
- if (maxVoteLayers > 0 && explicitDefaultVoteLayers + explicitExactOrMultipleVoteLayers == 0) {
- return *mAvailableRefreshRates.back();
- }
-
// Find the best refresh rate based on score
std::vector<std::pair<const RefreshRate*, float>> scores;
scores.reserve(mAvailableRefreshRates.size());
@@ -130,67 +140,85 @@
for (const auto& layer : layers) {
ALOGV("Calculating score for %s (type: %d)", layer.name.c_str(), layer.vote);
- if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min ||
- layer.vote == LayerVoteType::Max) {
+ if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) {
continue;
}
- // Adjust the weight in case we have explicit layers. The priority is:
- // - ExplicitExactOrMultiple
- // - ExplicitDefault
- // - Heuristic
auto weight = layer.weight;
- if (explicitExactOrMultipleVoteLayers + explicitDefaultVoteLayers > 0) {
- if (layer.vote == LayerVoteType::Heuristic) {
- weight /= 2.f;
- }
- }
- if (explicitExactOrMultipleVoteLayers > 0) {
- if (layer.vote == LayerVoteType::Heuristic ||
- layer.vote == LayerVoteType::ExplicitDefault) {
- weight /= 2.f;
+ for (auto i = 0u; i < scores.size(); i++) {
+ // If the layer wants Max, give higher score to the higher refresh rate
+ if (layer.vote == LayerVoteType::Max) {
+ const auto ratio = scores[i].first->fps / scores.back().first->fps;
+ // use ratio^2 to get a lower score the more we get further from peak
+ const auto layerScore = ratio * ratio;
+ ALOGV("%s (Max, weight %.2f) gives %s score of %.2f", layer.name.c_str(), weight,
+ scores[i].first->name.c_str(), layerScore);
+ scores[i].second += weight * layerScore;
+ continue;
}
- }
- for (auto& [refreshRate, overallScore] : scores) {
- const auto displayPeriod = refreshRate->vsyncPeriod;
+ const auto displayPeriod = scores[i].first->vsyncPeriod;
const auto layerPeriod = round<nsecs_t>(1e9f / layer.desiredRefreshRate);
+ if (layer.vote == LayerVoteType::ExplicitDefault) {
+ const auto layerScore = [&]() {
+ const auto [displayFramesQuot, displayFramesRem] =
+ getDisplayFrames(layerPeriod, displayPeriod);
+ if (displayFramesQuot == 0) {
+ // Layer desired refresh rate is higher the display rate.
+ return static_cast<float>(layerPeriod) / static_cast<float>(displayPeriod);
+ }
- // Calculate how many display vsyncs we need to present a single frame for this layer
- auto [displayFramesQuot, displayFramesRem] = std::div(layerPeriod, displayPeriod);
- if (displayFramesRem <= MARGIN ||
- std::abs(displayFramesRem - displayPeriod) <= MARGIN) {
- displayFramesQuot++;
- displayFramesRem = 0;
+ return 1.0f -
+ (static_cast<float>(displayFramesRem) /
+ static_cast<float>(layerPeriod));
+ }();
+
+ ALOGV("%s (ExplicitDefault, weight %.2f) %.2fHz gives %s score of %.2f",
+ layer.name.c_str(), weight, 1e9f / layerPeriod, scores[i].first->name.c_str(),
+ layerScore);
+ scores[i].second += weight * layerScore;
+ continue;
}
- float layerScore;
- static constexpr size_t MAX_FRAMES_TO_FIT = 10; // Stop calculating when score < 0.1
- if (displayFramesRem == 0) {
- // Layer desired refresh rate matches the display rate.
- layerScore = weight * 1.0f;
- } else if (displayFramesQuot == 0) {
- // Layer desired refresh rate is higher the display rate.
- layerScore = weight *
- (static_cast<float>(layerPeriod) / static_cast<float>(displayPeriod)) *
- (1.0f / (MAX_FRAMES_TO_FIT + 1));
- } else {
- // Layer desired refresh rate is lower the display rate. Check how well it fits the
- // cadence
- auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem));
- int iter = 2;
- while (diff > MARGIN && iter < MAX_FRAMES_TO_FIT) {
- diff = diff - (displayPeriod - diff);
- iter++;
- }
+ if (layer.vote == LayerVoteType::ExplicitExactOrMultiple ||
+ layer.vote == LayerVoteType::Heuristic) {
+ const auto layerScore = [&]() {
+ // Calculate how many display vsyncs we need to present a single frame for this
+ // layer
+ const auto [displayFramesQuot, displayFramesRem] =
+ getDisplayFrames(layerPeriod, displayPeriod);
+ static constexpr size_t MAX_FRAMES_TO_FIT =
+ 10; // Stop calculating when score < 0.1
+ if (displayFramesRem == 0) {
+ // Layer desired refresh rate matches the display rate.
+ return 1.0f;
+ }
- layerScore = weight * (1.0f / iter);
+ if (displayFramesQuot == 0) {
+ // Layer desired refresh rate is higher the display rate.
+ return (static_cast<float>(layerPeriod) /
+ static_cast<float>(displayPeriod)) *
+ (1.0f / (MAX_FRAMES_TO_FIT + 1));
+ }
+
+ // Layer desired refresh rate is lower the display rate. Check how well it fits
+ // the cadence
+ auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem));
+ int iter = 2;
+ while (diff > MARGIN_FOR_PERIOD_CALCULATION && iter < MAX_FRAMES_TO_FIT) {
+ diff = diff - (displayPeriod - diff);
+ iter++;
+ }
+
+ return 1.0f / iter;
+ }();
+ ALOGV("%s (ExplicitExactOrMultiple, weight %.2f) %.2fHz gives %s score of %.2f",
+ layer.name.c_str(), weight, 1e9f / layerPeriod, scores[i].first->name.c_str(),
+ layerScore);
+ scores[i].second += weight * layerScore;
+ continue;
}
-
- ALOGV("%s (weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(), weight,
- 1e9f / layerPeriod, refreshRate->name.c_str(), layerScore);
- overallScore += layerScore;
}
}
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 1132a8c..0b5c73c 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -28,6 +28,7 @@
#include "Scheduler/StrongTyping.h"
namespace android::scheduler {
+using namespace std::chrono_literals;
enum class RefreshRateConfigEvent : unsigned { None = 0b0, Changed = 0b1 };
@@ -43,6 +44,10 @@
*/
class RefreshRateConfigs {
public:
+ // Margin used when matching refresh rates to the content desired ones.
+ static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION =
+ std::chrono::nanoseconds(800us).count();
+
struct RefreshRate {
// The tolerance within which we consider FPS approximately equals.
static constexpr float FPS_EPSILON = 0.001f;
@@ -123,13 +128,15 @@
bool operator!=(const LayerRequirement& other) const { return !(*this == other); }
};
- // Returns all available refresh rates according to the current policy.
+ // Returns the refresh rate that fits best to the given layers.
const RefreshRate& getRefreshRateForContent(const std::vector<LayerRequirement>& layers) const
EXCLUDES(mLock);
- // Returns all available refresh rates according to the current policy.
- const RefreshRate& getRefreshRateForContentV2(const std::vector<LayerRequirement>& layers) const
- EXCLUDES(mLock);
+ // Returns the refresh rate that fits best to the given layers. This function also gets a
+ // boolean flag that indicates whether user touched the screen recently to be factored in when
+ // choosing the refresh rate.
+ const RefreshRate& getRefreshRateForContentV2(const std::vector<LayerRequirement>& layers,
+ bool touchActive) const EXCLUDES(mLock);
// Returns all the refresh rates supported by the device. This won't change at runtime.
const AllRefreshRatesMapType& getAllRefreshRates() const EXCLUDES(mLock);
@@ -188,6 +195,10 @@
template <typename Iter>
const RefreshRate* getBestRefreshRate(Iter begin, Iter end) const;
+ // Returns number of display frames and remainder when dividing the layer refresh period by
+ // display refresh period.
+ std::pair<nsecs_t, nsecs_t> getDisplayFrames(nsecs_t layerPeriod, nsecs_t displayPeriod) const;
+
// The list of refresh rates, indexed by display config ID. This must not change after this
// object is initialized.
AllRefreshRatesMapType mRefreshRates;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 71ac90e..3a44332 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -439,7 +439,7 @@
return;
}
mFeatures.contentRequirements = summary;
- mFeatures.contentDetection =
+ mFeatures.contentDetectionV1 =
!summary.empty() ? ContentDetectionState::On : ContentDetectionState::Off;
newConfigId = calculateRefreshRateConfigIndexType();
@@ -466,7 +466,7 @@
// NOTE: Instead of checking all the layers, we should be checking the layer
// that is currently on top. b/142507166 will give us this capability.
std::lock_guard<std::mutex> lock(mFeatureStateLock);
- if (mLayerHistory && !layerHistoryHasClientSpecifiedFrameRate()) {
+ if (mLayerHistory) {
mLayerHistory->clear();
mTouchTimer->reset();
@@ -556,7 +556,7 @@
return;
}
mFeatures.configId = newConfigId;
- if (eventOnContentDetection && mFeatures.contentDetection == ContentDetectionState::On) {
+ if (eventOnContentDetection && !mFeatures.contentRequirements.empty()) {
event = ConfigEvent::Changed;
}
}
@@ -564,33 +564,10 @@
mSchedulerCallback.changeRefreshRate(newRefreshRate, event);
}
-bool Scheduler::layerHistoryHasClientSpecifiedFrameRate() {
- // Traverse all the layers to see if any of them requested frame rate.
- for (const auto& layer : mFeatures.contentRequirements) {
- if (layer.vote == scheduler::RefreshRateConfigs::LayerVoteType::ExplicitDefault ||
- layer.vote == scheduler::RefreshRateConfigs::LayerVoteType::ExplicitExactOrMultiple) {
- return true;
- }
- }
-
- return false;
-}
-
HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType() {
- // This block of the code checks whether any layers used the SetFrameRate API. If they have,
- // their request should be honored depending on other active layers.
- if (layerHistoryHasClientSpecifiedFrameRate()) {
- if (!mUseContentDetectionV2) {
- return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements)
- .configId;
- } else {
- return mRefreshRateConfigs.getRefreshRateForContentV2(mFeatures.contentRequirements)
- .configId;
- }
- }
+ ATRACE_CALL();
- // If the layer history doesn't have the frame rate specified, check for other features and
- // honor them. NOTE: If we remove the kernel idle timer, and use our internal idle timer, this
+ // NOTE: If we remove the kernel idle timer, and use our internal idle timer, this
// code will have to be refactored. If Display Power is not in normal operation we want to be in
// performance mode. When coming back to normal mode, a grace period is given with
// DisplayPowerTimer.
@@ -600,9 +577,11 @@
return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
}
- // As long as touch is active we want to be in performance mode.
- if (mTouchTimer && mFeatures.touch == TouchState::Active) {
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ if (!mUseContentDetectionV2) {
+ // As long as touch is active we want to be in performance mode.
+ if (mTouchTimer && mFeatures.touch == TouchState::Active) {
+ return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ }
}
// If timer has expired as it means there is no new content on the screen.
@@ -612,7 +591,7 @@
if (!mUseContentDetectionV2) {
// If content detection is off we choose performance as we don't know the content fps.
- if (mFeatures.contentDetection == ContentDetectionState::Off) {
+ if (mFeatures.contentDetectionV1 == ContentDetectionState::Off) {
// NOTE: V1 always calls this, but this is not a default behavior for V2.
return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
}
@@ -621,14 +600,10 @@
return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements).configId;
}
- // Content detection is on, find the appropriate refresh rate with minimal error
- if (mFeatures.contentDetection == ContentDetectionState::On) {
- return mRefreshRateConfigs.getRefreshRateForContentV2(mFeatures.contentRequirements)
- .configId;
- }
-
- // There are no signals for refresh rate, just leave it as is.
- return mRefreshRateConfigs.getCurrentRefreshRateByPolicy().configId;
+ return mRefreshRateConfigs
+ .getRefreshRateForContentV2(mFeatures.contentRequirements,
+ mTouchTimer && mFeatures.touch == TouchState::Active)
+ .configId;
}
std::optional<HwcConfigIndexType> Scheduler::getPreferredConfigId() {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 81051be..46d1a5e 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -185,8 +185,6 @@
// for the suggested refresh rate.
HwcConfigIndexType calculateRefreshRateConfigIndexType() REQUIRES(mFeatureStateLock);
- bool layerHistoryHasClientSpecifiedFrameRate() REQUIRES(mFeatureStateLock);
-
// Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
struct Connection {
sp<EventThreadConnection> connection;
@@ -229,7 +227,7 @@
std::mutex mFeatureStateLock;
struct {
- ContentDetectionState contentDetection = ContentDetectionState::Off;
+ ContentDetectionState contentDetectionV1 = ContentDetectionState::Off;
TimerState idleTimer = TimerState::Reset;
TouchState touch = TouchState::Inactive;
TimerState displayPowerTimer = TimerState::Expired;
diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
index dbace11..2fd2579 100644
--- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
@@ -92,7 +92,8 @@
.setRelativeLayer(layerG, layerR->getHandle(), 1)
.apply();
- layerG.clear();
+ Transaction().reparent(layerG, nullptr).apply();
+
// layerG should have been removed
getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
}
diff --git a/services/surfaceflinger/tests/LayerUpdate_test.cpp b/services/surfaceflinger/tests/LayerUpdate_test.cpp
index cf3f8e8..cdd9d92 100644
--- a/services/surfaceflinger/tests/LayerUpdate_test.cpp
+++ b/services/surfaceflinger/tests/LayerUpdate_test.cpp
@@ -542,6 +542,7 @@
mCapture->checkPixel(64, 64, 111, 111, 111);
}
+ Transaction().reparent(mChild, nullptr).apply();
mChild.clear();
{
@@ -1702,6 +1703,7 @@
ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
auto redLayerHandle = redLayer->getHandle();
+ Transaction().reparent(redLayer, nullptr).apply();
redLayer.clear();
SurfaceComposerClient::Transaction().apply(true);
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 99c5f3d..7e62513 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -247,7 +247,7 @@
refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_60_90) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_60_90) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
{HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
@@ -261,100 +261,136 @@
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "Min";
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.vote = LayerVoteType::Max;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "Max";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 90.0f;
lr.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "90Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "60Hz Heuristic";
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "45Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 30.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "30Hz Heuristic";
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "24Hz Heuristic";
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+ lr.name = "";
ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 60, 60, nullptr), 0);
lr.vote = LayerVoteType::Min;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.vote = LayerVoteType::Max;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 90.0f;
lr.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 30.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_90, 90, 90, nullptr), 0);
lr.vote = LayerVoteType::Min;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.vote = LayerVoteType::Max;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 90.0f;
lr.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 30.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 0, 120, nullptr), 0);
lr.vote = LayerVoteType::Min;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.vote = LayerVoteType::Max;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 90.0f;
lr.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 30.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_60_72_90) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_60_72_90) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
{HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
@@ -370,29 +406,36 @@
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.vote = LayerVoteType::Max;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 90.0f;
lr.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 30.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected72Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_30_60_72_90_120) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_72_90_120) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
@@ -417,23 +460,25 @@
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60.0f;
lr2.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected120Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected120Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 48.0f;
lr2.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected72Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 48.0f;
lr2.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected72Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
}
-TEST_F(RefreshRateConfigsTest,
- twoDeviceConfigs_getRefreshRateForContentV2_30_60_90_120_DifferentTypes) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_90_120_DifferentTypes) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
@@ -456,54 +501,87 @@
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::ExplicitDefault;
+ lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 60.0f;
lr2.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected120Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "60Hz Heuristic";
+ EXPECT_EQ(expected120Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 60.0f;
lr2.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected120Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "60Hz Heuristic";
+ EXPECT_EQ(expected120Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 60.0f;
lr2.vote = LayerVoteType::ExplicitDefault;
- EXPECT_EQ(expected120Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "60Hz ExplicitDefault";
+ EXPECT_EQ(expected120Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90.0f;
lr2.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected120Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "90Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+
+ lr1.desiredRefreshRate = 24.0f;
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.name = "24Hz ExplicitExactOrMultiple";
+ lr2.desiredRefreshRate = 90.0f;
+ lr2.vote = LayerVoteType::ExplicitDefault;
+ lr2.name = "90Hz Heuristic";
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::ExplicitDefault;
+ lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 90.0f;
lr2.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected120Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "90Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::Heuristic;
+ lr1.name = "24Hz Heuristic";
lr2.desiredRefreshRate = 90.0f;
lr2.vote = LayerVoteType::ExplicitDefault;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "90Hz ExplicitDefault";
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90.0f;
lr2.vote = LayerVoteType::ExplicitDefault;
- EXPECT_EQ(expected120Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "90Hz ExplicitDefault";
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.desiredRefreshRate = 24.0f;
lr1.vote = LayerVoteType::ExplicitDefault;
+ lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 90.0f;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "90Hz ExplicitExactOrMultiple";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_30_60) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30}}};
@@ -517,29 +595,36 @@
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
- EXPECT_EQ(expected30Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected30Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.vote = LayerVoteType::Max;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 90.0f;
lr.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 30.0f;
- EXPECT_EQ(expected30Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected30Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_30_60_72_90) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_72_90) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
@@ -557,29 +642,59 @@
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
- EXPECT_EQ(expected30Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "Min";
+ EXPECT_EQ(expected30Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.vote = LayerVoteType::Max;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "Max";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 90.0f;
lr.vote = LayerVoteType::Heuristic;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "90Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "60Hz Heuristic";
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true));
lr.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "45Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true));
lr.desiredRefreshRate = 30.0f;
- EXPECT_EQ(expected30Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "30Hz Heuristic";
+ EXPECT_EQ(expected30Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true));
lr.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected72Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr.name = "24Hz Heuristic";
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true));
+
+ lr.desiredRefreshRate = 24.0f;
+ lr.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr.name = "24Hz ExplicitExactOrMultiple";
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_PriorityTest) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_PriorityTest) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
@@ -598,42 +713,49 @@
lr1.vote = LayerVoteType::Min;
lr2.vote = LayerVoteType::Max;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::Min;
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::Min;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 24.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::Max;
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::Max;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 15.0f;
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 30.0f;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 45.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_24FpsVideo) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_24FpsVideo) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
{HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
@@ -650,7 +772,8 @@
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) {
lr.desiredRefreshRate = fps;
- const auto& refreshRate = refreshRateConfigs->getRefreshRateForContentV2(layers);
+ const auto& refreshRate =
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false);
printf("%.2fHz chooses %s\n", fps, refreshRate.name.c_str());
EXPECT_EQ(expected60Config, refreshRate);
}
@@ -703,13 +826,22 @@
lr1.desiredRefreshRate = 60.0f;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 90.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+
+ lr1.vote = LayerVoteType::ExplicitDefault;
+ lr1.desiredRefreshRate = 90.0f;
+ lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr2.desiredRefreshRate = 60.0f;
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 90.0f;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 60.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
}
TEST_F(RefreshRateConfigsTest, testInPolicy) {
@@ -722,7 +854,7 @@
ASSERT_FALSE(expectedDefaultConfig.inPolicy(50.0f, 59.998f));
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_75HzContent) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_75HzContent) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
{HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
@@ -739,13 +871,14 @@
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
for (float fps = 75.0f; fps < 100.0f; fps += 0.1f) {
lr.desiredRefreshRate = fps;
- const auto& refreshRate = refreshRateConfigs->getRefreshRateForContentV2(layers);
+ const auto& refreshRate =
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false);
printf("%.2fHz chooses %s\n", fps, refreshRate.name.c_str());
EXPECT_EQ(expected90Config, refreshRate);
}
}
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_Multiples) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_Multiples) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
{HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
@@ -762,25 +895,99 @@
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 90.0f;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "90Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr2.vote = LayerVoteType::ExplicitDefault;
+ lr2.desiredRefreshRate = 90.0f;
+ lr2.name = "90Hz ExplicitDefault";
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
- EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "Max";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 30.0f;
+ lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 90.0f;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "90Hz Heuristic";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 30.0f;
+ lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
- EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+ lr2.name = "Max";
+ EXPECT_EQ(expected90Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false));
+}
+
+TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+ RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
+ RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+
+ auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
+ LayerRequirement{.weight = 1.0f}};
+ auto& lr1 = layers[0];
+ auto& lr2 = layers[1];
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr2.vote = LayerVoteType::NoVote;
+ lr2.name = "NoVote";
+ EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers, false));
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr2.vote = LayerVoteType::NoVote;
+ lr2.name = "NoVote";
+ EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers, true));
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr2.vote = LayerVoteType::Max;
+ lr2.name = "Max";
+ EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers, true));
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr2.vote = LayerVoteType::Max;
+ lr2.name = "Max";
+ EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers, false));
+
+ // The other layer starts to provide buffers
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr2.vote = LayerVoteType::Heuristic;
+ lr2.desiredRefreshRate = 90.0f;
+ lr2.name = "90Hz Heuristic";
+ EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers, false));
}
} // namespace
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index 7e988a1..aae72db 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -124,8 +124,7 @@
};
void AddImplicitLayers() {
- if (!is_instance_ ||
- !android::GraphicsEnv::getInstance().isDebuggable())
+ if (!is_instance_)
return;
GetLayersFromSettings();