Merge "libui: OWNERS"
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 005564d..1a1b010 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -64,6 +64,7 @@
#define ASENSOR_RESOLUTION_INVALID (nanf(""))
#define ASENSOR_FIFO_COUNT_INVALID (-1)
#define ASENSOR_DELAY_INVALID INT32_MIN
+#define ASENSOR_INVALID (-1)
/* (Keep in sync with hardware/sensors-base.h and Sensor.java.) */
@@ -208,6 +209,35 @@
*/
ASENSOR_TYPE_HEART_BEAT = 31,
/**
+ * This sensor type is for delivering additional sensor information aside
+ * from sensor event data.
+ *
+ * Additional information may include:
+ * - {@link ASENSOR_ADDITIONAL_INFO_INTERNAL_TEMPERATURE}
+ * - {@link ASENSOR_ADDITIONAL_INFO_SAMPLING}
+ * - {@link ASENSOR_ADDITIONAL_INFO_SENSOR_PLACEMENT}
+ * - {@link ASENSOR_ADDITIONAL_INFO_UNTRACKED_DELAY}
+ * - {@link ASENSOR_ADDITIONAL_INFO_VEC3_CALIBRATION}
+ *
+ * This type will never bind to a sensor. In other words, no sensor in the
+ * sensor list can have the type {@link ASENSOR_TYPE_ADDITIONAL_INFO}.
+ *
+ * If a device supports the sensor additional information feature, it will
+ * report additional information events via {@link ASensorEvent} and will
+ * have {@link ASensorEvent#type} set to
+ * {@link ASENSOR_TYPE_ADDITIONAL_INFO} and {@link ASensorEvent#sensor} set
+ * to the handle of the reporting sensor.
+ *
+ * Additional information reports consist of multiple frames ordered by
+ * {@link ASensorEvent#timestamp}. The first frame in the report will have
+ * a {@link AAdditionalInfoEvent#type} of
+ * {@link ASENSOR_ADDITIONAL_INFO_BEGIN}, and the last frame in the report
+ * will have a {@link AAdditionalInfoEvent#type} of
+ * {@link ASENSOR_ADDITIONAL_INFO_END}.
+ *
+ */
+ ASENSOR_TYPE_ADDITIONAL_INFO = 33,
+ /**
* {@link ASENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT}
*/
ASENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT = 34,
@@ -273,6 +303,51 @@
ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER = 2
};
+/**
+ * Sensor Additional Info Types.
+ *
+ * Used to populate {@link AAdditionalInfoEvent#type}.
+ */
+enum {
+ /** Marks the beginning of additional information frames */
+ ASENSOR_ADDITIONAL_INFO_BEGIN = 0,
+
+ /** Marks the end of additional information frames */
+ ASENSOR_ADDITIONAL_INFO_END = 1,
+
+ /**
+ * Estimation of the delay that is not tracked by sensor timestamps. This
+ * includes delay introduced by sensor front-end filtering, data transport,
+ * etc.
+ * float[2]: delay in seconds, standard deviation of estimated value
+ */
+ ASENSOR_ADDITIONAL_INFO_UNTRACKED_DELAY = 0x10000,
+
+ /** float: Celsius temperature */
+ ASENSOR_ADDITIONAL_INFO_INTERNAL_TEMPERATURE,
+
+ /**
+ * First three rows of a homogeneous matrix, which represents calibration to
+ * a three-element vector raw sensor reading.
+ * float[12]: 3x4 matrix in row major order
+ */
+ ASENSOR_ADDITIONAL_INFO_VEC3_CALIBRATION,
+
+ /**
+ * Location and orientation of sensor element in the device frame: origin is
+ * the geometric center of the mobile device screen surface; the axis
+ * definition corresponds to Android sensor definitions.
+ * float[12]: 3x4 matrix in row major order
+ */
+ ASENSOR_ADDITIONAL_INFO_SENSOR_PLACEMENT,
+
+ /**
+ * float[2]: raw sample period in seconds,
+ * standard deviation of sampling period
+ */
+ ASENSOR_ADDITIONAL_INFO_SAMPLING,
+};
+
/*
* A few useful constants
*/
@@ -341,7 +416,7 @@
int32_t handle;
} ADynamicSensorEvent;
-typedef struct {
+typedef struct AAdditionalInfoEvent {
int32_t type;
int32_t serial;
union {
@@ -444,6 +519,7 @@
* - ASensor_getStringType()
* - ASensor_getReportingMode()
* - ASensor_isWakeUpSensor()
+ * - ASensor_getHandle()
*/
typedef struct ASensor ASensor;
/**
@@ -785,6 +861,24 @@
int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor) __INTRODUCED_IN(26);
#endif /* __ANDROID_API__ >= 26 */
+#if __ANDROID_API__ >= __ANDROID_API_Q__
+/**
+ * Returns the sensor's handle.
+ *
+ * The handle identifies the sensor within the system and is included in the
+ * {@link ASensorEvent#sensor} field of sensor events, including those sent with type
+ * {@link ASENSOR_TYPE_ADDITIONAL_INFO}.
+ *
+ * A sensor's handle is able to be used to map {@link ASENSOR_TYPE_ADDITIONAL_INFO} events to the
+ * sensor that generated the event.
+ *
+ * It is important to note that the value returned by {@link ASensor_getHandle} is not the same as
+ * the value returned by the Java API {@link android.hardware.Sensor#getId} and no mapping exists
+ * between the values.
+ */
+int ASensor_getHandle(ASensor const* sensor) __INTRODUCED_IN(__ANDROID_API_Q__);
+#endif /* __ANDROID_API__ >= ANDROID_API_Q__ */
+
#ifdef __cplusplus
};
#endif
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index f6cc3af..96ee295 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -86,6 +86,10 @@
class BBinder::Extras
{
public:
+ // unlocked objects
+ bool mRequestingSid = false;
+
+ // for below objects
Mutex mLock;
BpBinder::ObjectManager mObjects;
};
@@ -163,19 +167,8 @@
const void* objectID, void* object, void* cleanupCookie,
object_cleanup_func func)
{
- Extras* e = mExtras.load(std::memory_order_acquire);
-
- if (!e) {
- e = new Extras;
- Extras* expected = nullptr;
- if (!mExtras.compare_exchange_strong(expected, e,
- std::memory_order_release,
- std::memory_order_acquire)) {
- delete e;
- e = expected; // Filled in by CAS
- }
- if (e == nullptr) return; // out of memory
- }
+ Extras* e = getOrCreateExtras();
+ if (!e) return; // out of memory
AutoMutex _l(e->mLock);
e->mObjects.attach(objectID, object, cleanupCookie, func);
@@ -204,6 +197,30 @@
return this;
}
+bool BBinder::isRequestingSid()
+{
+ Extras* e = mExtras.load(std::memory_order_acquire);
+
+ return e && e->mRequestingSid;
+}
+
+void BBinder::setRequestingSid(bool requestingSid)
+{
+ Extras* e = mExtras.load(std::memory_order_acquire);
+
+ if (!e) {
+ // default is false. Most things don't need sids, so avoiding allocations when possible.
+ if (!requestingSid) {
+ return;
+ }
+
+ e = getOrCreateExtras();
+ if (!e) return; // out of memory
+ }
+
+ e->mRequestingSid = true;
+}
+
BBinder::~BBinder()
{
Extras* e = mExtras.load(std::memory_order_relaxed);
@@ -267,6 +284,25 @@
}
}
+BBinder::Extras* BBinder::getOrCreateExtras()
+{
+ Extras* e = mExtras.load(std::memory_order_acquire);
+
+ if (!e) {
+ e = new Extras;
+ Extras* expected = nullptr;
+ if (!mExtras.compare_exchange_strong(expected, e,
+ std::memory_order_release,
+ std::memory_order_acquire)) {
+ delete e;
+ e = expected; // Filled in by CAS
+ }
+ if (e == nullptr) return nullptr; // out of memory
+ }
+
+ return e;
+}
+
// ---------------------------------------------------------------------------
enum {
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 1d4e234..9a561cb 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -88,7 +88,8 @@
"BR_FINISHED",
"BR_DEAD_BINDER",
"BR_CLEAR_DEATH_NOTIFICATION_DONE",
- "BR_FAILED_REPLY"
+ "BR_FAILED_REPLY",
+ "BR_TRANSACTION_SEC_CTX",
};
static const char *kCommandStrings[] = {
@@ -365,6 +366,11 @@
return mCallingPid;
}
+const char* IPCThreadState::getCallingSid() const
+{
+ return mCallingSid;
+}
+
uid_t IPCThreadState::getCallingUid() const
{
return mCallingUid;
@@ -372,6 +378,7 @@
int64_t IPCThreadState::clearCallingIdentity()
{
+ // ignore mCallingSid for legacy reasons
int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
clearCaller();
return token;
@@ -442,12 +449,14 @@
void IPCThreadState::restoreCallingIdentity(int64_t token)
{
mCallingUid = (int)(token>>32);
+ mCallingSid = nullptr; // not enough data to restore
mCallingPid = (int)token;
}
void IPCThreadState::clearCaller()
{
mCallingPid = getpid();
+ mCallingSid = nullptr; // expensive to lookup
mCallingUid = getuid();
}
@@ -1135,10 +1144,19 @@
}
break;
+ case BR_TRANSACTION_SEC_CTX:
case BR_TRANSACTION:
{
- binder_transaction_data tr;
- result = mIn.read(&tr, sizeof(tr));
+ binder_transaction_data_secctx tr_secctx;
+ binder_transaction_data& tr = tr_secctx.transaction_data;
+
+ if (cmd == (int) BR_TRANSACTION_SEC_CTX) {
+ result = mIn.read(&tr_secctx, sizeof(tr_secctx));
+ } else {
+ result = mIn.read(&tr, sizeof(tr));
+ tr_secctx.secctx = 0;
+ }
+
ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
@@ -1154,6 +1172,7 @@
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
const pid_t origPid = mCallingPid;
+ const char* origSid = mCallingSid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
@@ -1166,10 +1185,12 @@
clearPropagateWorkSource();
mCallingPid = tr.sender_pid;
+ mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
- //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
+ // ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid,
+ // (mCallingSid ? mCallingSid : "<N/A>"), mCallingUid);
Parcel reply;
status_t error;
@@ -1201,8 +1222,8 @@
}
mIPCThreadStateBase->popCurrentState();
- //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
- // mCallingPid, origPid, origUid);
+ //ALOGI("<<<< TRANSACT from pid %d restore pid %d sid %s uid %d\n",
+ // mCallingPid, origPid, (origSid ? origSid : "<N/A>"), origUid);
if ((tr.flags & TF_ONE_WAY) == 0) {
LOG_ONEWAY("Sending reply to %d!", mCallingPid);
@@ -1213,6 +1234,7 @@
}
mCallingPid = origPid;
+ mCallingSid = origSid;
mCallingUid = origUid;
mStrictModePolicy = origStrictModePolicy;
mLastTransactionBinderFlags = origTransactionBinderFlags;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index d285030..f779d6e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -220,7 +220,7 @@
}
if (binder != nullptr) {
- IBinder *local = binder->localBinder();
+ BBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == nullptr) {
@@ -232,6 +232,9 @@
obj.handle = handle;
obj.cookie = 0;
} else {
+ if (local->isRequestingSid()) {
+ obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
+ }
obj.hdr.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 3798b61..79db0cb 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -181,8 +181,20 @@
mBinderContextCheckFunc = checkFunc;
mBinderContextUserData = userData;
- int dummy = 0;
- status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
+ flat_binder_object obj {
+ .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
+ };
+
+ status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj);
+
+ // fallback to original method
+ if (result != 0) {
+ android_errorWriteLog(0x534e4554, "121035042");
+
+ int dummy = 0;
+ result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
+ }
+
if (result == 0) {
mManagesContexts = true;
} else if (result == -1) {
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index c251468..cf3ef84 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -60,6 +60,10 @@
virtual BBinder* localBinder();
+ bool isRequestingSid();
+ // This must be called before the object is sent to another process. Not thread safe.
+ void setRequestingSid(bool requestSid);
+
protected:
virtual ~BBinder();
@@ -75,6 +79,8 @@
class Extras;
+ Extras* getOrCreateExtras();
+
std::atomic<Extras*> mExtras;
void* mReserved0;
};
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index a6b0f7e..614b0b3 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -42,6 +42,11 @@
status_t clearLastError();
pid_t getCallingPid() const;
+ // nullptr if unavailable
+ //
+ // this can't be restored once it's cleared, and it does not return the
+ // context of the current process when not in a binder call.
+ const char* getCallingSid() const;
uid_t getCallingUid() const;
void setStrictModePolicy(int32_t policy);
@@ -64,6 +69,7 @@
int32_t getLastTransactionBinderFlags() const;
int64_t clearCallingIdentity();
+ // Restores PID/UID (not SID)
void restoreCallingIdentity(int64_t token);
int setupPolling(int* fd);
@@ -174,6 +180,7 @@
Parcel mOut;
status_t mLastError;
pid_t mCallingPid;
+ const char* mCallingSid;
uid_t mCallingUid;
// The UID of the process who is responsible for this transaction.
// This is used for resource attribution.
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index cd151ee..240b708 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -27,8 +27,8 @@
#include <utils/String16.h>
#include <utils/Vector.h>
#include <utils/Flattenable.h>
-#include <linux/android/binder.h>
+#include <binder/binder_kernel.h>
#include <binder/IInterface.h>
#include <binder/Parcelable.h>
#include <binder/Map.h>
diff --git a/libs/binder/include/binder/binder_kernel.h b/libs/binder/include/binder/binder_kernel.h
new file mode 100644
index 0000000..c7f6b4b
--- /dev/null
+++ b/libs/binder/include/binder/binder_kernel.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BINDER_KERNEL_H
+#define ANDROID_BINDER_KERNEL_H
+
+#include <linux/android/binder.h>
+
+/**
+ * This file exists because the uapi kernel headers in bionic are built
+ * from upstream kernel headers only, and not all of the hwbinder kernel changes
+ * have made it upstream yet. Therefore, the modifications to the
+ * binder header are added locally in this file.
+ */
+
+enum {
+ FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
+};
+
+#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
+
+struct binder_transaction_data_secctx {
+ struct binder_transaction_data transaction_data;
+ binder_uintptr_t secctx;
+};
+
+enum {
+ BR_TRANSACTION_SEC_CTX = _IOR('r', 2,
+ struct binder_transaction_data_secctx),
+};
+
+#endif // ANDROID_BINDER_KERNEL_H
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index 1be55e6..ce88d7b 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -39,7 +39,16 @@
if (err != NO_ERROR) {
return err;
}
- return output->writeBool(releasePreviousBuffer);
+ if (previousReleaseFence) {
+ err = output->writeBool(true);
+ if (err != NO_ERROR) {
+ return err;
+ }
+ err = output->write(*previousReleaseFence);
+ } else {
+ err = output->writeBool(false);
+ }
+ return err;
}
status_t SurfaceStats::readFromParcel(const Parcel* input) {
@@ -51,7 +60,19 @@
if (err != NO_ERROR) {
return err;
}
- return input->readBool(&releasePreviousBuffer);
+ bool hasFence = false;
+ err = input->readBool(&hasFence);
+ if (err != NO_ERROR) {
+ return err;
+ }
+ if (hasFence) {
+ previousReleaseFence = new Fence();
+ err = input->read(*previousReleaseFence);
+ if (err != NO_ERROR) {
+ return err;
+ }
+ }
+ return NO_ERROR;
}
status_t TransactionStats::writeToParcel(Parcel* output) const {
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index 537c957..b377a41 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -40,13 +40,14 @@
#define BQ_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
-#define ATRACE_BUFFER_INDEX(index) \
- if (ATRACE_ENABLED()) { \
- char ___traceBuf[1024]; \
- snprintf(___traceBuf, 1024, "%s: %d", \
- mCore->mConsumerName.string(), (index)); \
- android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \
- }
+#define ATRACE_BUFFER_INDEX(index) \
+ do { \
+ if (ATRACE_ENABLED()) { \
+ char ___traceBuf[1024]; \
+ snprintf(___traceBuf, 1024, "%s: %d", mCore->mConsumerName.string(), (index)); \
+ android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \
+ } \
+ } while (false)
namespace android {
diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h
index 8acfa7a..29ab026 100644
--- a/libs/gui/include/gui/ITransactionCompletedListener.h
+++ b/libs/gui/include/gui/ITransactionCompletedListener.h
@@ -52,12 +52,12 @@
status_t readFromParcel(const Parcel* input) override;
SurfaceStats() = default;
- SurfaceStats(const sp<IBinder>& sc, nsecs_t time, bool releasePrevBuffer)
- : surfaceControl(sc), acquireTime(time), releasePreviousBuffer(releasePrevBuffer) {}
+ SurfaceStats(const sp<IBinder>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence)
+ : surfaceControl(sc), acquireTime(time), previousReleaseFence(prevReleaseFence) {}
sp<IBinder> surfaceControl;
nsecs_t acquireTime = -1;
- bool releasePreviousBuffer = false;
+ sp<Fence> previousReleaseFence;
};
class TransactionStats : public Parcelable {
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index e0d9d23..2132f59 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -48,10 +48,28 @@
// Interface implementation for Layer
// -----------------------------------------------------------------------
void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
- // The transaction completed callback can only be sent if the release fence from the PREVIOUS
- // frame has fired. In practice, we should never actually wait on the previous release fence
- // but we should store it just in case.
- mPreviousReleaseFence = releaseFence;
+ // The previous release fence notifies the client that SurfaceFlinger is done with the previous
+ // buffer that was presented on this layer. The first transaction that came in this frame that
+ // replaced the previous buffer on this layer needs this release fence, because the fence will
+ // let the client know when that previous buffer is removed from the screen.
+ //
+ // Every other transaction on this layer does not need a release fence because no other
+ // Transactions that were set on this layer this frame are going to have their preceeding buffer
+ // removed from the display this frame.
+ //
+ // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
+ // buffer so it doesn't need a previous release fence because the layer still needs the previous
+ // buffer. The second transaction contains a buffer so it needs a previous release fence because
+ // the previous buffer will be released this frame. The third transaction also contains a
+ // buffer. It replaces the buffer in the second transaction. The buffer in the second
+ // transaction will now no longer be presented so it is released immediately and the third
+ // transaction doesn't need a previous release fence.
+ for (auto& handle : mDrawingState.callbackHandles) {
+ if (handle->releasePreviousBuffer) {
+ handle->previousReleaseFence = releaseFence;
+ break;
+ }
+ }
}
void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const {
@@ -60,7 +78,10 @@
}
void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) {
- return;
+ mFlinger->getTransactionCompletedThread().addPresentedCallbackHandles(
+ mDrawingState.callbackHandles);
+
+ mDrawingState.callbackHandles = {};
}
bool BufferStateLayer::shouldPresentNow(nsecs_t /*expectedPresentTime*/) const {
@@ -257,14 +278,14 @@
// Notify the transaction completed thread that there is a pending latched callback
// handle
- mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
+ mFlinger->getTransactionCompletedThread().registerPendingCallbackHandle(handle);
// Store so latched time and release fence can be set
mCurrentState.callbackHandles.push_back(handle);
} else { // If this layer will NOT need to be relatched and presented this frame
// Notify the transaction completed thread this handle is done
- mFlinger->getTransactionCompletedThread().addUnlatchedCallbackHandle(handle);
+ mFlinger->getTransactionCompletedThread().addUnpresentedCallbackHandle(handle);
}
}
@@ -504,9 +525,9 @@
return BAD_VALUE;
}
- mFlinger->getTransactionCompletedThread()
- .addLatchedCallbackHandles(getDrawingState().callbackHandles, latchTime,
- mPreviousReleaseFence);
+ for (auto& handle : mDrawingState.callbackHandles) {
+ handle->latchTime = latchTime;
+ }
// Handle sync fences
if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp
index a1a8692..d2b7fe0 100644
--- a/services/surfaceflinger/TransactionCompletedThread.cpp
+++ b/services/surfaceflinger/TransactionCompletedThread.cpp
@@ -62,8 +62,7 @@
mThread = std::thread(&TransactionCompletedThread::threadMain, this);
}
-void TransactionCompletedThread::registerPendingLatchedCallbackHandle(
- const sp<CallbackHandle>& handle) {
+void TransactionCompletedThread::registerPendingCallbackHandle(const sp<CallbackHandle>& handle) {
std::lock_guard lock(mMutex);
sp<IBinder> listener = IInterface::asBinder(handle->listener);
@@ -72,19 +71,10 @@
mPendingTransactions[listener][callbackIds]++;
}
-void TransactionCompletedThread::addLatchedCallbackHandles(
- const std::deque<sp<CallbackHandle>>& handles, nsecs_t latchTime,
- const sp<Fence>& previousReleaseFence) {
+void TransactionCompletedThread::addPresentedCallbackHandles(
+ const std::deque<sp<CallbackHandle>>& handles) {
std::lock_guard lock(mMutex);
- // If the previous release fences have not signaled, something as probably gone wrong.
- // Store the fences and check them again before sending a callback.
- if (previousReleaseFence &&
- previousReleaseFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
- ALOGD("release fence from the previous frame has not signaled");
- mPreviousReleaseFences.push_back(previousReleaseFence);
- }
-
for (const auto& handle : handles) {
auto listener = mPendingTransactions.find(IInterface::asBinder(handle->listener));
auto& pendingCallbacks = listener->second;
@@ -101,17 +91,16 @@
ALOGE("there are more latched callbacks than there were registered callbacks");
}
- addCallbackHandle(handle, latchTime);
+ addCallbackHandle(handle);
}
}
-void TransactionCompletedThread::addUnlatchedCallbackHandle(const sp<CallbackHandle>& handle) {
+void TransactionCompletedThread::addUnpresentedCallbackHandle(const sp<CallbackHandle>& handle) {
std::lock_guard lock(mMutex);
addCallbackHandle(handle);
}
-void TransactionCompletedThread::addCallbackHandle(const sp<CallbackHandle>& handle,
- nsecs_t latchTime) {
+void TransactionCompletedThread::addCallbackHandle(const sp<CallbackHandle>& handle) {
const sp<IBinder> listener = IInterface::asBinder(handle->listener);
// If we don't already have a reference to this listener, linkToDeath so we get a notification
@@ -128,9 +117,9 @@
listenerStats.listener = handle->listener;
auto& transactionStats = listenerStats.transactionStats[handle->callbackIds];
- transactionStats.latchTime = latchTime;
+ transactionStats.latchTime = handle->latchTime;
transactionStats.surfaceStats.emplace_back(handle->surfaceControl, handle->acquireTime,
- handle->releasePreviousBuffer);
+ handle->previousReleaseFence);
}
void TransactionCompletedThread::addPresentFence(const sp<Fence>& presentFence) {
@@ -151,15 +140,6 @@
while (mKeepRunning) {
mConditionVariable.wait(mMutex);
- // We should never hit this case. The release fences from the previous frame should have
- // signaled long before the current frame is presented.
- for (const auto& fence : mPreviousReleaseFences) {
- status_t status = fence->wait(100);
- if (status != NO_ERROR) {
- ALOGE("previous release fence has not signaled, err %d", status);
- }
- }
-
// For each listener
auto it = mListenerStats.begin();
while (it != mListenerStats.end()) {
@@ -200,7 +180,6 @@
if (mPresentFence) {
mPresentFence.clear();
- mPreviousReleaseFences.clear();
}
}
}
diff --git a/services/surfaceflinger/TransactionCompletedThread.h b/services/surfaceflinger/TransactionCompletedThread.h
index 1612f69..f49306d 100644
--- a/services/surfaceflinger/TransactionCompletedThread.h
+++ b/services/surfaceflinger/TransactionCompletedThread.h
@@ -40,7 +40,9 @@
sp<IBinder> surfaceControl;
bool releasePreviousBuffer = false;
+ sp<Fence> previousReleaseFence;
nsecs_t acquireTime = -1;
+ nsecs_t latchTime = -1;
};
class TransactionCompletedThread {
@@ -54,14 +56,13 @@
// layer has received the CallbackHandle so the TransactionCompletedThread knows not to send
// a callback for that Listener/Transaction pair until that CallbackHandle has been latched and
// presented.
- void registerPendingLatchedCallbackHandle(const sp<CallbackHandle>& handle);
- // Notifies the TransactionCompletedThread that a pending CallbackHandle has been latched.
- void addLatchedCallbackHandles(const std::deque<sp<CallbackHandle>>& handles, nsecs_t latchTime,
- const sp<Fence>& previousReleaseFence);
+ void registerPendingCallbackHandle(const sp<CallbackHandle>& handle);
+ // Notifies the TransactionCompletedThread that a pending CallbackHandle has been presented.
+ void addPresentedCallbackHandles(const std::deque<sp<CallbackHandle>>& handles);
// Adds the Transaction CallbackHandle from a layer that does not need to be relatched and
// presented this frame.
- void addUnlatchedCallbackHandle(const sp<CallbackHandle>& handle);
+ void addUnpresentedCallbackHandle(const sp<CallbackHandle>& handle);
void addPresentFence(const sp<Fence>& presentFence);
@@ -70,8 +71,7 @@
private:
void threadMain();
- void addCallbackHandle(const sp<CallbackHandle>& handle, nsecs_t latchTime = -1)
- REQUIRES(mMutex);
+ void addCallbackHandle(const sp<CallbackHandle>& handle) REQUIRES(mMutex);
class ThreadDeathRecipient : public IBinder::DeathRecipient {
public:
@@ -110,7 +110,6 @@
bool mKeepRunning GUARDED_BY(mMutex) = true;
sp<Fence> mPresentFence GUARDED_BY(mMutex);
- std::vector<sp<Fence>> mPreviousReleaseFences GUARDED_BY(mMutex);
};
} // namespace android
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index ef6999d..9339761 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -2542,6 +2542,7 @@
enum PreviousBuffer {
NOT_RELEASED = 0,
RELEASED,
+ UNKNOWN,
};
void reset() {
@@ -2596,14 +2597,19 @@
: mBufferResult(bufferResult), mPreviousBufferResult(previousBufferResult) {}
void verifySurfaceStats(const SurfaceStats& surfaceStats, nsecs_t latchTime) const {
- const auto& [surfaceControl, acquireTime, releasePreviousBuffer] = surfaceStats;
+ const auto& [surfaceControl, acquireTime, previousReleaseFence] = surfaceStats;
ASSERT_EQ(acquireTime > 0, mBufferResult == ExpectedResult::Buffer::ACQUIRED)
<< "bad acquire time";
ASSERT_LE(acquireTime, latchTime) << "acquire time should be <= latch time";
- ASSERT_EQ(releasePreviousBuffer,
- mPreviousBufferResult == ExpectedResult::PreviousBuffer::RELEASED)
- << "bad previous buffer released";
+
+ if (mPreviousBufferResult == ExpectedResult::PreviousBuffer::RELEASED) {
+ ASSERT_NE(previousReleaseFence, nullptr)
+ << "failed to set release prev buffer fence";
+ } else if (mPreviousBufferResult == ExpectedResult::PreviousBuffer::NOT_RELEASED) {
+ ASSERT_EQ(previousReleaseFence, nullptr)
+ << "should not have set released prev buffer fence";
+ }
}
private:
@@ -3177,13 +3183,11 @@
Transaction transaction;
CallbackHelper callback;
std::vector<ExpectedResult> expectedResults(50);
- ExpectedResult::PreviousBuffer previousBufferResult =
- ExpectedResult::PreviousBuffer::NOT_RELEASED;
for (auto& expected : expectedResults) {
expected.reset();
expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
- ExpectedResult::Buffer::ACQUIRED, previousBufferResult);
- previousBufferResult = ExpectedResult::PreviousBuffer::RELEASED;
+ ExpectedResult::Buffer::ACQUIRED,
+ ExpectedResult::PreviousBuffer::UNKNOWN);
int err = fillTransaction(transaction, &callback, layer);
if (err) {