Merge "Delete TouchState::source" into udc-qpr-dev
diff --git a/data/etc/input/Android.bp b/data/etc/input/Android.bp
index 90f3c6b..b662491 100644
--- a/data/etc/input/Android.bp
+++ b/data/etc/input/Android.bp
@@ -3,12 +3,21 @@
}
filegroup {
- name: "motion_predictor_model.fb",
- srcs: ["motion_predictor_model.fb"],
+ name: "motion_predictor_model",
+ srcs: [
+ "motion_predictor_model.tflite",
+ "motion_predictor_config.xml",
+ ],
}
prebuilt_etc {
name: "motion_predictor_model_prebuilt",
filename_from_src: true,
- src: "motion_predictor_model.fb",
+ src: "motion_predictor_model.tflite",
+}
+
+prebuilt_etc {
+ name: "motion_predictor_model_config",
+ filename_from_src: true,
+ src: "motion_predictor_config.xml",
}
diff --git a/data/etc/input/motion_predictor_config.xml b/data/etc/input/motion_predictor_config.xml
new file mode 100644
index 0000000..03dfd63
--- /dev/null
+++ b/data/etc/input/motion_predictor_config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<motion-predictor>
+ <!-- The time interval (ns) between the model's predictions. -->
+ <prediction-interval>4166666</prediction-interval> <!-- 4.167 ms = ~240 Hz -->
+</motion-predictor>
+
diff --git a/data/etc/input/motion_predictor_model.fb b/data/etc/input/motion_predictor_model.tflite
similarity index 100%
rename from data/etc/input/motion_predictor_model.fb
rename to data/etc/input/motion_predictor_model.tflite
Binary files differ
diff --git a/include/input/MotionPredictor.h b/include/input/MotionPredictor.h
index de8ddca..8797962 100644
--- a/include/input/MotionPredictor.h
+++ b/include/input/MotionPredictor.h
@@ -26,7 +26,9 @@
#include <android-base/thread_annotations.h>
#include <android/sysprop/InputProperties.sysprop.h>
#include <input/Input.h>
+#include <input/MotionPredictorMetricsManager.h>
#include <input/TfLiteMotionPredictor.h>
+#include <utils/Timers.h> // for nsecs_t
namespace android {
@@ -69,6 +71,7 @@
*/
MotionPredictor(nsecs_t predictionTimestampOffsetNanos,
std::function<bool()> checkEnableMotionPrediction = isMotionPredictionEnabled);
+
/**
* Record the actual motion received by the view. This event will be used for calculating the
* predictions.
@@ -77,7 +80,9 @@
* consistent with the previously recorded events.
*/
android::base::Result<void> record(const MotionEvent& event);
+
std::unique_ptr<MotionEvent> predict(nsecs_t timestamp);
+
bool isPredictionAvailable(int32_t deviceId, int32_t source);
private:
@@ -88,6 +93,8 @@
std::unique_ptr<TfLiteMotionPredictorBuffers> mBuffers;
std::optional<MotionEvent> mLastEvent;
+
+ std::optional<MotionPredictorMetricsManager> mMetricsManager;
};
} // namespace android
diff --git a/include/input/MotionPredictorMetricsManager.h b/include/input/MotionPredictorMetricsManager.h
new file mode 100644
index 0000000..6284f07
--- /dev/null
+++ b/include/input/MotionPredictorMetricsManager.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/Timers.h>
+
+namespace android {
+
+/**
+ * Class to handle computing and reporting metrics for MotionPredictor.
+ *
+ * Currently an empty implementation, containing only the API.
+ */
+class MotionPredictorMetricsManager {
+public:
+ // Note: the MetricsManager assumes that the input interval equals the prediction interval.
+ MotionPredictorMetricsManager(nsecs_t /*predictionInterval*/, size_t /*maxNumPredictions*/) {}
+
+ void onRecord(const MotionEvent& /*inputEvent*/) {}
+
+ void onPredict(const MotionEvent& /*predictionEvent*/) {}
+};
+
+} // namespace android
diff --git a/include/input/TfLiteMotionPredictor.h b/include/input/TfLiteMotionPredictor.h
index a340bd0..fbd6026 100644
--- a/include/input/TfLiteMotionPredictor.h
+++ b/include/input/TfLiteMotionPredictor.h
@@ -25,6 +25,7 @@
#include <android-base/mapped_file.h>
#include <input/RingBuffer.h>
+#include <utils/Timers.h>
#include <tensorflow/lite/core/api/error_reporter.h>
#include <tensorflow/lite/interpreter.h>
@@ -109,6 +110,9 @@
// Returns the length of the model's output buffers.
size_t outputLength() const;
+ // Returns the time interval between predictions.
+ nsecs_t predictionInterval() const { return mPredictionInterval; }
+
// Executes the model.
// Returns true if the model successfully executed and the output tensors can be read.
bool invoke();
@@ -127,7 +131,8 @@
std::span<const float> outputPressure() const;
private:
- explicit TfLiteMotionPredictorModel(std::unique_ptr<android::base::MappedFile> model);
+ explicit TfLiteMotionPredictorModel(std::unique_ptr<android::base::MappedFile> model,
+ nsecs_t predictionInterval);
void allocateTensors();
void attachInputTensors();
@@ -148,6 +153,8 @@
std::unique_ptr<tflite::FlatBufferModel> mModel;
std::unique_ptr<tflite::Interpreter> mInterpreter;
tflite::SignatureRunner* mRunner = nullptr;
+
+ const nsecs_t mPredictionInterval = 0;
};
} // namespace android
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 582437f..80ac2a9 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -399,45 +399,37 @@
return false;
}
- return (mShouldUseAngle == YES) ? true : false;
+ return mShouldUseAngle;
}
-void GraphicsEnv::updateShouldUseAngle() {
- const char* ANGLE_PREFER_ANGLE = "angle";
- const char* ANGLE_PREFER_NATIVE = "native";
-
- mShouldUseAngle = NO;
- if (mAngleDeveloperOptIn == ANGLE_PREFER_ANGLE) {
- ALOGV("User set \"Developer Options\" to force the use of ANGLE");
- mShouldUseAngle = YES;
- } else if (mAngleDeveloperOptIn == ANGLE_PREFER_NATIVE) {
- ALOGV("User set \"Developer Options\" to force the use of Native");
- } else {
- ALOGV("User set invalid \"Developer Options\": '%s'", mAngleDeveloperOptIn.c_str());
- }
-}
-
-void GraphicsEnv::setAngleInfo(const std::string& path, const std::string& packageName,
- const std::string& developerOptIn,
+// Set ANGLE information.
+// If path is "system", it means system ANGLE must be used for the process.
+// If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process.
+// If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless.
+void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNativeDriver,
+ const std::string& packageName,
const std::vector<std::string> eglFeatures) {
- if (mShouldUseAngle != UNKNOWN) {
- // We've already figured out an answer for this app, so just return.
- ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", packageName.c_str(),
- (mShouldUseAngle == YES) ? "true" : "false");
+ if (mShouldUseAngle) {
+ // ANGLE is already set up for this application process, even if the application
+ // needs to switch from apk to system or vice versa, the application process must
+ // be killed and relaunch so that the loader can properly load ANGLE again.
+ // The architecture does not support runtime switch between drivers, so just return.
+ ALOGE("ANGLE is already set for %s", packageName.c_str());
return;
}
mAngleEglFeatures = std::move(eglFeatures);
-
ALOGV("setting ANGLE path to '%s'", path.c_str());
- mAnglePath = path;
+ mAnglePath = std::move(path);
ALOGV("setting app package name to '%s'", packageName.c_str());
- mPackageName = packageName;
- ALOGV("setting ANGLE application opt-in to '%s'", developerOptIn.c_str());
- mAngleDeveloperOptIn = developerOptIn;
-
- // Update the current status of whether we should use ANGLE or not
- updateShouldUseAngle();
+ mPackageName = std::move(packageName);
+ if (path == "system") {
+ mShouldUseSystemAngle = true;
+ }
+ if (!path.empty()) {
+ mShouldUseAngle = true;
+ }
+ mShouldUseNativeDriver = shouldUseNativeDriver;
}
void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace,
@@ -484,13 +476,15 @@
}
// Return true if all the required libraries from vndk and sphal namespace are
-// linked to the updatable gfx driver namespace correctly.
-bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* vndkNamespace) {
+// linked to the driver namespace correctly.
+bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* destNamespace,
+ android_namespace_t* vndkNamespace,
+ const std::string& sharedSphalLibraries) {
const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK);
if (llndkLibraries.empty()) {
return false;
}
- if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) {
+ if (!android_link_namespaces(destNamespace, nullptr, llndkLibraries.c_str())) {
ALOGE("Failed to link default namespace[%s]", dlerror());
return false;
}
@@ -499,12 +493,12 @@
if (vndkspLibraries.empty()) {
return false;
}
- if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) {
+ if (!android_link_namespaces(destNamespace, vndkNamespace, vndkspLibraries.c_str())) {
ALOGE("Failed to link vndk namespace[%s]", dlerror());
return false;
}
- if (mSphalLibraries.empty()) {
+ if (sharedSphalLibraries.empty()) {
return true;
}
@@ -512,11 +506,11 @@
auto sphalNamespace = android_get_exported_namespace("sphal");
if (!sphalNamespace) {
ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace",
- mSphalLibraries.c_str());
+ sharedSphalLibraries.c_str());
return false;
}
- if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) {
+ if (!android_link_namespaces(destNamespace, sphalNamespace, sharedSphalLibraries.c_str())) {
ALOGE("Failed to link sphal namespace[%s]", dlerror());
return false;
}
@@ -561,14 +555,14 @@
return nullptr;
}
- mDriverNamespace = android_create_namespace("gfx driver",
+ mDriverNamespace = android_create_namespace("updatable gfx driver",
mDriverPath.c_str(), // ld_library_path
mDriverPath.c_str(), // default_library_path
ANDROID_NAMESPACE_TYPE_ISOLATED,
nullptr, // permitted_when_isolated_path
nullptr);
- if (!linkDriverNamespaceLocked(vndkNamespace)) {
+ if (!linkDriverNamespaceLocked(mDriverNamespace, vndkNamespace, mSphalLibraries)) {
mDriverNamespace = nullptr;
}
@@ -586,20 +580,49 @@
return mAngleNamespace;
}
- if (mAnglePath.empty()) {
- ALOGV("mAnglePath is empty, not creating ANGLE namespace");
+ if (mAnglePath.empty() && !mShouldUseSystemAngle) {
+ ALOGV("mAnglePath is empty and not using system ANGLE, abort creating ANGLE namespace");
return nullptr;
}
- mAngleNamespace = android_create_namespace("ANGLE",
- nullptr, // ld_library_path
- mAnglePath.c_str(), // default_library_path
- ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED,
- nullptr, // permitted_when_isolated_path
- nullptr);
+ // Construct the search paths for system ANGLE.
+ const char* const defaultLibraryPaths =
+#if defined(__LP64__)
+ "/vendor/lib64/egl:/system/lib64/egl";
+#else
+ "/vendor/lib/egl:/system/lib/egl";
+#endif
+
+ // If the application process will run on top of system ANGLE, construct the namespace
+ // with sphal namespace being the parent namespace so that search paths and libraries
+ // are properly inherited.
+ mAngleNamespace =
+ android_create_namespace("ANGLE",
+ mShouldUseSystemAngle ? defaultLibraryPaths
+ : mAnglePath.c_str(), // ld_library_path
+ mShouldUseSystemAngle
+ ? defaultLibraryPaths
+ : mAnglePath.c_str(), // default_library_path
+ ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED,
+ nullptr, // permitted_when_isolated_path
+ mShouldUseSystemAngle ? android_get_exported_namespace("sphal")
+ : nullptr); // parent
ALOGD_IF(!mAngleNamespace, "Could not create ANGLE namespace from default");
+ if (!mShouldUseSystemAngle) {
+ return mAngleNamespace;
+ }
+
+ auto vndkNamespace = android_get_exported_namespace("vndk");
+ if (!vndkNamespace) {
+ return nullptr;
+ }
+
+ if (!linkDriverNamespaceLocked(mAngleNamespace, vndkNamespace, "")) {
+ mAngleNamespace = nullptr;
+ }
+
return mAngleNamespace;
}
@@ -612,4 +635,12 @@
gpuService->toggleAngleAsSystemDriver(enabled);
}
+bool GraphicsEnv::shouldUseSystemAngle() {
+ return mShouldUseSystemAngle;
+}
+
+bool GraphicsEnv::shouldUseNativeDriver() {
+ return mShouldUseNativeDriver;
+}
+
} // namespace android
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index a1b5e50..6cce3f6 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -29,6 +29,11 @@
struct NativeLoaderNamespace;
+// The GraphicsEnv is a singleton per application process and is used to properly set up the
+// graphics drivers for the application process during application starts. The architecture of
+// the graphics driver loader does not support runtime switch and only supports switch to different
+// graphics drivers when application process launches and hence the only way to switch to different
+// graphics drivers is to completely kill the application process and relaunch the application.
class GraphicsEnv {
public:
static GraphicsEnv& getInstance();
@@ -103,8 +108,11 @@
// (libraries must be stored uncompressed and page aligned); such elements
// in the search path must have a '!' after the zip filename, e.g.
// /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
- void setAngleInfo(const std::string& path, const std::string& packageName,
- const std::string& devOptIn, const std::vector<std::string> eglFeatures);
+ // If the search patch is "system", then it means the system ANGLE should be used.
+ // If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process.
+ // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless.
+ void setAngleInfo(const std::string& path, const bool shouldUseNativeDriver,
+ const std::string& packageName, const std::vector<std::string> eglFeatures);
// Get the ANGLE driver namespace.
android_namespace_t* getAngleNamespace();
// Get the app package name.
@@ -112,6 +120,8 @@
const std::vector<std::string>& getAngleEglFeatures();
// Set the persist.graphics.egl system property value.
void nativeToggleAngleAsSystemDriver(bool enabled);
+ bool shouldUseSystemAngle();
+ bool shouldUseNativeDriver();
/*
* Apis for debug layer
@@ -132,12 +142,10 @@
const std::string& getDebugLayersGLES();
private:
- enum UseAngle { UNKNOWN, YES, NO };
-
- // Update whether ANGLE should be used.
- void updateShouldUseAngle();
// Link updatable driver namespace with llndk and vndk-sp libs.
- bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace);
+ bool linkDriverNamespaceLocked(android_namespace_t* destNamespace,
+ android_namespace_t* vndkNamespace,
+ const std::string& sharedSphalLibraries);
// Check whether this process is ready to send stats.
bool readyToSendGpuStatsLocked();
// Send the initial complete GpuStats to GpuService.
@@ -165,12 +173,14 @@
std::string mAnglePath;
// App's package name.
std::string mPackageName;
- // ANGLE developer opt in status.
- std::string mAngleDeveloperOptIn;
// ANGLE EGL features;
std::vector<std::string> mAngleEglFeatures;
- // Use ANGLE flag.
- UseAngle mShouldUseAngle = UNKNOWN;
+ // Whether ANGLE should be used.
+ bool mShouldUseAngle = false;
+ // Whether loader should load system ANGLE.
+ bool mShouldUseSystemAngle = false;
+ // Whether loader should load native GLES driver.
+ bool mShouldUseNativeDriver = false;
// ANGLE namespace.
android_namespace_t* mAngleNamespace = nullptr;
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 9ac1829..8a17d8a 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -215,6 +215,7 @@
"libcutils",
"liblog",
"libPlatformProperties",
+ "libtinyxml2",
"libvintf",
],
@@ -271,6 +272,7 @@
required: [
"motion_predictor_model_prebuilt",
+ "motion_predictor_model_config",
],
},
host: {
diff --git a/libs/input/MotionPredictor.cpp b/libs/input/MotionPredictor.cpp
index 3037573..68e6888 100644
--- a/libs/input/MotionPredictor.cpp
+++ b/libs/input/MotionPredictor.cpp
@@ -36,9 +36,6 @@
namespace android {
namespace {
-const int64_t PREDICTION_INTERVAL_NANOS =
- 12500000 / 3; // TODO(b/266747937): Get this from the model.
-
/**
* Log debug messages about predictions.
* Enable this via "adb shell setprop log.tag.MotionPredictor DEBUG"
@@ -70,7 +67,7 @@
android::base::Result<void> MotionPredictor::record(const MotionEvent& event) {
if (mLastEvent && mLastEvent->getDeviceId() != event.getDeviceId()) {
// We still have an active gesture for another device. The provided MotionEvent is not
- // consistent the previous gesture.
+ // consistent with the previous gesture.
LOG(ERROR) << "Inconsistent event stream: last event is " << *mLastEvent << ", but "
<< __func__ << " is called with " << event;
return android::base::Error()
@@ -86,9 +83,10 @@
// Initialise the model now that it's likely to be used.
if (!mModel) {
mModel = TfLiteMotionPredictorModel::create();
+ LOG_ALWAYS_FATAL_IF(!mModel);
}
- if (mBuffers == nullptr) {
+ if (!mBuffers) {
mBuffers = std::make_unique<TfLiteMotionPredictorBuffers>(mModel->inputLength());
}
@@ -136,6 +134,15 @@
mLastEvent = MotionEvent();
}
mLastEvent->copyFrom(&event, /*keepHistory=*/false);
+
+ // Pass input event to the MetricsManager.
+ if (!mMetricsManager) {
+ mMetricsManager =
+ std::make_optional<MotionPredictorMetricsManager>(mModel->predictionInterval(),
+ mModel->outputLength());
+ }
+ mMetricsManager->onRecord(event);
+
return {};
}
@@ -177,19 +184,20 @@
const int64_t futureTime = timestamp + mPredictionTimestampOffsetNanos;
for (int i = 0; i < predictedR.size() && predictionTime <= futureTime; ++i) {
- const TfLiteMotionPredictorSample::Point point =
- convertPrediction(axisFrom, axisTo, predictedR[i], predictedPhi[i]);
- // TODO(b/266747654): Stop predictions if confidence is < some threshold.
+ // TODO(b/266747654): Stop predictions if confidence and/or predicted pressure are below
+ // some thresholds.
- ALOGD_IF(isDebug(), "prediction %d: %f, %f", i, point.x, point.y);
+ const TfLiteMotionPredictorSample::Point predictedPoint =
+ convertPrediction(axisFrom, axisTo, predictedR[i], predictedPhi[i]);
+
+ ALOGD_IF(isDebug(), "prediction %d: %f, %f", i, predictedPoint.x, predictedPoint.y);
PointerCoords coords;
coords.clear();
- coords.setAxisValue(AMOTION_EVENT_AXIS_X, point.x);
- coords.setAxisValue(AMOTION_EVENT_AXIS_Y, point.y);
- // TODO(b/266747654): Stop predictions if predicted pressure is < some threshold.
+ coords.setAxisValue(AMOTION_EVENT_AXIS_X, predictedPoint.x);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_Y, predictedPoint.y);
coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, predictedPressure[i]);
- predictionTime += PREDICTION_INTERVAL_NANOS;
+ predictionTime += mModel->predictionInterval();
if (i == 0) {
hasPredictions = true;
prediction->initialize(InputEvent::nextId(), event.getDeviceId(), event.getSource(),
@@ -206,12 +214,17 @@
}
axisFrom = axisTo;
- axisTo = point;
+ axisTo = predictedPoint;
}
- // TODO(b/266747511): Interpolate to futureTime?
+
if (!hasPredictions) {
return nullptr;
}
+
+ // Pass predictions to the MetricsManager.
+ LOG_ALWAYS_FATAL_IF(!mMetricsManager);
+ mMetricsManager->onPredict(*prediction);
+
return prediction;
}
diff --git a/libs/input/TfLiteMotionPredictor.cpp b/libs/input/TfLiteMotionPredictor.cpp
index 85fa176..9f4aaa8 100644
--- a/libs/input/TfLiteMotionPredictor.cpp
+++ b/libs/input/TfLiteMotionPredictor.cpp
@@ -36,6 +36,7 @@
#define ATRACE_TAG ATRACE_TAG_INPUT
#include <cutils/trace.h>
#include <log/log.h>
+#include <utils/Timers.h>
#include "tensorflow/lite/core/api/error_reporter.h"
#include "tensorflow/lite/core/api/op_resolver.h"
@@ -44,6 +45,8 @@
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/mutable_op_resolver.h"
+#include "tinyxml2.h"
+
namespace android {
namespace {
@@ -72,16 +75,31 @@
std::string getModelPath() {
#if defined(__ANDROID__)
- static const char* oemModel = "/vendor/etc/motion_predictor_model.fb";
+ static const char* oemModel = "/vendor/etc/motion_predictor_model.tflite";
if (fileExists(oemModel)) {
return oemModel;
}
- return "/system/etc/motion_predictor_model.fb";
+ return "/system/etc/motion_predictor_model.tflite";
#else
- return base::GetExecutableDirectory() + "/motion_predictor_model.fb";
+ return base::GetExecutableDirectory() + "/motion_predictor_model.tflite";
#endif
}
+std::string getConfigPath() {
+ // The config file should be alongside the model file.
+ return base::Dirname(getModelPath()) + "/motion_predictor_config.xml";
+}
+
+int64_t parseXMLInt64(const tinyxml2::XMLElement& configRoot, const char* elementName) {
+ const tinyxml2::XMLElement* element = configRoot.FirstChildElement(elementName);
+ LOG_ALWAYS_FATAL_IF(!element, "Could not find '%s' element", elementName);
+
+ int64_t value = 0;
+ LOG_ALWAYS_FATAL_IF(element->QueryInt64Text(&value) != tinyxml2::XML_SUCCESS,
+ "Failed to parse %s: %s", elementName, element->GetText());
+ return value;
+}
+
// A TFLite ErrorReporter that logs to logcat.
class LoggingErrorReporter : public tflite::ErrorReporter {
public:
@@ -246,13 +264,23 @@
PLOG(FATAL) << "Failed to mmap model";
}
+ const std::string configPath = getConfigPath();
+ tinyxml2::XMLDocument configDocument;
+ LOG_ALWAYS_FATAL_IF(configDocument.LoadFile(configPath.c_str()) != tinyxml2::XML_SUCCESS,
+ "Failed to load config file from %s", configPath.c_str());
+
+ // Parse configuration file.
+ const tinyxml2::XMLElement* configRoot = configDocument.FirstChildElement("motion-predictor");
+ LOG_ALWAYS_FATAL_IF(!configRoot);
+ const nsecs_t predictionInterval = parseXMLInt64(*configRoot, "prediction-interval");
+
return std::unique_ptr<TfLiteMotionPredictorModel>(
- new TfLiteMotionPredictorModel(std::move(modelBuffer)));
+ new TfLiteMotionPredictorModel(std::move(modelBuffer), predictionInterval));
}
TfLiteMotionPredictorModel::TfLiteMotionPredictorModel(
- std::unique_ptr<android::base::MappedFile> model)
- : mFlatBuffer(std::move(model)) {
+ std::unique_ptr<android::base::MappedFile> model, nsecs_t predictionInterval)
+ : mFlatBuffer(std::move(model)), mPredictionInterval(predictionInterval) {
CHECK(mFlatBuffer);
mErrorReporter = std::make_unique<LoggingErrorReporter>();
mModel = tflite::FlatBufferModel::VerifyAndBuildFromBuffer(mFlatBuffer->data(),
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index 6aae25d..cadac88 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -64,12 +64,13 @@
"libcutils",
"liblog",
"libPlatformProperties",
+ "libtinyxml2",
"libutils",
"libvintf",
],
data: [
"data/*",
- ":motion_predictor_model.fb",
+ ":motion_predictor_model",
],
test_options: {
unit_test: true,
diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.cpp b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
index b99e385..c16586b 100644
--- a/libs/renderengine/skia/SkiaVkRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
@@ -263,7 +263,7 @@
VK_GET_INST_PROC(instance, EnumerateDeviceExtensionProperties);
VK_GET_INST_PROC(instance, GetPhysicalDeviceProperties2);
VK_GET_INST_PROC(instance, GetPhysicalDeviceExternalSemaphoreProperties);
- VK_GET_INST_PROC(instance, GetPhysicalDeviceQueueFamilyProperties);
+ VK_GET_INST_PROC(instance, GetPhysicalDeviceQueueFamilyProperties2);
VK_GET_INST_PROC(instance, GetPhysicalDeviceFeatures2);
VK_GET_INST_PROC(instance, CreateDevice);
@@ -342,17 +342,37 @@
}
uint32_t queueCount;
- vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, nullptr);
+ vkGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueCount, nullptr);
if (queueCount == 0) {
BAIL("Could not find queues for physical device");
}
- std::vector<VkQueueFamilyProperties> queueProps(queueCount);
- vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, queueProps.data());
+ std::vector<VkQueueFamilyProperties2> queueProps(queueCount);
+ std::vector<VkQueueFamilyGlobalPriorityPropertiesEXT> queuePriorityProps(queueCount);
+ VkQueueGlobalPriorityKHR queuePriority = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR;
+ // Even though we don't yet know if the VK_EXT_global_priority extension is available,
+ // we can safely add the request to the pNext chain, and if the extension is not
+ // available, it will be ignored.
+ for (uint32_t i = 0; i < queueCount; ++i) {
+ queuePriorityProps[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT;
+ queuePriorityProps[i].pNext = nullptr;
+ queueProps[i].pNext = &queuePriorityProps[i];
+ }
+ vkGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueCount, queueProps.data());
int graphicsQueueIndex = -1;
for (uint32_t i = 0; i < queueCount; ++i) {
- if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+ // Look at potential answers to the VK_EXT_global_priority query. If answers were
+ // provided, we may adjust the queuePriority.
+ if (queueProps[i].queueFamilyProperties.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+ for (uint32_t j = 0; j < queuePriorityProps[i].priorityCount; j++) {
+ if (queuePriorityProps[i].priorities[j] > queuePriority) {
+ queuePriority = queuePriorityProps[i].priorities[j];
+ }
+ }
+ if (queuePriority == VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR) {
+ interface.isRealtimePriority = true;
+ }
graphicsQueueIndex = i;
break;
}
@@ -419,12 +439,11 @@
VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,
nullptr,
// If queue priority is supported, RE should always have realtime priority.
- VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT,
+ queuePriority,
};
if (interface.grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
queueNextPtr = &queuePriorityCreateInfo;
- interface.isRealtimePriority = true;
}
VkDeviceQueueCreateFlags deviceQueueCreateFlags =
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index b4fc5f0..654e5b7 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -161,6 +161,16 @@
// Return true if ANGLE namespace is set.
android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
if (ns) {
+ // Unless the default GLES driver is ANGLE and the process should use system ANGLE, since
+ // the intended GLES driver is already loaded.
+ // This should be updated in a later patch that cleans up namespaces
+ if (!(cnx->angleLoaded && android::GraphicsEnv::getInstance().shouldUseSystemAngle())) {
+ return true;
+ }
+ }
+
+ // Return true if native GLES drivers should be used and ANGLE is already loaded.
+ if (android::GraphicsEnv::getInstance().shouldUseNativeDriver() && cnx->angleLoaded) {
return true;
}
@@ -206,17 +216,17 @@
do_android_unload_sphal_library(hnd->dso[0]);
}
cnx->dso = nullptr;
+ cnx->angleLoaded = false;
}
cnx->systemDriverUnloaded = true;
}
-void* Loader::open(egl_connection_t* cnx)
-{
+void* Loader::open(egl_connection_t* cnx) {
ATRACE_CALL();
const nsecs_t openTime = systemTime();
- if (should_unload_system_driver(cnx)) {
+ if (cnx->dso && should_unload_system_driver(cnx)) {
unload_system_driver(cnx);
}
@@ -225,22 +235,38 @@
return cnx->dso;
}
- // Firstly, try to load ANGLE driver.
- driver_t* hnd = attempt_to_load_angle(cnx);
+ driver_t* hnd = nullptr;
+ // Firstly, try to load ANGLE driver, if ANGLE should be loaded and fail, abort.
+ if (android::GraphicsEnv::getInstance().shouldUseAngle()) {
+ hnd = attempt_to_load_angle(cnx);
+ LOG_ALWAYS_FATAL_IF(!hnd, "Failed to load ANGLE.");
+ }
if (!hnd) {
// Secondly, try to load from driver apk.
hnd = attempt_to_load_updated_driver(cnx);
+
+ // If updated driver apk is set but fail to load, abort here.
+ LOG_ALWAYS_FATAL_IF(android::GraphicsEnv::getInstance().getDriverNamespace(),
+ "couldn't find an OpenGL ES implementation from %s",
+ android::GraphicsEnv::getInstance().getDriverPath().c_str());
}
+ // Attempt to load native GLES drivers specified by ro.hardware.egl if native is selected.
+ // If native is selected but fail to load, abort.
+ if (!hnd && android::GraphicsEnv::getInstance().shouldUseNativeDriver()) {
+ auto driverSuffix = base::GetProperty(RO_DRIVER_SUFFIX_PROPERTY, "");
+ LOG_ALWAYS_FATAL_IF(driverSuffix.empty(),
+ "Native GLES driver is selected but not specified in %s",
+ RO_DRIVER_SUFFIX_PROPERTY);
+ hnd = attempt_to_load_system_driver(cnx, driverSuffix.c_str(), true);
+ LOG_ALWAYS_FATAL_IF(!hnd, "Native GLES driver is selected but failed to load. %s=%s",
+ RO_DRIVER_SUFFIX_PROPERTY, driverSuffix.c_str());
+ }
+
+ // Finally, try to load default driver.
bool failToLoadFromDriverSuffixProperty = false;
if (!hnd) {
- // If updated driver apk is set but fail to load, abort here.
- if (android::GraphicsEnv::getInstance().getDriverNamespace()) {
- LOG_ALWAYS_FATAL("couldn't find an OpenGL ES implementation from %s",
- android::GraphicsEnv::getInstance().getDriverPath().c_str());
- }
- // Finally, try to load system driver.
// Start by searching for the library name appended by the system
// properties of the GLES userspace driver in both locations.
// i.e.:
@@ -541,10 +567,6 @@
Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
ATRACE_CALL();
- if (!android::GraphicsEnv::getInstance().shouldUseAngle()) {
- return nullptr;
- }
-
android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
if (!ns) {
return nullptr;
diff --git a/services/inputflinger/InputDeviceMetricsCollector.cpp b/services/inputflinger/InputDeviceMetricsCollector.cpp
index 999e175..89e37db 100644
--- a/services/inputflinger/InputDeviceMetricsCollector.cpp
+++ b/services/inputflinger/InputDeviceMetricsCollector.cpp
@@ -31,7 +31,7 @@
namespace {
-constexpr nanoseconds DEFAULT_USAGE_SESSION_TIMEOUT = std::chrono::minutes(2);
+constexpr nanoseconds DEFAULT_USAGE_SESSION_TIMEOUT = std::chrono::seconds(5);
/**
* Log debug messages about metrics events logged to statsd.
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 37b3187..1a9f47d 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -34,7 +34,7 @@
namespace android {
static const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
- sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
+ sysprop::InputProperties::enable_input_device_usage_metrics().value_or(false);
using gui::FocusRequest;
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index f0b1072..cdc4c08 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -49,15 +49,38 @@
"name": "CtsViewTestCases",
"options": [
{
- "include-filter": "android.view.cts.input",
- "include-filter": "android.view.cts.HoverTest",
- "include-filter": "android.view.cts.MotionEventTest",
- "include-filter": "android.view.cts.PointerCaptureTest",
- "include-filter": "android.view.cts.TooltipTest",
- "include-filter": "android.view.cts.TouchDelegateTest",
- "include-filter": "android.view.cts.VelocityTrackerTest",
- "include-filter": "android.view.cts.VerifyInputEventTest",
- "include-filter": "android.view.cts.ViewTest",
+ "include-filter": "android.view.cts.input"
+ }
+ ]
+ },
+ {
+ "name": "CtsViewTestCases",
+ "options": [
+ {
+ "include-filter": "android.view.cts.HoverTest"
+ },
+ {
+ "include-filter": "android.view.cts.MotionEventTest"
+ },
+ {
+ "include-filter": "android.view.cts.PointerCaptureTest"
+ },
+ {
+ "include-filter": "android.view.cts.TooltipTest"
+ },
+ {
+ "include-filter": "android.view.cts.TouchDelegateTest"
+ },
+ {
+ "include-filter": "android.view.cts.VelocityTrackerTest"
+ },
+ {
+ "include-filter": "android.view.cts.VerifyInputEventTest"
+ },
+ {
+ "include-filter": "android.view.cts.ViewTest"
+ },
+ {
"include-filter": "android.view.cts.ViewUnbufferedTest"
}
]
@@ -66,7 +89,9 @@
"name": "CtsWidgetTestCases",
"options": [
{
- "include-filter": "android.widget.cts.NumberPickerTest",
+ "include-filter": "android.widget.cts.NumberPickerTest"
+ },
+ {
"include-filter": "android.widget.cts.SeekBarTest"
}
]
@@ -75,8 +100,17 @@
"name": "FrameworksCoreTests",
"options": [
{
- "include-filter": "android.hardware.input",
- "include-filter": "android.view.VerifiedKeyEventTest",
+ "include-filter": "android.hardware.input"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksCoreTests",
+ "options": [
+ {
+ "include-filter": "android.view.VerifiedKeyEventTest"
+ },
+ {
"include-filter": "android.view.VerifiedMotionEventTest"
}
]
@@ -153,15 +187,38 @@
"name": "CtsViewTestCases",
"options": [
{
- "include-filter": "android.view.cts.input",
- "include-filter": "android.view.cts.HoverTest",
- "include-filter": "android.view.cts.MotionEventTest",
- "include-filter": "android.view.cts.PointerCaptureTest",
- "include-filter": "android.view.cts.TooltipTest",
- "include-filter": "android.view.cts.TouchDelegateTest",
- "include-filter": "android.view.cts.VelocityTrackerTest",
- "include-filter": "android.view.cts.VerifyInputEventTest",
- "include-filter": "android.view.cts.ViewTest",
+ "include-filter": "android.view.cts.input"
+ }
+ ]
+ },
+ {
+ "name": "CtsViewTestCases",
+ "options": [
+ {
+ "include-filter": "android.view.cts.HoverTest"
+ },
+ {
+ "include-filter": "android.view.cts.MotionEventTest"
+ },
+ {
+ "include-filter": "android.view.cts.PointerCaptureTest"
+ },
+ {
+ "include-filter": "android.view.cts.TooltipTest"
+ },
+ {
+ "include-filter": "android.view.cts.TouchDelegateTest"
+ },
+ {
+ "include-filter": "android.view.cts.VelocityTrackerTest"
+ },
+ {
+ "include-filter": "android.view.cts.VerifyInputEventTest"
+ },
+ {
+ "include-filter": "android.view.cts.ViewTest"
+ },
+ {
"include-filter": "android.view.cts.ViewUnbufferedTest"
}
]
@@ -170,7 +227,9 @@
"name": "CtsWidgetTestCases",
"options": [
{
- "include-filter": "android.widget.cts.NumberPickerTest",
+ "include-filter": "android.widget.cts.NumberPickerTest"
+ },
+ {
"include-filter": "android.widget.cts.SeekBarTest"
}
]
@@ -179,7 +238,9 @@
"name": "FrameworksCoreTests",
"options": [
{
- "include-filter": "android.view.VerifiedKeyEventTest",
+ "include-filter": "android.view.VerifiedKeyEventTest"
+ },
+ {
"include-filter": "android.view.VerifiedMotionEventTest"
}
]