Loading services/displayservice/Android.bp 0 → 100644 +46 −0 Original line number Original line Diff line number Diff line // // Copyright (C) 2017 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. // cc_library_shared { name: "libdisplayservicehidl", srcs: [ "DisplayService.cpp", "DisplayEventReceiver.cpp", ], shared_libs: [ "libbase", "liblog", "libgui", "libhidlbase", "libhidltransport", "libutils", "android.frameworks.displayservice@1.0", ], export_include_dirs: ["include"], export_shared_lib_headers: [ "android.frameworks.displayservice@1.0", "libgui", "libutils", ], cflags: [ "-Werror", "-Wall", ] } services/displayservice/DisplayEventReceiver.cpp 0 → 100644 +167 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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. */ #define LOG_TAG "libdisplayservicehidl" #include <displayservice/DisplayEventReceiver.h> #include <android-base/logging.h> #include <android/frameworks/displayservice/1.0/BpHwEventCallback.h> #include <thread> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { sp<Looper> getLooper() { static sp<Looper> looper = []() { sp<Looper> looper = new Looper(false /* allowNonCallbacks */); std::thread{[&](){ int pollResult = looper->pollAll(-1 /* timeout */); LOG(ERROR) << "Looper::pollAll returns unexpected " << pollResult; }}.detach(); return looper; }(); return looper; } DisplayEventReceiver::AttachedEvent::AttachedEvent(const sp<IEventCallback> &callback) : mCallback(callback) { mLooperAttached = getLooper()->addFd(mFwkReceiver.getFd(), Looper::POLL_CALLBACK, Looper::EVENT_INPUT, this, nullptr); } DisplayEventReceiver::AttachedEvent::~AttachedEvent() { if (!detach()) { LOG(ERROR) << "Could not remove fd from looper."; } } bool DisplayEventReceiver::AttachedEvent::detach() { if (!valid()) { return true; } return getLooper()->removeFd(mFwkReceiver.getFd()); } bool DisplayEventReceiver::AttachedEvent::valid() const { return mFwkReceiver.initCheck() == OK && mLooperAttached; } DisplayEventReceiver::FwkReceiver &DisplayEventReceiver::AttachedEvent::receiver() { return mFwkReceiver; } int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* /* data */) { CHECK(fd == mFwkReceiver.getFd()); if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { LOG(ERROR) << "AttachedEvent handleEvent received error or hangup:" << events; return 0; // remove the callback } if (!(events & Looper::EVENT_INPUT)) { LOG(ERROR) << "AttachedEvent handleEvent unhandled poll event:" << events; return 1; // keep the callback } const static size_t SIZE = 1; ssize_t n; FwkReceiver::Event buf[SIZE]; while ((n = mFwkReceiver.getEvents(buf, SIZE)) > 0) { for (size_t i = 0; i < static_cast<size_t>(n); ++i) { const FwkReceiver::Event &event = buf[i]; uint32_t type = event.header.type; uint64_t timestamp = event.header.timestamp; switch(buf[i].header.type) { case FwkReceiver::DISPLAY_EVENT_VSYNC: { mCallback->onVsync(timestamp, event.vsync.count); } break; case FwkReceiver::DISPLAY_EVENT_HOTPLUG: { mCallback->onHotplug(timestamp, event.hotplug.connected); } break; default: { LOG(ERROR) << "AttachedEvent handleEvent unknown type: " << type; } } } } return 1; // keep on going } Return<Status> DisplayEventReceiver::init(const sp<IEventCallback>& callback) { std::unique_lock<std::mutex> lock(mMutex); if (mAttached != nullptr || callback == nullptr) { return Status::BAD_VALUE; } mAttached = new AttachedEvent(callback); return mAttached->valid() ? Status::SUCCESS : Status::UNKNOWN; } Return<Status> DisplayEventReceiver::setVsyncRate(int32_t count) { std::unique_lock<std::mutex> lock(mMutex); if (mAttached == nullptr || count < 0) { return Status::BAD_VALUE; } bool success = OK == mAttached->receiver().setVsyncRate(count); return success ? Status::SUCCESS : Status::UNKNOWN; } Return<Status> DisplayEventReceiver::requestNextVsync() { std::unique_lock<std::mutex> lock(mMutex); if (mAttached == nullptr) { return Status::BAD_VALUE; } bool success = OK == mAttached->receiver().requestNextVsync(); return success ? Status::SUCCESS : Status::UNKNOWN; } Return<Status> DisplayEventReceiver::close() { if (mAttached == nullptr) { return Status::BAD_VALUE; } std::unique_lock<std::mutex> lock(mMutex); bool success = mAttached->detach(); mAttached = nullptr; return success ? Status::SUCCESS : Status::UNKNOWN; } } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android services/displayservice/DisplayService.cpp 0 → 100644 +18 −0 Original line number Original line Diff line number Diff line #include <displayservice/DisplayService.h> #include <displayservice/DisplayEventReceiver.h> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { Return<sp<IDisplayEventReceiver>> DisplayService::getEventReceiver() { return new DisplayEventReceiver(); } } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android services/displayservice/include/displayservice/DisplayEventReceiver.h 0 → 100644 +56 −0 Original line number Original line Diff line number Diff line #ifndef ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H #define ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H #include <android/frameworks/displayservice/1.0/IDisplayEventReceiver.h> #include <gui/DisplayEventReceiver.h> #include <hidl/Status.h> #include <gui/DisplayEventReceiver.h> #include <utils/Looper.h> #include <mutex> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { using ::android::hardware::Return; using ::android::hardware::Void; class DisplayEventReceiver : public IDisplayEventReceiver { public: Return<Status> init(const sp<IEventCallback>& callback) override; Return<Status> setVsyncRate(int32_t count) override; Return<Status> requestNextVsync() override; Return<Status> close() override; private: using FwkReceiver = ::android::DisplayEventReceiver; struct AttachedEvent : LooperCallback { AttachedEvent(const sp<IEventCallback> &callback); ~AttachedEvent(); bool detach(); bool valid() const; FwkReceiver &receiver(); virtual int handleEvent(int fd, int events, void* /* data */) override; private: FwkReceiver mFwkReceiver; sp<IEventCallback> mCallback; bool mLooperAttached; }; sp<AttachedEvent> mAttached; std::mutex mMutex; }; } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android #endif // ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H services/displayservice/include/displayservice/DisplayService.h 0 → 100644 +26 −0 Original line number Original line Diff line number Diff line #ifndef ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H #define ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H #include <android/frameworks/displayservice/1.0/IDisplayService.h> #include <hidl/Status.h> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { using ::android::hardware::Return; using ::android::hardware::Void; struct DisplayService : public IDisplayService { Return<sp<IDisplayEventReceiver>> getEventReceiver() override; }; } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android #endif // ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H Loading
services/displayservice/Android.bp 0 → 100644 +46 −0 Original line number Original line Diff line number Diff line // // Copyright (C) 2017 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. // cc_library_shared { name: "libdisplayservicehidl", srcs: [ "DisplayService.cpp", "DisplayEventReceiver.cpp", ], shared_libs: [ "libbase", "liblog", "libgui", "libhidlbase", "libhidltransport", "libutils", "android.frameworks.displayservice@1.0", ], export_include_dirs: ["include"], export_shared_lib_headers: [ "android.frameworks.displayservice@1.0", "libgui", "libutils", ], cflags: [ "-Werror", "-Wall", ] }
services/displayservice/DisplayEventReceiver.cpp 0 → 100644 +167 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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. */ #define LOG_TAG "libdisplayservicehidl" #include <displayservice/DisplayEventReceiver.h> #include <android-base/logging.h> #include <android/frameworks/displayservice/1.0/BpHwEventCallback.h> #include <thread> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { sp<Looper> getLooper() { static sp<Looper> looper = []() { sp<Looper> looper = new Looper(false /* allowNonCallbacks */); std::thread{[&](){ int pollResult = looper->pollAll(-1 /* timeout */); LOG(ERROR) << "Looper::pollAll returns unexpected " << pollResult; }}.detach(); return looper; }(); return looper; } DisplayEventReceiver::AttachedEvent::AttachedEvent(const sp<IEventCallback> &callback) : mCallback(callback) { mLooperAttached = getLooper()->addFd(mFwkReceiver.getFd(), Looper::POLL_CALLBACK, Looper::EVENT_INPUT, this, nullptr); } DisplayEventReceiver::AttachedEvent::~AttachedEvent() { if (!detach()) { LOG(ERROR) << "Could not remove fd from looper."; } } bool DisplayEventReceiver::AttachedEvent::detach() { if (!valid()) { return true; } return getLooper()->removeFd(mFwkReceiver.getFd()); } bool DisplayEventReceiver::AttachedEvent::valid() const { return mFwkReceiver.initCheck() == OK && mLooperAttached; } DisplayEventReceiver::FwkReceiver &DisplayEventReceiver::AttachedEvent::receiver() { return mFwkReceiver; } int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* /* data */) { CHECK(fd == mFwkReceiver.getFd()); if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { LOG(ERROR) << "AttachedEvent handleEvent received error or hangup:" << events; return 0; // remove the callback } if (!(events & Looper::EVENT_INPUT)) { LOG(ERROR) << "AttachedEvent handleEvent unhandled poll event:" << events; return 1; // keep the callback } const static size_t SIZE = 1; ssize_t n; FwkReceiver::Event buf[SIZE]; while ((n = mFwkReceiver.getEvents(buf, SIZE)) > 0) { for (size_t i = 0; i < static_cast<size_t>(n); ++i) { const FwkReceiver::Event &event = buf[i]; uint32_t type = event.header.type; uint64_t timestamp = event.header.timestamp; switch(buf[i].header.type) { case FwkReceiver::DISPLAY_EVENT_VSYNC: { mCallback->onVsync(timestamp, event.vsync.count); } break; case FwkReceiver::DISPLAY_EVENT_HOTPLUG: { mCallback->onHotplug(timestamp, event.hotplug.connected); } break; default: { LOG(ERROR) << "AttachedEvent handleEvent unknown type: " << type; } } } } return 1; // keep on going } Return<Status> DisplayEventReceiver::init(const sp<IEventCallback>& callback) { std::unique_lock<std::mutex> lock(mMutex); if (mAttached != nullptr || callback == nullptr) { return Status::BAD_VALUE; } mAttached = new AttachedEvent(callback); return mAttached->valid() ? Status::SUCCESS : Status::UNKNOWN; } Return<Status> DisplayEventReceiver::setVsyncRate(int32_t count) { std::unique_lock<std::mutex> lock(mMutex); if (mAttached == nullptr || count < 0) { return Status::BAD_VALUE; } bool success = OK == mAttached->receiver().setVsyncRate(count); return success ? Status::SUCCESS : Status::UNKNOWN; } Return<Status> DisplayEventReceiver::requestNextVsync() { std::unique_lock<std::mutex> lock(mMutex); if (mAttached == nullptr) { return Status::BAD_VALUE; } bool success = OK == mAttached->receiver().requestNextVsync(); return success ? Status::SUCCESS : Status::UNKNOWN; } Return<Status> DisplayEventReceiver::close() { if (mAttached == nullptr) { return Status::BAD_VALUE; } std::unique_lock<std::mutex> lock(mMutex); bool success = mAttached->detach(); mAttached = nullptr; return success ? Status::SUCCESS : Status::UNKNOWN; } } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android
services/displayservice/DisplayService.cpp 0 → 100644 +18 −0 Original line number Original line Diff line number Diff line #include <displayservice/DisplayService.h> #include <displayservice/DisplayEventReceiver.h> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { Return<sp<IDisplayEventReceiver>> DisplayService::getEventReceiver() { return new DisplayEventReceiver(); } } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android
services/displayservice/include/displayservice/DisplayEventReceiver.h 0 → 100644 +56 −0 Original line number Original line Diff line number Diff line #ifndef ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H #define ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H #include <android/frameworks/displayservice/1.0/IDisplayEventReceiver.h> #include <gui/DisplayEventReceiver.h> #include <hidl/Status.h> #include <gui/DisplayEventReceiver.h> #include <utils/Looper.h> #include <mutex> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { using ::android::hardware::Return; using ::android::hardware::Void; class DisplayEventReceiver : public IDisplayEventReceiver { public: Return<Status> init(const sp<IEventCallback>& callback) override; Return<Status> setVsyncRate(int32_t count) override; Return<Status> requestNextVsync() override; Return<Status> close() override; private: using FwkReceiver = ::android::DisplayEventReceiver; struct AttachedEvent : LooperCallback { AttachedEvent(const sp<IEventCallback> &callback); ~AttachedEvent(); bool detach(); bool valid() const; FwkReceiver &receiver(); virtual int handleEvent(int fd, int events, void* /* data */) override; private: FwkReceiver mFwkReceiver; sp<IEventCallback> mCallback; bool mLooperAttached; }; sp<AttachedEvent> mAttached; std::mutex mMutex; }; } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android #endif // ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H
services/displayservice/include/displayservice/DisplayService.h 0 → 100644 +26 −0 Original line number Original line Diff line number Diff line #ifndef ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H #define ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H #include <android/frameworks/displayservice/1.0/IDisplayService.h> #include <hidl/Status.h> namespace android { namespace frameworks { namespace displayservice { namespace V1_0 { namespace implementation { using ::android::hardware::Return; using ::android::hardware::Void; struct DisplayService : public IDisplayService { Return<sp<IDisplayEventReceiver>> getEventReceiver() override; }; } // namespace implementation } // namespace V1_0 } // namespace displayservice } // namespace frameworks } // namespace android #endif // ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H