Merge "servicemanager: vintf declared API"
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 2c3efe5..99cb93a 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -141,7 +141,7 @@
}
}
- PipeRelay relay(out);
+ PipeRelay relay(out, err, interfaceName, instanceName);
if (relay.initCheck() != OK) {
std::string msg = "PipeRelay::initCheck() FAILED w/ " + std::to_string(relay.initCheck());
diff --git a/cmds/lshal/PipeRelay.cpp b/cmds/lshal/PipeRelay.cpp
index 820679f..4e97636 100644
--- a/cmds/lshal/PipeRelay.cpp
+++ b/cmds/lshal/PipeRelay.cpp
@@ -23,7 +23,6 @@
#include <atomic>
-#include <android-base/logging.h>
#include <utils/Thread.h>
namespace android {
@@ -31,8 +30,15 @@
static constexpr struct timeval READ_TIMEOUT { .tv_sec = 1, .tv_usec = 0 };
+static std::string getThreadName(std::string interfaceName, const std::string &instanceName) {
+ auto dot = interfaceName.rfind(".");
+ if (dot != std::string::npos) interfaceName = interfaceName.substr(dot + 1);
+ return "RelayThread_" + interfaceName + "_" + instanceName;
+}
+
struct PipeRelay::RelayThread : public Thread {
- explicit RelayThread(int fd, std::ostream &os);
+ explicit RelayThread(int fd, std::ostream &os, const NullableOStream<std::ostream> &err,
+ const std::string &fqName);
bool threadLoop() override;
void setFinished();
@@ -40,6 +46,7 @@
private:
int mFd;
std::ostream &mOutStream;
+ NullableOStream<std::ostream> mErrStream;
// If we were to use requestExit() and exitPending() instead, threadLoop()
// may not run at all by the time ~PipeRelay is called (i.e. debug() has
@@ -47,13 +54,17 @@
// read() are executed until data are drained.
std::atomic_bool mFinished;
+ std::string mFqName;
+
DISALLOW_COPY_AND_ASSIGN(RelayThread);
};
////////////////////////////////////////////////////////////////////////////////
-PipeRelay::RelayThread::RelayThread(int fd, std::ostream &os)
- : mFd(fd), mOutStream(os), mFinished(false) {}
+PipeRelay::RelayThread::RelayThread(int fd, std::ostream &os,
+ const NullableOStream<std::ostream> &err,
+ const std::string &fqName)
+ : mFd(fd), mOutStream(os), mErrStream(err), mFinished(false), mFqName(fqName) {}
bool PipeRelay::RelayThread::threadLoop() {
char buffer[1024];
@@ -66,13 +77,14 @@
int res = TEMP_FAILURE_RETRY(select(mFd + 1, &set, nullptr, nullptr, &timeout));
if (res < 0) {
- PLOG(INFO) << "select() failed";
+ mErrStream << "debug " << mFqName << ": select() failed";
return false;
}
if (res == 0 || !FD_ISSET(mFd, &set)) {
if (mFinished) {
- LOG(WARNING) << "debug: timeout reading from pipe, output may be truncated.";
+ mErrStream << "debug " << mFqName
+ << ": timeout reading from pipe, output may be truncated.";
return false;
}
// timeout, but debug() has not returned, so wait for HAL to finish.
@@ -83,7 +95,7 @@
ssize_t n = TEMP_FAILURE_RETRY(read(mFd, buffer, sizeof(buffer)));
if (n < 0) {
- PLOG(ERROR) << "read() failed";
+ mErrStream << "debug " << mFqName << ": read() failed";
}
if (n <= 0) {
@@ -101,8 +113,9 @@
////////////////////////////////////////////////////////////////////////////////
-PipeRelay::PipeRelay(std::ostream &os)
- : mInitCheck(NO_INIT) {
+PipeRelay::PipeRelay(std::ostream &os, const NullableOStream<std::ostream> &err,
+ const std::string &interfaceName, const std::string &instanceName)
+ : mInitCheck(NO_INIT) {
int res = pipe(mFds);
if (res < 0) {
@@ -110,8 +123,8 @@
return;
}
- mThread = new RelayThread(mFds[0], os);
- mInitCheck = mThread->run("RelayThread");
+ mThread = new RelayThread(mFds[0], os, err, interfaceName + "/" + instanceName);
+ mInitCheck = mThread->run(getThreadName(interfaceName, instanceName).c_str());
}
void PipeRelay::CloseFd(int *fd) {
diff --git a/cmds/lshal/PipeRelay.h b/cmds/lshal/PipeRelay.h
index 835016041..bd994b4 100644
--- a/cmds/lshal/PipeRelay.h
+++ b/cmds/lshal/PipeRelay.h
@@ -21,6 +21,8 @@
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include "NullableOStream.h"
+
namespace android {
namespace lshal {
@@ -28,7 +30,10 @@
* written to the "write"-end of the pair to the specified output stream "os".
*/
struct PipeRelay {
- explicit PipeRelay(std::ostream &os);
+ explicit PipeRelay(std::ostream& os,
+ const NullableOStream<std::ostream>& err,
+ const std::string& interfaceName,
+ const std::string& instanceName);
~PipeRelay();
status_t initCheck() const;
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 16afecd..05fcc2b 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -448,6 +448,14 @@
return mLastTransactionBinderFlags;
}
+void IPCThreadState::setCallRestriction(ProcessState::CallRestriction restriction) {
+ mCallRestriction = restriction;
+}
+
+ProcessState::CallRestriction IPCThreadState::getCallRestriction() const {
+ return mCallRestriction;
+}
+
void IPCThreadState::restoreCallingIdentity(int64_t token)
{
mCallingUid = (int)(token>>32);
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index a530565..83ca687 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -282,9 +282,17 @@
// a driver API to get a handle to the context manager with
// proper reference counting.
+ IPCThreadState* ipc = IPCThreadState::self();
+
+ CallRestriction originalCallRestriction = ipc->getCallRestriction();
+ ipc->setCallRestriction(CallRestriction::NONE);
+
Parcel data;
- status_t status = IPCThreadState::self()->transact(
+ status_t status = ipc->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
+
+ ipc->setCallRestriction(originalCallRestriction);
+
if (status == DEAD_OBJECT)
return nullptr;
}
diff --git a/libs/binder/fuzzer/binder.cpp b/libs/binder/fuzzer/binder.cpp
index 52c730c..c2d4a3f 100644
--- a/libs/binder/fuzzer/binder.cpp
+++ b/libs/binder/fuzzer/binder.cpp
@@ -19,6 +19,8 @@
#include "util.h"
#include <android/os/IServiceManager.h>
+#include <binder/ParcelableHolder.h>
+#include <binder/PersistableBundle.h>
using ::android::status_t;
@@ -251,5 +253,20 @@
PARCEL_READ_NO_STATUS(uid_t, readCallingWorkSourceUid),
PARCEL_READ_NO_STATUS(size_t, getBlobAshmemSize),
PARCEL_READ_NO_STATUS(size_t, getOpenAshmemSize),
+
+ // additional parcelable objects defined in libbinder
+ [] (const ::android::Parcel& p, uint8_t data) {
+ using ::android::os::ParcelableHolder;
+ using ::android::Parcelable;
+ FUZZ_LOG() << "about to read ParcelableHolder using readParcelable with status";
+ Parcelable::Stability stability = Parcelable::Stability::STABILITY_LOCAL;
+ if ( (data & 1) == 1 ) {
+ stability = Parcelable::Stability::STABILITY_VINTF;
+ }
+ ParcelableHolder t = ParcelableHolder(stability);
+ status_t status = p.readParcelable(&t);
+ FUZZ_LOG() << "ParcelableHolder status: " << status;
+ },
+ PARCEL_READ_WITH_STATUS(android::os::PersistableBundle, readParcelable),
};
// clang-format on
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index aa256d4..49ef253 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -32,6 +32,8 @@
class IPCThreadState
{
public:
+ using CallRestriction = ProcessState::CallRestriction;
+
static IPCThreadState* self();
static IPCThreadState* selfOrNull(); // self(), but won't instantiate
@@ -99,6 +101,9 @@
void setLastTransactionBinderFlags(int32_t flags);
int32_t getLastTransactionBinderFlags() const;
+ void setCallRestriction(CallRestriction restriction);
+ CallRestriction getCallRestriction() const;
+
int64_t clearCallingIdentity();
// Restores PID/UID (not SID)
void restoreCallingIdentity(int64_t token);
@@ -157,7 +162,6 @@
// This constant needs to be kept in sync with Binder.UNSET_WORKSOURCE from the Java
// side.
static const int32_t kUnsetWorkSource = -1;
-
private:
IPCThreadState();
~IPCThreadState();
@@ -204,8 +208,7 @@
bool mPropagateWorkSource;
int32_t mStrictModePolicy;
int32_t mLastTransactionBinderFlags;
-
- ProcessState::CallRestriction mCallRestriction;
+ CallRestriction mCallRestriction;
};
} // namespace android
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index f59bb75..439b019 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -199,6 +199,9 @@
public:
/**
* Takes ownership of a.
+ *
+ * WARNING: this constructor is only expected to be used when reading a
+ * status value. Use `ScopedAStatus::ok()` instead.
*/
explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
~ScopedAStatus() {}
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
new file mode 100644
index 0000000..6701518
--- /dev/null
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_parcelable_utils.h
+ * @brief Helper for parcelable.
+ */
+
+#pragma once
+
+namespace ndk {
+// Also see Parcelable.h in libbinder.
+typedef int32_t parcelable_stability_t;
+enum {
+ STABILITY_LOCAL,
+ STABILITY_VINTF, // corresponds to @VintfStability
+};
+} // namespace ndk
+
+/** @} */
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index c33c44f..722ae23 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -272,7 +272,7 @@
}
binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
- return PruneStatusT(status->get()->writeToParcel(parcel->get()));
+ return PruneStatusT(status->get().writeToParcel(parcel->get()));
}
binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
::android::binder::Status bstatus;
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index d889593..a8ae441 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -23,7 +23,8 @@
using ::android::binder::Status;
AStatus* AStatus_newOk() {
- return new AStatus();
+ static AStatus status = AStatus();
+ return &status;
}
AStatus* AStatus_fromExceptionCode(binder_exception_t exception) {
@@ -47,27 +48,27 @@
}
bool AStatus_isOk(const AStatus* status) {
- return status->get()->isOk();
+ return status->get().isOk();
}
binder_exception_t AStatus_getExceptionCode(const AStatus* status) {
- return PruneException(status->get()->exceptionCode());
+ return PruneException(status->get().exceptionCode());
}
int32_t AStatus_getServiceSpecificError(const AStatus* status) {
- return status->get()->serviceSpecificErrorCode();
+ return status->get().serviceSpecificErrorCode();
}
binder_status_t AStatus_getStatus(const AStatus* status) {
- return PruneStatusT(status->get()->transactionError());
+ return PruneStatusT(status->get().transactionError());
}
const char* AStatus_getMessage(const AStatus* status) {
- return status->get()->exceptionMessage().c_str();
+ return status->get().exceptionMessage().c_str();
}
const char* AStatus_getDescription(const AStatus* status) {
- android::String8 description = status->get()->toString8();
+ android::String8 description = status->get().toString8();
char* cStr = new char[description.size() + 1];
memcpy(cStr, description.c_str(), description.size() + 1);
return cStr;
@@ -78,7 +79,9 @@
}
void AStatus_delete(AStatus* status) {
- delete status;
+ if (status != AStatus_newOk()) {
+ delete status;
+ }
}
binder_status_t PruneStatusT(status_t status) {
diff --git a/libs/binder/ndk/status_internal.h b/libs/binder/ndk/status_internal.h
index f6227f7..cb96e48 100644
--- a/libs/binder/ndk/status_internal.h
+++ b/libs/binder/ndk/status_internal.h
@@ -25,8 +25,7 @@
AStatus() {} // ok
explicit AStatus(::android::binder::Status&& status) : mStatus(std::move(status)) {}
- ::android::binder::Status* get() { return &mStatus; }
- const ::android::binder::Status* get() const { return &mStatus; }
+ const ::android::binder::Status& get() const { return mStatus; }
private:
::android::binder::Status mStatus;
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index 0234820..dc8270e 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -28,11 +28,8 @@
rust_bindgen {
name: "libbinder_ndk_bindgen",
crate_name: "binder_ndk_bindgen",
- wrapper_src: "sys/BinderBindings.h",
+ wrapper_src: "sys/BinderBindings.hpp",
source_stem: "bindings",
- cflags: [
- "-x c++",
- ],
bindgen_flags: [
// Unfortunately the only way to specify the rust_non_exhaustive enum
// style for a type is to make it the default
diff --git a/libs/binder/rust/sys/BinderBindings.h b/libs/binder/rust/sys/BinderBindings.hpp
similarity index 100%
rename from libs/binder/rust/sys/BinderBindings.h
rename to libs/binder/rust/sys/BinderBindings.hpp
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index ef7a6f5..351af65 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -86,6 +86,10 @@
mReceiveFd = std::move(receiveFd);
}
+void BitTube::setSendFd(base::unique_fd&& sendFd) {
+ mSendFd = std::move(sendFd);
+}
+
ssize_t BitTube::write(void const* vaddr, size_t size) {
ssize_t err, len;
do {
@@ -115,6 +119,11 @@
status_t result = reply->writeDupFileDescriptor(mReceiveFd);
mReceiveFd.reset();
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply->writeDupFileDescriptor(mSendFd);
+ mSendFd.reset();
return result;
}
@@ -126,6 +135,13 @@
ALOGE("BitTube::readFromParcel: can't dup file descriptor (%s)", strerror(error));
return -error;
}
+ mSendFd.reset(dup(parcel->readFileDescriptor()));
+ if (mSendFd < 0) {
+ mSendFd.reset();
+ int error = errno;
+ ALOGE("BitTube::readFromParcel: can't dup file descriptor (%s)", strerror(error));
+ return -error;
+ }
return NO_ERROR;
}
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index b33bc9e..682fe91 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -89,12 +89,8 @@
return OK;
}
-void DisplayEventDispatcher::requestLatestConfig() {
- status_t status = mReceiver.requestLatestConfig();
- if (status) {
- ALOGW("Failed enable config events, status=%d", status);
- return;
- }
+void DisplayEventDispatcher::injectEvent(const DisplayEventReceiver::Event& event) {
+ mReceiver.sendEvents(&event, 1);
}
int DisplayEventDispatcher::getFd() const {
@@ -157,6 +153,9 @@
dispatchConfigChanged(ev.header.timestamp, ev.header.displayId,
ev.config.configId, ev.config.vsyncPeriod);
break;
+ case DisplayEventReceiver::DISPLAY_EVENT_NULL:
+ dispatchNullEvent(ev.header.timestamp, ev.header.displayId);
+ break;
default:
ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
break;
@@ -168,4 +167,5 @@
}
return gotVsync;
}
+
} // namespace android
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index 1fed509..f2b0962 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -79,14 +79,6 @@
return NO_INIT;
}
-status_t DisplayEventReceiver::requestLatestConfig() {
- if (mEventConnection != nullptr) {
- mEventConnection->requestLatestConfig();
- return NO_ERROR;
- }
- return NO_INIT;
-}
-
ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
size_t count) {
return DisplayEventReceiver::getEvents(mDataChannel.get(), events, count);
@@ -98,6 +90,10 @@
return gui::BitTube::recvObjects(dataChannel, events, count);
}
+ssize_t DisplayEventReceiver::sendEvents(Event const* events, size_t count) {
+ return DisplayEventReceiver::sendEvents(mDataChannel.get(), events, count);
+}
+
ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
Event const* events, size_t count)
{
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
index aa74bfd..c0e246f 100644
--- a/libs/gui/IDisplayEventConnection.cpp
+++ b/libs/gui/IDisplayEventConnection.cpp
@@ -26,8 +26,7 @@
STEAL_RECEIVE_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
SET_VSYNC_RATE,
REQUEST_NEXT_VSYNC,
- REQUEST_LATEST_CONFIG,
- LAST = REQUEST_LATEST_CONFIG,
+ LAST = REQUEST_NEXT_VSYNC,
};
} // Anonymous namespace
@@ -54,11 +53,6 @@
callRemoteAsync<decltype(&IDisplayEventConnection::requestNextVsync)>(
Tag::REQUEST_NEXT_VSYNC);
}
-
- void requestLatestConfig() override {
- callRemoteAsync<decltype(&IDisplayEventConnection::requestLatestConfig)>(
- Tag::REQUEST_LATEST_CONFIG);
- }
};
// Out-of-line virtual method definition to trigger vtable emission in this translation unit (see
@@ -80,8 +74,6 @@
return callLocal(data, reply, &IDisplayEventConnection::setVsyncRate);
case Tag::REQUEST_NEXT_VSYNC:
return callLocalAsync(data, reply, &IDisplayEventConnection::requestNextVsync);
- case Tag::REQUEST_LATEST_CONFIG:
- return callLocalAsync(data, reply, &IDisplayEventConnection::requestLatestConfig);
}
}
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index f210c34..eb5b004 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -31,7 +31,7 @@
status_t initialize();
void dispose();
status_t scheduleVsync();
- void requestLatestConfig();
+ void injectEvent(const DisplayEventReceiver::Event& event);
int getFd() const;
virtual int handleEvent(int receiveFd, int events, void* data);
@@ -48,6 +48,9 @@
bool connected) = 0;
virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
int32_t configId, nsecs_t vsyncPeriod) = 0;
+ // AChoreographer-specific hook for processing null-events so that looper
+ // can be properly poked.
+ virtual void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) = 0;
bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
uint32_t* outCount);
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 8d49184..0e10d1a 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -53,6 +53,7 @@
DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
DISPLAY_EVENT_CONFIG_CHANGED = fourcc('c', 'o', 'n', 'f'),
+ DISPLAY_EVENT_NULL = fourcc('n', 'u', 'l', 'l'),
};
struct Event {
@@ -130,6 +131,7 @@
* sendEvents write events to the queue and returns how many events were
* written.
*/
+ ssize_t sendEvents(Event const* events, size_t count);
static ssize_t sendEvents(gui::BitTube* dataChannel, Event const* events, size_t count);
/*
@@ -146,12 +148,6 @@
*/
status_t requestNextVsync();
- /*
- * requestLatestConfig() force-requests the current config for the primary
- * display.
- */
- status_t requestLatestConfig();
-
private:
sp<IDisplayEventConnection> mEventConnection;
std::unique_ptr<gui::BitTube> mDataChannel;
diff --git a/libs/gui/include/gui/IDisplayEventConnection.h b/libs/gui/include/gui/IDisplayEventConnection.h
index 674aafd..cff22a3 100644
--- a/libs/gui/include/gui/IDisplayEventConnection.h
+++ b/libs/gui/include/gui/IDisplayEventConnection.h
@@ -51,11 +51,6 @@
* requestNextVsync() schedules the next vsync event. It has no effect if the vsync rate is > 0.
*/
virtual void requestNextVsync() = 0; // Asynchronous
-
- /*
- * requestLatestConfig() requests the config for the primary display.
- */
- virtual void requestLatestConfig() = 0; // Asynchronous
};
class BnDisplayEventConnection : public SafeBnInterface<IDisplayEventConnection> {
diff --git a/libs/gui/include/private/gui/BitTube.h b/libs/gui/include/private/gui/BitTube.h
index 13c0162..8048518 100644
--- a/libs/gui/include/private/gui/BitTube.h
+++ b/libs/gui/include/private/gui/BitTube.h
@@ -58,6 +58,9 @@
// resets this BitTube's receive file descriptor to receiveFd
void setReceiveFd(base::unique_fd&& receiveFd);
+ // resets this BitTube's send file descriptor to sendFd
+ void setSendFd(base::unique_fd&& sendFd);
+
// send objects (sized blobs). All objects are guaranteed to be written or the call fails.
template <typename T>
static ssize_t sendObjects(BitTube* tube, T const* events, size_t count) {
@@ -85,7 +88,7 @@
// the message, excess data is silently discarded.
ssize_t read(void* vaddr, size_t size);
- base::unique_fd mSendFd;
+ mutable base::unique_fd mSendFd;
mutable base::unique_fd mReceiveFd;
static ssize_t sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize);
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index e458b2e..b431cbb 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -136,6 +136,7 @@
void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId, int32_t configId,
nsecs_t vsyncPeriod) override;
+ void dispatchNullEvent(nsecs_t, PhysicalDisplayId) override;
void scheduleCallbacks();
@@ -170,7 +171,7 @@
Choreographer::Choreographer(const sp<Looper>& looper)
: DisplayEventDispatcher(looper, ISurfaceComposer::VsyncSource::eVsyncSourceApp,
- ISurfaceComposer::ConfigChanged::eConfigChangedDispatch),
+ ISurfaceComposer::ConfigChanged::eConfigChangedSuppress),
mLooper(looper),
mThreadId(std::this_thread::get_id()) {
std::lock_guard<std::mutex> _l(gChoreographers.lock);
@@ -294,8 +295,14 @@
} else {
// If the looper thread is detached from Choreographer, then refresh rate
// changes will be handled in AChoreographer_handlePendingEvents, so we
- // need to redispatch a config from SF
- requestLatestConfig();
+ // need to wake up the looper thread by writing to the write-end of the
+ // socket the looper is listening on.
+ // Fortunately, these events are small so sending packets across the
+ // socket should be atomic across processes.
+ DisplayEventReceiver::Event event;
+ event.header = DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
+ PhysicalDisplayId(0), systemTime()};
+ injectEvent(event);
}
}
@@ -374,28 +381,15 @@
// displays. When multi-display choreographer is properly supported, then
// PhysicalDisplayId should no longer be ignored.
void Choreographer::dispatchConfigChanged(nsecs_t, PhysicalDisplayId displayId, int32_t configId,
- nsecs_t vsyncPeriod) {
+ nsecs_t) {
ALOGV("choreographer %p ~ received config change event "
"(displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", configId=%d).",
this, displayId, configId);
+}
- const nsecs_t lastPeriod = mLatestVsyncPeriod;
- std::vector<RefreshRateCallback> callbacks{};
- {
- std::lock_guard<std::mutex> _l{mLock};
- for (auto& cb : mRefreshRateCallbacks) {
- callbacks.push_back(cb);
- cb.firstCallbackFired = true;
- }
- }
-
- for (auto& cb : callbacks) {
- if (!cb.firstCallbackFired || (vsyncPeriod > 0 && vsyncPeriod != lastPeriod)) {
- cb.callback(vsyncPeriod, cb.data);
- }
- }
-
- mLatestVsyncPeriod = vsyncPeriod;
+void Choreographer::dispatchNullEvent(nsecs_t, PhysicalDisplayId) {
+ ALOGV("choreographer %p ~ received null event.", this);
+ handleRefreshRateUpdates();
}
void Choreographer::handleMessage(const Message& message) {
@@ -449,12 +443,18 @@
}
void AChoreographer_routePostFrameCallback(AChoreographer* choreographer,
AChoreographer_frameCallback callback, void* data) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return AChoreographer_postFrameCallback(choreographer, callback, data);
+#pragma clang diagnostic pop
}
void AChoreographer_routePostFrameCallbackDelayed(AChoreographer* choreographer,
AChoreographer_frameCallback callback, void* data,
long delayMillis) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return AChoreographer_postFrameCallbackDelayed(choreographer, callback, data, delayMillis);
+#pragma clang diagnostic pop
}
void AChoreographer_routePostFrameCallback64(AChoreographer* choreographer,
AChoreographer_frameCallback64 callback, void* data) {
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index cee36a1..845bf50 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -139,6 +139,7 @@
status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
outChannel->setReceiveFd(mChannel.moveReceiveFd());
+ outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd())));
return NO_ERROR;
}
@@ -152,11 +153,6 @@
mEventThread->requestNextVsync(this);
}
-void EventThreadConnection::requestLatestConfig() {
- ATRACE_NAME("requestLatestConfig");
- mEventThread->requestLatestConfig(this);
-}
-
status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
@@ -269,28 +265,6 @@
}
}
-void EventThread::requestLatestConfig(const sp<EventThreadConnection>& connection) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (connection->mForcedConfigChangeDispatch) {
- return;
- }
- connection->mForcedConfigChangeDispatch = true;
- auto pendingConfigChange =
- std::find_if(std::begin(mPendingEvents), std::end(mPendingEvents),
- [&](const DisplayEventReceiver::Event& event) {
- return event.header.type ==
- DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED;
- });
-
- // If we didn't find a pending config change event, then push out the
- // latest one we've ever seen.
- if (pendingConfigChange == std::end(mPendingEvents)) {
- mPendingEvents.push_back(mLastConfigChangeEvent);
- }
-
- mCondition.notify_all();
-}
-
void EventThread::onScreenReleased() {
std::lock_guard<std::mutex> lock(mMutex);
if (!mVSyncState || mVSyncState->synthetic) {
@@ -366,9 +340,6 @@
mInterceptVSyncsCallback(event->header.timestamp);
}
break;
- case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
- mLastConfigChangeEvent = *event;
- break;
}
}
@@ -381,10 +352,6 @@
vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
if (event && shouldConsumeEvent(*event, connection)) {
- if (event->header.type == DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED &&
- connection->mForcedConfigChangeDispatch) {
- connection->mForcedConfigChangeDispatch = false;
- }
consumers.push_back(connection);
}
@@ -460,9 +427,7 @@
return true;
case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED: {
- const bool oneTimeDispatch = connection->mForcedConfigChangeDispatch;
- return oneTimeDispatch ||
- connection->mConfigChanged == ISurfaceComposer::eConfigChangedDispatch;
+ return connection->mConfigChanged == ISurfaceComposer::eConfigChangedDispatch;
}
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 64acbd7..49f624c 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -81,19 +81,13 @@
status_t stealReceiveChannel(gui::BitTube* outChannel) override;
status_t setVsyncRate(uint32_t rate) override;
void requestNextVsync() override; // asynchronous
- void requestLatestConfig() override; // asynchronous
// Called in response to requestNextVsync.
const ResyncCallback resyncCallback;
VSyncRequest vsyncRequest = VSyncRequest::None;
- ISurfaceComposer::ConfigChanged mConfigChanged =
+ const ISurfaceComposer::ConfigChanged mConfigChanged =
ISurfaceComposer::ConfigChanged::eConfigChangedSuppress;
- // Store whether we need to force dispatching a config change separately -
- // if mConfigChanged ever changes before the config change is dispatched
- // then we still need to propagate an initial config to the app if we
- // haven't already.
- bool mForcedConfigChangeDispatch = false;
private:
virtual void onFirstRef();
@@ -129,10 +123,6 @@
virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0;
// Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
- // Dispatches the most recent configuration
- // Usage of this method assumes that only the primary internal display
- // supports multiple display configurations.
- virtual void requestLatestConfig(const sp<EventThreadConnection>& connection) = 0;
// Retrieves the number of event connections tracked by this EventThread.
virtual size_t getEventThreadConnectionCount() = 0;
@@ -153,7 +143,6 @@
status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
void requestNextVsync(const sp<EventThreadConnection>& connection) override;
- void requestLatestConfig(const sp<EventThreadConnection>& connection) override;
// called before the screen is turned off from main thread
void onScreenReleased() override;
@@ -201,7 +190,6 @@
std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
- DisplayEventReceiver::Event mLastConfigChangeEvent GUARDED_BY(mMutex);
// VSYNC state of connected display.
struct VSyncState {