Merge "Add bugreport section progress reporter"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index eb9079b..6f78141 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -43,8 +43,10 @@
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
#include <cutils/native_handle.h>
#include <cutils/properties.h>
+#include <hidl/ServiceManagement.h>
#include <openssl/sha.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
@@ -131,8 +133,6 @@
};
static const int NUM_OF_DUMPS = arraysize(kDumpstateBoardFiles);
-static const std::string kLsHalDebugPath = "/bugreports/dumpstate_lshal.txt";
-
static constexpr char PROPERTY_EXTRA_OPTIONS[] = "dumpstate.options";
static constexpr char PROPERTY_LAST_ID[] = "dumpstate.last_id";
static constexpr char PROPERTY_VERSION[] = "dumpstate.version";
@@ -1093,6 +1093,57 @@
}
}
+static void DumpHals() {
+ using android::sp;
+ using android::hidl::manager::V1_0::IServiceManager;
+ using android::hardware::defaultServiceManager;
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (sm == nullptr) {
+ MYLOGE("Could not retrieve hwservicemanager to dump hals.\n");
+ return;
+ }
+
+ auto ret = sm->list([&](const auto& interfaces) {
+ for (const std::string& interface : interfaces) {
+ std::string cleanName = interface;
+ std::replace_if(cleanName.begin(),
+ cleanName.end(),
+ [](char c) {
+ return !isalnum(c) &&
+ std::string("@-_:.").find(c) == std::string::npos;
+ }, '_');
+ const std::string path = kDumpstateBoardPath + "lshal_debug_" + cleanName;
+
+ {
+ auto fd = android::base::unique_fd(
+ TEMP_FAILURE_RETRY(open(path.c_str(),
+ O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
+ if (fd < 0) {
+ MYLOGE("Could not open %s to dump additional hal information.\n", path.c_str());
+ continue;
+ }
+ RunCommandToFd(fd,
+ "",
+ {"lshal", "debug", interface},
+ CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
+
+ bool empty = 0 == lseek(fd, 0, SEEK_END);
+ if (!empty) {
+ ds.AddZipEntry("lshal-debug/" + cleanName + ".txt", path);
+ }
+ }
+
+ unlink(path.c_str());
+ }
+ });
+
+ if (!ret.isOk()) {
+ MYLOGE("Could not list hals from hwservicemanager.\n");
+ }
+}
+
static void dumpstate() {
DurationReporter duration_reporter("DUMPSTATE");
@@ -1121,18 +1172,10 @@
RunCommand("LIBRANK", {"librank"}, CommandOptions::AS_ROOT);
if (ds.IsZipping()) {
- RunCommand(
- "HARDWARE HALS",
- {"lshal", std::string("--debug=") + kLsHalDebugPath},
- CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
-
- ds.AddZipEntry("lshal-debug.txt", kLsHalDebugPath);
-
- unlink(kLsHalDebugPath.c_str());
+ RunCommand("HARDWARE HALS", {"lshal"}, CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
+ DumpHals();
} else {
- RunCommand(
- "HARDWARE HALS", {"lshal", "--debug"},
- CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
+ RunCommand("HARDWARE HALS", {"lshal", "--debug"}, CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
}
RunCommand("PRINTENV", {"printenv"});
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 715bf8c..1053522 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -37,6 +37,7 @@
#include <unistd.h>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
@@ -71,6 +72,7 @@
static constexpr const char* kCpPath = "/system/bin/cp";
static constexpr const char* kXattrDefault = "user.default";
+static constexpr const char* kPropHasReserved = "vold.has_reserved";
static constexpr const int MIN_RESTRICTED_HOME_SDK_VERSION = 24; // > M
@@ -302,6 +304,9 @@
*/
static int prepare_app_quota(const std::unique_ptr<std::string>& uuid, const std::string& device,
uid_t uid) {
+ // Skip when reserved blocks are protecting us against abusive apps
+ if (android::base::GetBoolProperty(kPropHasReserved, false)) return 0;
+ // Skip when device no quotas present
if (device.empty()) return 0;
struct dqblk dq;
@@ -2417,14 +2422,18 @@
mQuotaReverseMounts[target] = source;
// ext4 only enables DQUOT_USAGE_ENABLED by default, so we
- // need to kick it again to enable DQUOT_LIMITS_ENABLED.
- if (quotactl(QCMD(Q_QUOTAON, USRQUOTA), source.c_str(), QFMT_VFS_V1, nullptr) != 0
- && errno != EBUSY) {
- PLOG(ERROR) << "Failed to enable USRQUOTA on " << source;
- }
- if (quotactl(QCMD(Q_QUOTAON, GRPQUOTA), source.c_str(), QFMT_VFS_V1, nullptr) != 0
- && errno != EBUSY) {
- PLOG(ERROR) << "Failed to enable GRPQUOTA on " << source;
+ // need to kick it again to enable DQUOT_LIMITS_ENABLED. We
+ // only need hard limits enabled when we're not being protected
+ // by reserved blocks.
+ if (!android::base::GetBoolProperty(kPropHasReserved, false)) {
+ if (quotactl(QCMD(Q_QUOTAON, USRQUOTA), source.c_str(), QFMT_VFS_V1,
+ nullptr) != 0 && errno != EBUSY) {
+ PLOG(ERROR) << "Failed to enable USRQUOTA on " << source;
+ }
+ if (quotactl(QCMD(Q_QUOTAON, GRPQUOTA), source.c_str(), QFMT_VFS_V1,
+ nullptr) != 0 && errno != EBUSY) {
+ PLOG(ERROR) << "Failed to enable GRPQUOTA on " << source;
+ }
}
}
}
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index ee3e1dc..2e88e3c 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -66,6 +66,7 @@
static constexpr const char* kMinidebugInfoSystemProperty = "dalvik.vm.dex2oat-minidebuginfo";
static constexpr bool kMinidebugInfoSystemPropertyDefault = false;
static constexpr const char* kMinidebugDex2oatFlag = "--generate-mini-debug-info";
+static constexpr const char* kDisableCompactDexFlag = "--compact-dex-level=none";
// Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below.
struct FreeDelete {
@@ -414,6 +415,12 @@
ALOGV("Running %s in=%s out=%s\n", dex2oat_bin, relative_input_file_name, output_file_name);
+ // Disable cdex if update input vdex is true since this combination of options is not
+ // supported.
+ // Disable cdex for non-background compiles since we don't want to regress app install until
+ // there are enough benefits to justify the tradeoff.
+ const bool disable_cdex = !background_job_compile || (input_vdex_fd == output_vdex_fd);
+
const char* argv[9 // program name, mandatory arguments and the final NULL
+ (have_dex2oat_isa_variant ? 1 : 0)
+ (have_dex2oat_isa_features ? 1 : 0)
@@ -432,6 +439,7 @@
+ (class_loader_context != nullptr ? 1 : 0)
+ (has_base_dir ? 1 : 0)
+ (have_dex2oat_large_app_threshold ? 1 : 0)
+ + (disable_cdex ? 1 : 0)
+ (generate_minidebug_info ? 1 : 0)];
int i = 0;
argv[i++] = dex2oat_bin;
@@ -499,6 +507,9 @@
if (generate_minidebug_info) {
argv[i++] = kMinidebugDex2oatFlag;
}
+ if (disable_cdex) {
+ argv[i++] = kDisableCompactDexFlag;
+ }
// Do not add after dex2oat_flags, they should override others for debugging.
argv[i] = NULL;
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index 622f866..f371320 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -18,6 +18,8 @@
#include "Lshal.h"
+#include <hidl-util/FQName.h>
+
namespace android {
namespace lshal {
@@ -46,7 +48,15 @@
if (status != OK) {
return status;
}
+
auto pair = splitFirst(mInterfaceName, '/');
+
+ FQName fqName(pair.first);
+ if (!fqName.isValid() || fqName.isIdentifier() || !fqName.isFullyQualified()) {
+ mLshal.err() << "Invalid fully-qualified name '" << pair.first << "'\n\n";
+ return USAGE;
+ }
+
return mLshal.emitDebugInfo(
pair.first, pair.second.empty() ? "default" : pair.second, mOptions,
mLshal.out().buf(),
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index b6abc1b..d790bed 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -46,7 +46,7 @@
<feature name="android.software.home_screen" />
<feature name="android.software.input_methods" />
<feature name="android.software.picture_in_picture" notLowRam="true" />
- <feature name="android.software.activities_on_secondary_displays" />
+ <feature name="android.software.activities_on_secondary_displays" notLowRam="true" />
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
<feature name="android.software.autofill" />
diff --git a/libs/math/tests/mat_test.cpp b/libs/math/tests/mat_test.cpp
index 3217a1a..a14c7ea 100644
--- a/libs/math/tests/mat_test.cpp
+++ b/libs/math/tests/mat_test.cpp
@@ -35,7 +35,7 @@
TEST_F(MatTest, Basics) {
mat4 m0;
- EXPECT_EQ(sizeof(mat4), sizeof(float)*16);
+ EXPECT_EQ(sizeof(m0), sizeof(float)*16);
}
TEST_F(MatTest, ComparisonOps) {
@@ -76,6 +76,7 @@
EXPECT_EQ(m3, m1);
mat4 m4(vec4(1), vec4(2), vec4(3), vec4(4));
+ EXPECT_NE(m4, m1);
}
TEST_F(MatTest, ArithmeticOps) {
@@ -172,7 +173,7 @@
TEST_F(Mat3Test, Basics) {
mat3 m0;
- EXPECT_EQ(sizeof(mat3), sizeof(float)*9);
+ EXPECT_EQ(sizeof(m0), sizeof(float)*9);
}
TEST_F(Mat3Test, ComparisonOps) {
@@ -279,7 +280,7 @@
TEST_F(Mat2Test, Basics) {
mat2 m0;
- EXPECT_EQ(sizeof(mat2), sizeof(float)*4);
+ EXPECT_EQ(sizeof(m0), sizeof(float)*4);
}
TEST_F(Mat2Test, ComparisonOps) {
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index a3ee7bb..316f15a 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -71,6 +71,7 @@
void GrantDisplayOwnership() { hardware_composer_.Enable(); }
void SeizeDisplayOwnership() { hardware_composer_.Disable(); }
+ void OnBootFinished() { hardware_composer_.OnBootFinished(); }
private:
friend BASE;
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index be17ecf..5d796dc 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -53,6 +53,9 @@
const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns";
+// How long to wait after boot finishes before we turn the display off.
+constexpr int kBootFinishedDisplayOffTimeoutSec = 10;
+
// Get time offset from a vsync to when the pose for that vsync should be
// predicted out to. For example, if scanout gets halfway through the frame
// at the halfway point between vsyncs, then this could be half the period.
@@ -190,6 +193,16 @@
UpdatePostThreadState(PostThreadState::Suspended, true);
}
+void HardwareComposer::OnBootFinished() {
+ std::lock_guard<std::mutex> lock(post_thread_mutex_);
+ if (boot_finished_)
+ return;
+ boot_finished_ = true;
+ post_thread_wait_.notify_one();
+ if (is_standalone_device_)
+ request_display_callback_(true);
+}
+
// Update the post thread quiescent state based on idle and suspended inputs.
void HardwareComposer::UpdatePostThreadState(PostThreadStateType state,
bool suspend) {
@@ -276,6 +289,25 @@
property_set(kDvrPerformanceProperty, "idle");
}
+bool HardwareComposer::PostThreadCondWait(std::unique_lock<std::mutex>& lock,
+ int timeout_sec,
+ const std::function<bool()>& pred) {
+ auto pred_with_quit = [&] {
+ return pred() || (post_thread_state_ & PostThreadState::Quit);
+ };
+ if (timeout_sec >= 0) {
+ post_thread_wait_.wait_for(lock, std::chrono::seconds(timeout_sec),
+ pred_with_quit);
+ } else {
+ post_thread_wait_.wait(lock, pred_with_quit);
+ }
+ if (post_thread_state_ & PostThreadState::Quit) {
+ ALOGI("HardwareComposer::PostThread: Quitting.");
+ return true;
+ }
+ return false;
+}
+
HWC::Error HardwareComposer::Validate(hwc2_display_t display) {
uint32_t num_types;
uint32_t num_requests;
@@ -508,7 +540,7 @@
pending_surfaces_ = std::move(surfaces);
}
- if (request_display_callback_ && (!is_standalone_device_ || !composer_))
+ if (request_display_callback_ && !is_standalone_device_)
request_display_callback_(!display_idle);
// Set idle state based on whether there are any surfaces to handle.
@@ -697,6 +729,28 @@
bool was_running = false;
+ if (is_standalone_device_) {
+ // First, wait until boot finishes.
+ std::unique_lock<std::mutex> lock(post_thread_mutex_);
+ if (PostThreadCondWait(lock, -1, [this] { return boot_finished_; })) {
+ return;
+ }
+
+ // Then, wait until we're either leaving the quiescent state, or the boot
+ // finished display off timeout expires.
+ if (PostThreadCondWait(lock, kBootFinishedDisplayOffTimeoutSec,
+ [this] { return !post_thread_quiescent_; })) {
+ return;
+ }
+
+ LOG_ALWAYS_FATAL_IF(post_thread_state_ & PostThreadState::Suspended,
+ "Vr flinger should own the display by now.");
+ post_thread_resumed_ = true;
+ post_thread_ready_.notify_all();
+ OnPostThreadResumed();
+ was_running = true;
+ }
+
while (1) {
ATRACE_NAME("HardwareComposer::PostThread");
@@ -715,13 +769,12 @@
post_thread_resumed_ = false;
post_thread_ready_.notify_all();
- if (post_thread_state_ & PostThreadState::Quit) {
- ALOGI("HardwareComposer::PostThread: Quitting.");
+ if (PostThreadCondWait(lock, -1,
+ [this] { return !post_thread_quiescent_; })) {
+ // A true return value means we've been asked to quit.
return;
}
- post_thread_wait_.wait(lock, [this] { return !post_thread_quiescent_; });
-
post_thread_resumed_ = true;
post_thread_ready_.notify_all();
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index 9ed4b22..1d0c7ef 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -327,6 +327,9 @@
// it's paused. This should only be called from surface flinger's main thread.
void Disable();
+ // Called on a binder thread.
+ void OnBootFinished();
+
// Get the HMD display metrics for the current display.
display::Metrics GetHmdDisplayMetrics() const;
@@ -434,6 +437,16 @@
// Called on the post thread when the post thread is paused or quits.
void OnPostThreadPaused();
+ // Use post_thread_wait_ to wait for a specific condition, specified by pred.
+ // timeout_sec < 0 means wait indefinitely, otherwise it specifies the timeout
+ // in seconds.
+ // The lock must be held when this function is called.
+ // Returns true if the wait was interrupted because the post thread was asked
+ // to quit.
+ bool PostThreadCondWait(std::unique_lock<std::mutex>& lock,
+ int timeout_sec,
+ const std::function<bool()>& pred);
+
// Map the given shared memory buffer to our broadcast ring to track updates
// to the config parameters.
int MapConfigBuffer(IonBuffer& ion_buffer);
@@ -482,6 +495,10 @@
std::condition_variable post_thread_wait_;
std::condition_variable post_thread_ready_;
+ // When boot is finished this will be set to true and the post thread will be
+ // notified via post_thread_wait_.
+ bool boot_finished_ = false;
+
// Backlight LED brightness sysfs node.
pdx::LocalHandle backlight_brightness_fd_;
diff --git a/libs/vr/libvrflinger/vr_flinger.cpp b/libs/vr/libvrflinger/vr_flinger.cpp
index 5e7abd7..26aed4f 100644
--- a/libs/vr/libvrflinger/vr_flinger.cpp
+++ b/libs/vr/libvrflinger/vr_flinger.cpp
@@ -115,6 +115,7 @@
}
void VrFlinger::OnBootFinished() {
+ display_service_->OnBootFinished();
sp<IVrManager> vr_manager = interface_cast<IVrManager>(
defaultServiceManager()->checkService(String16("vrmanager")));
if (vr_manager.get()) {
diff --git a/opengl/libs/EGL/FileBlobCache.cpp b/opengl/libs/EGL/FileBlobCache.cpp
index ff608a3..7923715 100644
--- a/opengl/libs/EGL/FileBlobCache.cpp
+++ b/opengl/libs/EGL/FileBlobCache.cpp
@@ -16,6 +16,7 @@
#include "FileBlobCache.h"
+#include <errno.h>
#include <inttypes.h>
#include <log/log.h>
#include <sys/mman.h>
@@ -182,4 +183,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 9822849..91a3455 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -407,9 +407,8 @@
DIR* d = opendir(search);
if (d != NULL) {
- struct dirent cur;
struct dirent* e;
- while (readdir_r(d, &cur, &e) == 0 && e) {
+ while ((e = readdir(d)) != NULL) {
if (e->d_type == DT_DIR) {
continue;
}
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index 2ee222b..520fea4 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -69,13 +69,15 @@
NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
uint32_t policyFlags,
int32_t action, int32_t actionButton, int32_t flags, int32_t metaState,
- int32_t buttonState, int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
+ int32_t buttonState, int32_t edgeFlags, int32_t displayId, uint32_t deviceTimestamp,
+ uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime) :
eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
action(action), actionButton(actionButton),
flags(flags), metaState(metaState), buttonState(buttonState),
- edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
+ edgeFlags(edgeFlags), displayId(displayId), deviceTimestamp(deviceTimestamp),
+ pointerCount(pointerCount),
xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
for (uint32_t i = 0; i < pointerCount; i++) {
this->pointerProperties[i].copyFrom(pointerProperties[i]);
@@ -88,7 +90,8 @@
policyFlags(other.policyFlags),
action(other.action), actionButton(other.actionButton), flags(other.flags),
metaState(other.metaState), buttonState(other.buttonState),
- edgeFlags(other.edgeFlags), displayId(other.displayId), pointerCount(other.pointerCount),
+ edgeFlags(other.edgeFlags), displayId(other.displayId),
+ deviceTimestamp(other.deviceTimestamp), pointerCount(other.pointerCount),
xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
for (uint32_t i = 0; i < pointerCount; i++) {
pointerProperties[i].copyFrom(other.pointerProperties[i]);
diff --git a/services/inputflinger/InputListener.h b/services/inputflinger/InputListener.h
index ea3dd1c..77afb34 100644
--- a/services/inputflinger/InputListener.h
+++ b/services/inputflinger/InputListener.h
@@ -90,6 +90,13 @@
int32_t buttonState;
int32_t edgeFlags;
int32_t displayId;
+ /**
+ * A timestamp in the input device's time base, not the platform's.
+ * The units are microseconds since the last reset.
+ * This can only be compared to other device timestamps from the same device.
+ * This value will overflow after a little over an hour.
+ */
+ uint32_t deviceTimestamp;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
@@ -102,7 +109,7 @@
NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
int32_t action, int32_t actionButton, int32_t flags,
int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
+ int32_t edgeFlags, int32_t displayId, uint32_t deviceTimestamp, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime);
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 76ea889..e0cd8a0 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -1787,7 +1787,7 @@
MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
- mHaveStylus(false) {
+ mHaveStylus(false), mDeviceTimestamp(0) {
}
MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
@@ -1828,6 +1828,7 @@
} else {
clearSlots(-1);
}
+ mDeviceTimestamp = 0;
}
void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
@@ -1921,6 +1922,8 @@
} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
// MultiTouch Sync: The driver has returned all data for *one* of the pointers.
mCurrentSlot += 1;
+ } else if (rawEvent->type == EV_MSC && rawEvent->code == MSC_TIMESTAMP) {
+ mDeviceTimestamp = rawEvent->value;
}
}
@@ -2894,7 +2897,7 @@
NotifyMotionArgs releaseArgs(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
+ displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&releaseArgs);
}
@@ -2903,7 +2906,7 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
motionEventAction, 0, 0, metaState, currentButtonState,
AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
+ displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&args);
@@ -2915,7 +2918,7 @@
NotifyMotionArgs pressArgs(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
+ displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&pressArgs);
}
@@ -2929,7 +2932,7 @@
NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
+ displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&hoverArgs);
}
@@ -2942,7 +2945,7 @@
NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, currentButtonState,
AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
+ displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&scrollArgs);
}
@@ -3072,7 +3075,7 @@
NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, 0,
AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
+ displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
0, 0, 0);
getListener()->notifyMotion(&scrollArgs);
}
@@ -4729,6 +4732,7 @@
int32_t buttonState = mCurrentCookedState.buttonState;
dispatchMotion(when, policyFlags, mSource, AMOTION_EVENT_ACTION_CANCEL, 0, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
@@ -4751,6 +4755,7 @@
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
AMOTION_EVENT_EDGE_FLAG_NONE,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
@@ -4785,6 +4790,7 @@
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0, 0, metaState, buttonState, 0,
+ mCurrentCookedState.deviceTimestamp,
mLastCookedState.cookedPointerData.pointerProperties,
mLastCookedState.cookedPointerData.pointerCoords,
mLastCookedState.cookedPointerData.idToIndex,
@@ -4799,6 +4805,7 @@
ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, 0,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
@@ -4817,6 +4824,7 @@
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_POINTER_DOWN, 0, 0, metaState, buttonState, 0,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
@@ -4832,6 +4840,7 @@
int32_t metaState = getContext()->getGlobalMetaState();
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastCookedState.buttonState, 0,
+ mLastCookedState.deviceTimestamp,
mLastCookedState.cookedPointerData.pointerProperties,
mLastCookedState.cookedPointerData.pointerCoords,
mLastCookedState.cookedPointerData.idToIndex,
@@ -4848,6 +4857,7 @@
if (!mSentHoverEnter) {
dispatchMotion(when, policyFlags, mSource, AMOTION_EVENT_ACTION_HOVER_ENTER,
0, 0, metaState, mCurrentRawState.buttonState, 0,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
@@ -4859,6 +4869,7 @@
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
@@ -4878,6 +4889,7 @@
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton,
0, metaState, buttonState, 0,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex, idBits, -1,
@@ -4895,6 +4907,7 @@
buttonState |= actionButton;
dispatchMotion(when, policyFlags, mSource, AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton,
0, metaState, buttonState, 0,
+ mCurrentCookedState.deviceTimestamp,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex, idBits, -1,
@@ -4913,6 +4926,8 @@
uint32_t currentPointerCount = mCurrentRawState.rawPointerData.pointerCount;
mCurrentCookedState.cookedPointerData.clear();
+ mCurrentCookedState.deviceTimestamp =
+ mCurrentRawState.deviceTimestamp;
mCurrentCookedState.cookedPointerData.pointerCount = currentPointerCount;
mCurrentCookedState.cookedPointerData.hoveringIdBits =
mCurrentRawState.rawPointerData.hoveringIdBits;
@@ -5305,7 +5320,7 @@
if (cancelPreviousGesture) {
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_CANCEL, 0, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
dispatchedGestureIdBits, -1, 0,
@@ -5326,6 +5341,7 @@
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0,
mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
dispatchedGestureIdBits, id,
@@ -5340,7 +5356,7 @@
if (moveNeeded) {
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
dispatchedGestureIdBits, -1,
@@ -5361,6 +5377,7 @@
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_POINTER_DOWN, 0, 0, metaState, buttonState, 0,
+ /* deviceTimestamp */ 0,
mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
dispatchedGestureIdBits, id,
@@ -5372,7 +5389,7 @@
if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
- metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
mPointerGesture.currentGestureIdBits, -1,
@@ -5399,7 +5416,7 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mViewport.displayId, 1, &pointerProperties, &pointerCoords,
+ mViewport.displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
0, 0, mPointerGesture.downTime);
getListener()->notifyMotion(&args);
}
@@ -5429,7 +5446,7 @@
int32_t buttonState = mCurrentRawState.buttonState;
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_CANCEL, 0, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
mPointerGesture.lastGestureIdBits, -1,
@@ -6321,7 +6338,7 @@
// Send up.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
- mViewport.displayId,
+ mViewport.displayId, /* deviceTimestamp */ 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6334,7 +6351,7 @@
// Send hover exit.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastRawState.buttonState, 0,
- mViewport.displayId,
+ mViewport.displayId, /* deviceTimestamp */ 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6349,7 +6366,7 @@
// Send down.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_DOWN, 0, 0, metaState, mCurrentRawState.buttonState, 0,
- mViewport.displayId,
+ mViewport.displayId, /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6359,7 +6376,7 @@
// Send move.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, mCurrentRawState.buttonState, 0,
- mViewport.displayId,
+ mViewport.displayId, /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6374,7 +6391,7 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
- mViewport.displayId,
+ mViewport.displayId, /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6385,7 +6402,7 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
- mViewport.displayId,
+ mViewport.displayId, /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6406,7 +6423,7 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, mCurrentRawState.buttonState, 0,
- mViewport.displayId,
+ mViewport.displayId, /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &pointerCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6431,7 +6448,7 @@
void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
int32_t action, int32_t actionButton, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+ int32_t metaState, int32_t buttonState, int32_t edgeFlags, uint32_t deviceTimestamp,
const PointerProperties* properties, const PointerCoords* coords,
const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId,
float xPrecision, float yPrecision, nsecs_t downTime) {
@@ -6469,7 +6486,7 @@
NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
action, actionButton, flags, metaState, buttonState, edgeFlags,
- mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
+ mViewport.displayId, deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
xPrecision, yPrecision, downTime);
getListener()->notifyMotion(&args);
}
@@ -6949,6 +6966,7 @@
outCount += 1;
}
+ outState->deviceTimestamp = mMultiTouchMotionAccumulator.getDeviceTimestamp();
outState->rawPointerData.pointerCount = outCount;
mPointerIdBits = newPointerIdBits;
@@ -7388,7 +7406,8 @@
NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
+ ADISPLAY_ID_NONE, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ 0, 0, 0);
getListener()->notifyMotion(&args);
}
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 4f48262..cef3212 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -947,6 +947,7 @@
inline size_t getSlotCount() const { return mSlotCount; }
inline const Slot* getSlot(size_t index) const { return &mSlots[index]; }
+ inline uint32_t getDeviceTimestamp() const { return mDeviceTimestamp; }
private:
int32_t mCurrentSlot;
@@ -954,6 +955,7 @@
size_t mSlotCount;
bool mUsingSlotsProtocol;
bool mHaveStylus;
+ uint32_t mDeviceTimestamp;
void clearSlots(int32_t initialSlot);
};
@@ -1396,6 +1398,7 @@
struct RawState {
nsecs_t when;
+ uint32_t deviceTimestamp;
// Raw pointer sample data.
RawPointerData rawPointerData;
@@ -1408,6 +1411,7 @@
void copyFrom(const RawState& other) {
when = other.when;
+ deviceTimestamp = other.deviceTimestamp;
rawPointerData.copyFrom(other.rawPointerData);
buttonState = other.buttonState;
rawVScroll = other.rawVScroll;
@@ -1416,6 +1420,7 @@
void clear() {
when = 0;
+ deviceTimestamp = 0;
rawPointerData.clear();
buttonState = 0;
rawVScroll = 0;
@@ -1424,6 +1429,7 @@
};
struct CookedState {
+ uint32_t deviceTimestamp;
// Cooked pointer sample data.
CookedPointerData cookedPointerData;
@@ -1435,6 +1441,7 @@
int32_t buttonState;
void copyFrom(const CookedState& other) {
+ deviceTimestamp = other.deviceTimestamp;
cookedPointerData.copyFrom(other.cookedPointerData);
fingerIdBits = other.fingerIdBits;
stylusIdBits = other.stylusIdBits;
@@ -1443,6 +1450,7 @@
}
void clear() {
+ deviceTimestamp = 0;
cookedPointerData.clear();
fingerIdBits.clear();
stylusIdBits.clear();
@@ -1837,6 +1845,7 @@
void dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
int32_t action, int32_t actionButton,
int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+ uint32_t deviceTimestamp,
const PointerProperties* properties, const PointerCoords* coords,
const uint32_t* idToIndex, BitSet32 idBits,
int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime);
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 63c92d1..22f15a0 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -4384,6 +4384,7 @@
void processSlot(MultiTouchInputMapper* mapper, int32_t slot);
void processToolType(MultiTouchInputMapper* mapper, int32_t toolType);
void processKey(MultiTouchInputMapper* mapper, int32_t code, int32_t value);
+ void processTimestamp(MultiTouchInputMapper* mapper, uint32_t value);
void processMTSync(MultiTouchInputMapper* mapper);
void processSync(MultiTouchInputMapper* mapper);
};
@@ -4499,6 +4500,10 @@
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
}
+void MultiTouchInputMapperTest::processTimestamp(MultiTouchInputMapper* mapper, uint32_t value) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_MSC, MSC_TIMESTAMP, value);
+}
+
void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0);
}
@@ -5881,5 +5886,63 @@
toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
}
+TEST_F(MultiTouchInputMapperTest, Process_HandlesTimestamp) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+ NotifyMotionArgs args;
+
+ // By default, deviceTimestamp should be zero
+ processPosition(mapper, 100, 100);
+ processMTSync(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(0U, args.deviceTimestamp);
+
+ // Now the timestamp of 1000 is reported by evdev and should appear in MotionArgs
+ processPosition(mapper, 0, 0);
+ processTimestamp(mapper, 1000);
+ processMTSync(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(1000U, args.deviceTimestamp);
+}
+
+TEST_F(MultiTouchInputMapperTest, WhenMapperIsReset_TimestampIsCleared) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+ NotifyMotionArgs args;
+
+ // Send a touch event with a timestamp
+ processPosition(mapper, 100, 100);
+ processTimestamp(mapper, 1);
+ processMTSync(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(1U, args.deviceTimestamp);
+
+ // Since the data accumulates, and new timestamp has not arrived, deviceTimestamp won't change
+ processPosition(mapper, 100, 200);
+ processMTSync(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(1U, args.deviceTimestamp);
+
+ mapper->reset(/* when */ 0);
+ // After the mapper is reset, deviceTimestamp should become zero again
+ processPosition(mapper, 100, 300);
+ processMTSync(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(0U, args.deviceTimestamp);
+}
+
} // namespace android
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 5f70ab5..d860f58 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -105,7 +105,8 @@
bool BufferLayer::isVisible() const {
return !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
- (getBE().compositionInfo.mBuffer != NULL || getBE().compositionInfo.hwc.sidebandStream != NULL);
+ (getBE().compositionInfo.mBuffer != nullptr ||
+ getBE().compositionInfo.hwc.sidebandStream != nullptr);
}
bool BufferLayer::isFixedSize() const {
@@ -377,7 +378,7 @@
mSidebandStream = mConsumer->getSidebandStream();
// replicated in LayerBE until FE/BE is ready to be synchronized
getBE().compositionInfo.hwc.sidebandStream = mSidebandStream;
- if (getBE().compositionInfo.hwc.sidebandStream != NULL) {
+ if (getBE().compositionInfo.hwc.sidebandStream != nullptr) {
setTransactionFlags(eTransactionNeeded);
mFlinger->setTransactionFlags(eTraversalNeeded);
}
@@ -492,7 +493,7 @@
mConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot);
// replicated in LayerBE until FE/BE is ready to be synchronized
mActiveBuffer = getBE().compositionInfo.mBuffer;
- if (getBE().compositionInfo.mBuffer == NULL) {
+ if (getBE().compositionInfo.mBuffer == nullptr) {
// this can only happen if the very first buffer was rejected.
return outDirtyRegion;
}
@@ -508,7 +509,7 @@
mRefreshPending = true;
mFrameLatencyNeeded = true;
- if (oldBuffer == NULL) {
+ if (oldBuffer == nullptr) {
// the first time we receive a buffer, we need to trigger a
// geometry invalidation.
recomputeVisibleRegions = true;
@@ -528,7 +529,7 @@
recomputeVisibleRegions = true;
}
- if (oldBuffer != NULL) {
+ if (oldBuffer != nullptr) {
uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth();
uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight();
if (bufWidth != uint32_t(oldBuffer->width) ||
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index bf61236..8f5c9c7 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -271,7 +271,7 @@
// If item->mGraphicBuffer is not null, this buffer has not been acquired
// before, so any prior EglImage created is using a stale buffer. This
// replaces any old EglImage with a new one (using the new buffer).
- if (item->mGraphicBuffer != NULL) {
+ if (item->mGraphicBuffer != nullptr) {
mImages[item->mSlot] = new Image(item->mGraphicBuffer, mRE);
}
@@ -306,8 +306,8 @@
}
BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture,
- mCurrentTextureImage != NULL ? mCurrentTextureImage->graphicBufferHandle() : 0, slot,
- mSlots[slot].mGraphicBuffer->handle);
+ mCurrentTextureImage != nullptr ? mCurrentTextureImage->graphicBufferHandle() : 0,
+ slot, mSlots[slot].mGraphicBuffer->handle);
// Hang onto the pointer so that it isn't freed in the call to
// releaseBufferLocked() if we're in shared buffer mode and both buffers are
@@ -355,7 +355,7 @@
status_t BufferLayerConsumer::bindTextureImageLocked() {
mRE.checkErrors();
- if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == NULL) {
+ if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) {
BLC_LOGE("bindTextureImage: no currently-bound texture");
mRE.bindExternalTextureImage(mTexName, RE::Image(mRE));
return NO_INIT;
@@ -414,11 +414,11 @@
bool needsRecompute = mFilteringEnabled != enabled;
mFilteringEnabled = enabled;
- if (needsRecompute && mCurrentTextureImage == NULL) {
- BLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL");
+ if (needsRecompute && mCurrentTextureImage == nullptr) {
+ BLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == nullptr");
}
- if (needsRecompute && mCurrentTextureImage != NULL) {
+ if (needsRecompute && mCurrentTextureImage != nullptr) {
computeCurrentTransformMatrixLocked();
}
}
@@ -429,7 +429,7 @@
(mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer();
if (buf == nullptr) {
BLC_LOGD("computeCurrentTransformMatrixLocked: "
- "mCurrentTextureImage is NULL");
+ "mCurrentTextureImage is nullptr");
}
const Rect& cropRect = canUseImageCrop(mCurrentCrop) ? Rect::EMPTY_RECT : mCurrentCrop;
GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, buf, cropRect, mCurrentTransform,
@@ -476,7 +476,7 @@
*outSlot = mCurrentTexture;
}
- return (mCurrentTextureImage == nullptr) ? NULL : mCurrentTextureImage->graphicBuffer();
+ return (mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer();
}
Rect BufferLayerConsumer::getCurrentCrop() const {
@@ -564,7 +564,7 @@
listener = mContentsChangedListener.promote();
}
- if (listener != NULL) {
+ if (listener != nullptr) {
listener->onSidebandStreamChanged();
}
}
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index 51c2b41..f473390 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -228,7 +228,7 @@
const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; }
const native_handle* graphicBufferHandle() {
- return mGraphicBuffer == NULL ? NULL : mGraphicBuffer->handle;
+ return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle;
}
const RE::Image& image() const { return mImage; }
@@ -265,7 +265,7 @@
// computeCurrentTransformMatrixLocked computes the transform matrix for the
// current texture. It uses mCurrentTransform and the current GraphicBuffer
// to compute this matrix and stores it in mCurrentTransformMatrix.
- // mCurrentTextureImage must not be NULL.
+ // mCurrentTextureImage must not be nullptr.
void computeCurrentTransformMatrixLocked();
// doFenceWaitLocked inserts a wait command into the RenderEngine command
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index ea6541a..a69940a 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -206,7 +206,7 @@
status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
sp<Layer> layer = getLayerUser(handle);
- if (layer == NULL) {
+ if (layer == nullptr) {
return NAME_NOT_FOUND;
}
layer->clearFrameStats();
@@ -215,7 +215,7 @@
status_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const {
sp<Layer> layer = getLayerUser(handle);
- if (layer == NULL) {
+ if (layer == nullptr) {
return NAME_NOT_FOUND;
}
layer->getFrameStats(outStats);
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 2753f11..9772f9a 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -160,7 +160,7 @@
}
bool DisplayDevice::isValid() const {
- return mFlinger != NULL;
+ return mFlinger != nullptr;
}
int DisplayDevice::getWidth() const {
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 4186b7a..eaa5455 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -80,7 +80,7 @@
// on/off.
android_dataspace mDataSpace;
- // mCurrentBuffer is the current buffer or NULL to indicate that there is
+ // mCurrentBuffer is the current buffer or nullptr to indicate that there is
// no current buffer.
sp<GraphicBuffer> mCurrentBuffer;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index ab4a4b2..affe505 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -467,7 +467,6 @@
Error Display::getHdrCapabilities(
std::unique_ptr<HdrCapabilities>* outCapabilities) const
{
- uint32_t numTypes = 0;
float maxLuminance = -1.0f;
float maxAverageLuminance = -1.0f;
float minLuminance = -1.0f;
@@ -480,7 +479,6 @@
for (auto type : intTypes) {
types.push_back(static_cast<int32_t>(type));
}
- numTypes = types.size();
if (error != Error::None) {
return error;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
index 4bc63bb..fe7944f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
@@ -190,7 +190,7 @@
virtual status_t setLayer(size_t index) = 0;
virtual HWCLayer* dup() = 0;
static HWCLayer* copy(HWCLayer *rhs) {
- return rhs ? rhs->dup() : NULL;
+ return rhs ? rhs->dup() : nullptr;
}
protected:
virtual ~HWCLayer() { }
@@ -205,7 +205,7 @@
HWCLayer* const mLayerList;
size_t mIndex;
- LayerListIterator() : mLayerList(NULL), mIndex(0) { }
+ LayerListIterator() : mLayerList(nullptr), mIndex(0) { }
LayerListIterator(HWCLayer* layer, size_t index)
: mLayerList(layer), mIndex(index) { }
@@ -371,8 +371,8 @@
sp<SurfaceFlinger> mFlinger;
framebuffer_device_t* mFbDev;
struct hwc_composer_device_1* mHwc;
- // invariant: mLists[0] != NULL iff mHwc != NULL
- // mLists[i>0] can be NULL. that display is to be ignored
+ // invariant: mLists[0] != nullptr iff mHwc != nullptr
+ // mLists[i>0] can be nullptr. that display is to be ignored
struct hwc_display_contents_1* mLists[MAX_HWC_DISPLAYS];
DisplayData mDisplayData[MAX_HWC_DISPLAYS];
// protect mDisplayData from races between prepare and dump
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index cde96e4..3480b24 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -108,7 +108,7 @@
mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight);
sink->setAsyncMode(true);
IGraphicBufferProducer::QueueBufferOutput output;
- mSource[SOURCE_SCRATCH]->connect(NULL, NATIVE_WINDOW_API_EGL, false, &output);
+ mSource[SOURCE_SCRATCH]->connect(nullptr, NATIVE_WINDOW_API_EGL, false, &output);
}
VirtualDisplaySurface::~VirtualDisplaySurface() {
@@ -203,7 +203,7 @@
}
sp<GraphicBuffer> fbBuffer = mFbProducerSlot >= 0 ?
- mProducerBuffers[mFbProducerSlot] : sp<GraphicBuffer>(NULL);
+ mProducerBuffers[mFbProducerSlot] : sp<GraphicBuffer>(nullptr);
sp<GraphicBuffer> outBuffer = mProducerBuffers[mOutputProducerSlot];
VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)",
mFbProducerSlot, fbBuffer.get(),
@@ -214,7 +214,7 @@
mHwc.setOutputBuffer(mDisplayId, mOutputFence, outBuffer);
status_t result = NO_ERROR;
- if (fbBuffer != NULL) {
+ if (fbBuffer != nullptr) {
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer,
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index a1a0420..5c0e3b3 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -216,7 +216,7 @@
size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; ) {
sp<Connection> connection(mDisplayEventConnections[i].promote());
- if (connection != NULL) {
+ if (connection != nullptr) {
bool added = false;
if (connection->count >= 0) {
// we need vsync events because at least
@@ -346,7 +346,7 @@
sp<Connection> connection =
mDisplayEventConnections.itemAt(i).promote();
result.appendFormat(" %p: count=%d\n",
- connection.get(), connection!=NULL ? connection->count : 0);
+ connection.get(), connection != nullptr ? connection->count : 0);
}
}
diff --git a/services/surfaceflinger/FrameTracker.cpp b/services/surfaceflinger/FrameTracker.cpp
index 99c4daa..1539873 100644
--- a/services/surfaceflinger/FrameTracker.cpp
+++ b/services/surfaceflinger/FrameTracker.cpp
@@ -82,17 +82,17 @@
mFrameRecords[mOffset].frameReadyTime = INT64_MAX;
mFrameRecords[mOffset].actualPresentTime = INT64_MAX;
- if (mFrameRecords[mOffset].frameReadyFence != NULL) {
+ if (mFrameRecords[mOffset].frameReadyFence != nullptr) {
// We're clobbering an unsignaled fence, so we need to decrement the
// fence count.
- mFrameRecords[mOffset].frameReadyFence = NULL;
+ mFrameRecords[mOffset].frameReadyFence = nullptr;
mNumFences--;
}
- if (mFrameRecords[mOffset].actualPresentFence != NULL) {
+ if (mFrameRecords[mOffset].actualPresentFence != nullptr) {
// We're clobbering an unsignaled fence, so we need to decrement the
// fence count.
- mFrameRecords[mOffset].actualPresentFence = NULL;
+ mFrameRecords[mOffset].actualPresentFence = nullptr;
mNumFences--;
}
}
@@ -153,10 +153,10 @@
bool updated = false;
const std::shared_ptr<FenceTime>& rfence = records[idx].frameReadyFence;
- if (rfence != NULL) {
+ if (rfence != nullptr) {
records[idx].frameReadyTime = rfence->getSignalTime();
if (records[idx].frameReadyTime < INT64_MAX) {
- records[idx].frameReadyFence = NULL;
+ records[idx].frameReadyFence = nullptr;
numFences--;
updated = true;
}
@@ -164,10 +164,10 @@
const std::shared_ptr<FenceTime>& pfence =
records[idx].actualPresentFence;
- if (pfence != NULL) {
+ if (pfence != nullptr) {
records[idx].actualPresentTime = pfence->getSignalTime();
if (records[idx].actualPresentTime < INT64_MAX) {
- records[idx].actualPresentFence = NULL;
+ records[idx].actualPresentFence = nullptr;
numFences--;
updated = true;
}
diff --git a/services/surfaceflinger/FrameTracker.h b/services/surfaceflinger/FrameTracker.h
index adcdfb5..b4a9fd6 100644
--- a/services/surfaceflinger/FrameTracker.h
+++ b/services/surfaceflinger/FrameTracker.h
@@ -35,7 +35,7 @@
// possible.
//
// Some of the time values tracked may be set either as a specific timestamp
-// or a fence. When a non-NULL fence is set for a given time value, the
+// or a fence. When a non-nullptr fence is set for a given time value, the
// signal time of that fence is used instead of the timestamp.
class FrameTracker {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cc675c4..63f6781 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -265,7 +265,7 @@
if (!mCurrentCrop.isEmpty()) {
// if the buffer crop is defined, we use that
crop = mCurrentCrop;
- } else if (getBE().compositionInfo.mBuffer != NULL) {
+ } else if (getBE().compositionInfo.mBuffer != nullptr) {
// otherwise we use the whole buffer
crop = getBE().compositionInfo.mBuffer->getBounds();
} else {
diff --git a/services/surfaceflinger/LayerRejecter.cpp b/services/surfaceflinger/LayerRejecter.cpp
index e864607..a5f0b98 100644
--- a/services/surfaceflinger/LayerRejecter.cpp
+++ b/services/surfaceflinger/LayerRejecter.cpp
@@ -41,7 +41,7 @@
mFreezeGeometryUpdates(freezePositionUpdates) {}
bool LayerRejecter::reject(const sp<GraphicBuffer>& buf, const BufferItem& item) {
- if (buf == NULL) {
+ if (buf == nullptr) {
return false;
}
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index e014406..1b5a466 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -26,15 +26,6 @@
namespace android {
-Description::Description() {
- mPremultipliedAlpha = false;
- mOpaque = true;
- mTextureEnabled = false;
- mColorMatrixEnabled = false;
-}
-
-Description::~Description() {}
-
void Description::setPremultipliedAlpha(bool premultipliedAlpha) {
mPremultipliedAlpha = premultipliedAlpha;
}
diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/Description.h
index cbac855..1811952 100644
--- a/services/surfaceflinger/RenderEngine/Description.h
+++ b/services/surfaceflinger/RenderEngine/Description.h
@@ -36,27 +36,27 @@
friend class ProgramCache;
// whether textures are premultiplied
- bool mPremultipliedAlpha;
+ bool mPremultipliedAlpha = false;
// whether this layer is marked as opaque
- bool mOpaque;
+ bool mOpaque = true;
// Texture this layer uses
Texture mTexture;
- bool mTextureEnabled;
+ bool mTextureEnabled = false;
// color used when texturing is disabled or when setting alpha.
half4 mColor;
// projection matrix
mat4 mProjectionMatrix;
- bool mColorMatrixEnabled;
+ bool mColorMatrixEnabled = false;
mat4 mColorMatrix;
- bool mIsWideGamut;
+ bool mIsWideGamut = false;
public:
- Description();
- ~Description();
+ Description() = default;
+ ~Description() = default;
void setPremultipliedAlpha(bool premultipliedAlpha);
void setOpaque(bool opaque);
diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp
index baf92eb..225bcf0 100644
--- a/services/surfaceflinger/RenderEngine/Program.cpp
+++ b/services/surfaceflinger/RenderEngine/Program.cpp
@@ -115,7 +115,7 @@
GLint l;
glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &l);
char* src = new char[l];
- glGetShaderSource(shader, l, NULL, src);
+ glGetShaderSource(shader, l, nullptr, src);
result.append(src);
delete[] src;
return result;
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 4f138dc..3b8ac0e 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -98,7 +98,7 @@
continue;
}
Program* program = mCache.valueFor(shaderKey);
- if (program == NULL) {
+ if (program == nullptr) {
program = generateProgram(shaderKey);
mCache.add(shaderKey, program);
shaderCount++;
@@ -273,7 +273,7 @@
// look-up the program in the cache
Program* program = mCache.valueFor(needs);
- if (program == NULL) {
+ if (program == nullptr) {
// we didn't find our program, so generate one...
nsecs_t time = -systemTime();
program = generateProgram(needs);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 314333f..179b790 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -36,11 +36,11 @@
std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featureFlags) {
// initialize EGL for the default display
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (!eglInitialize(display, NULL, NULL)) {
+ if (!eglInitialize(display, nullptr, nullptr)) {
LOG_ALWAYS_FATAL("failed to initialize EGL");
}
- GLExtensions& extensions(GLExtensions::getInstance());
+ GLExtensions& extensions = GLExtensions::getInstance();
extensions.initWithEGLStrings(eglQueryStringImplementationANDROID(display, EGL_VERSION),
eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS));
@@ -79,7 +79,7 @@
contextAttributes.push_back(EGL_NONE);
contextAttributes.push_back(EGL_NONE);
- EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes.data());
+ EGLContext ctxt = eglCreateContext(display, config, nullptr, contextAttributes.data());
// if can't create a GL context, we can only abort.
LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
@@ -132,7 +132,7 @@
}
RenderEngine::RenderEngine()
- : mEGLDisplay(EGL_NO_DISPLAY), mEGLConfig(NULL), mEGLContext(EGL_NO_CONTEXT) {}
+ : mEGLDisplay(EGL_NO_DISPLAY), mEGLConfig(nullptr), mEGLContext(EGL_NO_CONTEXT) {}
RenderEngine::~RenderEngine() {
eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
@@ -183,7 +183,7 @@
return base::unique_fd();
}
- EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
+ EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
if (sync == EGL_NO_SYNC_KHR) {
ALOGW("failed to create EGL native fence sync: %#x", eglGetError());
return base::unique_fd();
@@ -208,7 +208,7 @@
return false;
}
- EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
+ EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr);
if (sync == EGL_NO_SYNC_KHR) {
ALOGW("failed to create EGL fence sync: %#x", eglGetError());
return false;
@@ -347,7 +347,7 @@
}
void RenderEngine::dump(String8& result) {
- const GLExtensions& extensions(GLExtensions::getInstance());
+ const GLExtensions& extensions = GLExtensions::getInstance();
result.appendFormat("EGL implementation : %s\n", extensions.getEGLVersion());
result.appendFormat("%s\n", extensions.getEGLExtensions());
@@ -363,7 +363,7 @@
RenderEngine& engine, ANativeWindowBuffer* buffer)
: mEngine(engine) {
mImage = eglCreateImageKHR(mEngine.mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
- buffer, NULL);
+ buffer, nullptr);
if (mImage == EGL_NO_IMAGE_KHR) {
mStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
return;
@@ -394,7 +394,7 @@
static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, EGLint attribute,
EGLint wanted, EGLConfig* outConfig) {
EGLint numConfigs = -1, n = 0;
- eglGetConfigs(dpy, NULL, 0, &numConfigs);
+ eglGetConfigs(dpy, nullptr, 0, &numConfigs);
EGLConfig* const configs = new EGLConfig[numConfigs];
eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7e308e8..e967265 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -382,7 +382,7 @@
sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
- return NULL;
+ return nullptr;
}
return mBuiltinDisplays[id];
}
@@ -531,7 +531,7 @@
}
}
- if (callback != NULL) {
+ if (callback != nullptr) {
callback->onVSyncEvent(when);
}
}
@@ -737,7 +737,7 @@
status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
Vector<DisplayInfo>* configs) {
- if ((configs == NULL) || (display.get() == NULL)) {
+ if (configs == nullptr || display.get() == nullptr) {
return BAD_VALUE;
}
@@ -761,7 +761,7 @@
static int getDensityFromProperty(char const* propName) {
char property[PROPERTY_VALUE_MAX];
int density = 0;
- if (property_get(propName, property, NULL) > 0) {
+ if (property_get(propName, property, nullptr) > 0) {
density = atoi(property);
}
return density;
@@ -842,7 +842,7 @@
status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
DisplayStatInfo* stats) {
- if (stats == NULL) {
+ if (stats == nullptr) {
return BAD_VALUE;
}
@@ -854,13 +854,13 @@
}
int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
- if (display == NULL) {
- ALOGE("%s : display is NULL", __func__);
+ if (display == nullptr) {
+ ALOGE("%s : display is nullptr", __func__);
return BAD_VALUE;
}
sp<const DisplayDevice> device(getDisplayDevice(display));
- if (device != NULL) {
+ if (device != nullptr) {
return device->getActiveConfig();
}
@@ -905,7 +905,7 @@
return true;
}
sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
- if (hw == NULL) {
+ if (hw == nullptr) {
ALOGE("Attempt to set active config = %d for null display %p",
mMode, mDisplay.get());
} else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
@@ -2165,7 +2165,7 @@
const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
defaultDisplay->makeCurrent();
sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));
- if (hw != NULL)
+ if (hw != nullptr)
hw->disconnect(getHwComposer());
if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
mEventThread->onHotplugReceived(draw[i].type, false);
@@ -2185,7 +2185,7 @@
// from the drawing state, so that it get re-added
// below.
sp<DisplayDevice> hw(getDisplayDeviceLocked(display));
- if (hw != NULL)
+ if (hw != nullptr)
hw->disconnect(getHwComposer());
mDisplays.removeItem(display);
mDrawingState.displays.removeItemsAt(i);
@@ -2195,7 +2195,7 @@
}
const sp<DisplayDevice> disp(getDisplayDeviceLocked(display));
- if (disp != NULL) {
+ if (disp != nullptr) {
if (state.layerStack != draw[i].layerStack) {
disp->setLayerStack(state.layerStack);
}
@@ -2231,7 +2231,7 @@
// Virtual displays without a surface are dormant:
// they have external state (layer stack, projection,
// etc.) but no internal state (i.e. a DisplayDevice).
- if (state.surface != NULL) {
+ if (state.surface != nullptr) {
// Allow VR composer to use virtual displays.
if (mUseHwcVirtualDisplays || getBE().mHwc->isUsingVrComposer()) {
@@ -2268,7 +2268,7 @@
producer = vds;
}
} else {
- ALOGE_IF(state.surface!=NULL,
+ ALOGE_IF(state.surface != nullptr,
"adding a supported display, but rendering "
"surface is provided (%p), ignoring it",
state.surface.get());
@@ -2279,7 +2279,7 @@
}
const wp<IBinder>& display(curr.keyAt(i));
- if (dispSurface != NULL) {
+ if (dispSurface != nullptr) {
sp<DisplayDevice> hw =
new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
dispSurface, producer, hasWideColorDisplay);
@@ -2334,10 +2334,10 @@
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
sp<const DisplayDevice> hw(mDisplays[dpy]);
if (layer->belongsToDisplay(hw->getLayerStack(), hw->isPrimary())) {
- if (disp == NULL) {
+ if (disp == nullptr) {
disp = std::move(hw);
} else {
- disp = NULL;
+ disp = nullptr;
break;
}
}
@@ -2345,7 +2345,7 @@
}
if (transactionFlags & eDisplayTransactionNeeded) {
- if (disp == NULL) {
+ if (disp == nullptr) {
// NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
// redraw after transform hint changes. See bug 8508397.
@@ -2941,16 +2941,16 @@
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
// Here we need to check that the interface we're given is indeed
- // one of our own. A malicious client could give us a NULL
+ // one of our own. A malicious client could give us a nullptr
// IInterface, or one of its own or even one of our own but a
// different type. All these situations would cause us to crash.
//
// NOTE: it would be better to use RTTI as we could directly check
// that we have a Client*. however, RTTI is disabled in Android.
- if (s.client != NULL) {
+ if (s.client != nullptr) {
sp<IBinder> binder = IInterface::asBinder(s.client);
- if (binder != NULL) {
- if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) {
+ if (binder != nullptr) {
+ if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != nullptr) {
sp<Client> client( static_cast<Client *>(s.client.get()) );
transactionFlags |= setClientStateLocked(client, s.state);
}
@@ -3324,7 +3324,7 @@
// called by a client when it wants to remove a Layer
status_t err = NO_ERROR;
sp<Layer> l(client->getLayerUser(handle));
- if (l != NULL) {
+ if (l != nullptr) {
mInterceptor.saveSurfaceDeletion(l);
err = removeLayer(l);
ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
@@ -3489,7 +3489,7 @@
mDisplay(disp) { mMode = mode; }
virtual bool handler() {
sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
- if (hw == NULL) {
+ if (hw == nullptr) {
ALOGE("Attempt to set power mode = %d for null display %p",
mMode, mDisplay.get());
} else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
@@ -3978,7 +3978,7 @@
break;
}
}
- if (dpy == NULL) {
+ if (dpy == nullptr) {
ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
// Just use the primary display so we have something to return
dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
@@ -4245,7 +4245,7 @@
reply->writeBool(hasWideColorDisplay);
return NO_ERROR;
}
- case 1025: { // tracing
+ case 1025: { // Set layer tracing
n = data.readInt32();
if (n) {
ALOGV("LayerTracing enabled");
@@ -4259,6 +4259,10 @@
}
return NO_ERROR;
}
+ case 1026: { // Get layer tracing status
+ reply->writeBool(mTracing.isEnabled());
+ return NO_ERROR;
+ }
}
}
return err;
@@ -4306,7 +4310,7 @@
}
status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
- sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
+ sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
float frameScale) {
ATRACE_CALL();
@@ -4400,6 +4404,9 @@
int syncFd = -1;
std::optional<status_t> captureResult;
+ const int uid = IPCThreadState::self()->getCallingUid();
+ const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
+
sp<LambdaMessage> message = new LambdaMessage([&]() {
// If there is a refresh pending, bug out early and tell the binder thread to try again
// after the refresh.
@@ -4416,7 +4423,7 @@
{
Mutex::Autolock _l(mStateLock);
result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
- useIdentityTransform, &fd);
+ useIdentityTransform, forSystem, &fd);
}
{
@@ -4513,6 +4520,7 @@
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer,
bool useIdentityTransform,
+ bool forSystem,
int* outSyncFd) {
ATRACE_CALL();
@@ -4522,7 +4530,10 @@
secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() && layer->isSecure());
});
- if (secureLayerIsVisible) {
+ // We allow the system server to take screenshots of secure layers for
+ // use in situations like the Screen-rotation animation and place
+ // the impetus on WindowManager to not persist them.
+ if (secureLayerIsVisible && !forSystem) {
ALOGW("FB is protected: PERMISSION_DENIED");
return PERMISSION_DENIED;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 2477bdc..8030fbd 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -524,7 +524,7 @@
status_t captureScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer, bool useIdentityTransform,
- int* outSyncFd);
+ bool forSystem, int* outSyncFd);
void traverseLayersInDisplay(const sp<const DisplayDevice>& display, int32_t minLayerZ,
int32_t maxLayerZ, const LayerVector::Visitor& visitor);
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index ed806b8..de78c3f 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -148,7 +148,7 @@
mBGSurfaceControl = mComposerClient->createSurface(
String8("BG Interceptor Test Surface"), displayWidth, displayHeight,
PIXEL_FORMAT_RGBA_8888, 0);
- ASSERT_TRUE(mBGSurfaceControl != NULL);
+ ASSERT_TRUE(mBGSurfaceControl != nullptr);
ASSERT_TRUE(mBGSurfaceControl->isValid());
mBGLayerId = getSurfaceId("BG Interceptor Test Surface");
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index ff81dc9..ac8a2ad 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -148,8 +148,8 @@
bool unlock = true) {
ANativeWindow_Buffer outBuffer;
sp<Surface> s = sc->getSurface();
- ASSERT_TRUE(s != NULL);
- ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, NULL));
+ ASSERT_TRUE(s != nullptr);
+ ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr));
uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
for (int y = 0; y < outBuffer.height; y++) {
for (int x = 0; x < outBuffer.width; x++) {
@@ -279,7 +279,7 @@
private:
sp<GraphicBuffer> mOutBuffer;
- uint8_t* mPixels = NULL;
+ uint8_t* mPixels = nullptr;
};
class LayerTransactionTest : public ::testing::Test {
@@ -1483,14 +1483,14 @@
mBGSurfaceControl =
mComposerClient->createSurface(String8("BG Test Surface"), displayWidth,
displayHeight, PIXEL_FORMAT_RGBA_8888, 0);
- ASSERT_TRUE(mBGSurfaceControl != NULL);
+ ASSERT_TRUE(mBGSurfaceControl != nullptr);
ASSERT_TRUE(mBGSurfaceControl->isValid());
fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
// Foreground surface
mFGSurfaceControl = mComposerClient->createSurface(String8("FG Test Surface"), 64, 64,
PIXEL_FORMAT_RGBA_8888, 0);
- ASSERT_TRUE(mFGSurfaceControl != NULL);
+ ASSERT_TRUE(mFGSurfaceControl != nullptr);
ASSERT_TRUE(mFGSurfaceControl->isValid());
fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
@@ -1498,7 +1498,7 @@
// Synchronization surface
mSyncSurfaceControl = mComposerClient->createSurface(String8("Sync Test Surface"), 1, 1,
PIXEL_FORMAT_RGBA_8888, 0);
- ASSERT_TRUE(mSyncSurfaceControl != NULL);
+ ASSERT_TRUE(mSyncSurfaceControl != nullptr);
ASSERT_TRUE(mSyncSurfaceControl->isValid());
fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
@@ -2018,7 +2018,7 @@
mNewComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- ASSERT_TRUE(mChildNewClient != NULL);
+ ASSERT_TRUE(mChildNewClient != nullptr);
ASSERT_TRUE(mChildNewClient->isValid());
fillSurfaceRGBA8(mChildNewClient, 200, 200, 200);
@@ -2210,7 +2210,7 @@
TEST_F(ChildLayerTest, ReparentFromNoParent) {
sp<SurfaceControl> newSurface = mComposerClient->createSurface(String8("New Surface"), 10, 10,
PIXEL_FORMAT_RGBA_8888, 0);
- ASSERT_TRUE(newSurface != NULL);
+ ASSERT_TRUE(newSurface != nullptr);
ASSERT_TRUE(newSurface->isValid());
fillSurfaceRGBA8(newSurface, 63, 195, 63);