/* * Copyright (C) 2024 Amlogic Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "BinderServer.h" #include #include #include #include "binderInfo.h" BinderServer::BinderServer() { mSCallback = std::make_shared(); mServerFunc.emplace(CMD_SEND_CLIENT, &ServerCallback::registerCallback); mServerFunc.emplace(CMD_CREATE_LAYER, &ServerCallback::createLayer); mServerFunc.emplace(CMD_DESTROY_LAYER, &ServerCallback::destroyLayer); mServerFunc.emplace(CMD_SET_TUNNEL_ID, &ServerCallback::setTunnelId); mServerFunc.emplace(CMD_SET_LAYER_INDEX, &ServerCallback::setLayerIndex); mServerFunc.emplace(CMD_SET_LAYER_ZORDER, &ServerCallback::setLayerZorder); mServerFunc.emplace(CMD_SET_SOURCE_CROP, &ServerCallback::setSourceCrop); mServerFunc.emplace(CMD_SET_DISPLAY_FRAME, &ServerCallback::setDisplayFrame); mServerFunc.emplace(CMD_GET_DELAY_LATENCY, &ServerCallback::getDelayLatency); mServerFunc.emplace(CMD_SET_MAIN_PLANE, &ServerCallback::setToMainPlane); mServerFunc.emplace(CMD_GET_UI_SIZE, &ServerCallback::getUiSize); } void BinderServer::ServiceDeathRecipient::binderDied(const wp& who) { if (mCb != NULL) mCb->removeClient(mClientId); } int BinderServer::ServerCallback::registerCallback(const Parcel& data, Parcel* reply) { sp binder = data.readStrongBinder(); int callingPid = IPCThreadState::self()->getCallingPid(); sp deathRecip = new ServiceDeathRecipient(this, callingPid); std::shared_ptr client = std::make_shared(mMesonCompositor); if (binder != NULL) binder->linkToDeath(deathRecip); mClients.emplace(callingPid, std::make_pair(client, deathRecip)); mBinders.emplace(callingPid, binder); return 0; } int BinderServer::ServerCallback::createLayer(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int32_t id = 0; int ret; int callingPid = IPCThreadState::self()->getCallingPid(); ret = mMesonCompositor->createLayer(displayId, &id); if (!ret) { auto client = mClients.find(callingPid); if (client != mClients.end()) { auto info = client->second; auto [cc, deathRecipient] = info; if (cc.get()) cc->addDisplay(displayId, id); } } reply->writeInt32(id); return ret; } int BinderServer::ServerCallback::destroyLayer(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int layerId = data.readInt32(); int callingPid = IPCThreadState::self()->getCallingPid(); auto client = mClients.find(callingPid); if (client != mClients.end()) { auto info = client->second; auto [cc, deathRecipient] = info; if (cc.get()) cc->removeDisplay(displayId, layerId); } return mMesonCompositor->destroyLayer(displayId, layerId); } int BinderServer::ServerCallback::setTunnelId(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int layerId = data.readInt32(); int tunnelId = data.readInt32(); return mMesonCompositor->setTunnelId(displayId, layerId, tunnelId); } int BinderServer::ServerCallback::setLayerIndex(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int layerId = data.readInt32(); int index = data.readInt32(); return mMesonCompositor->setLayerIndex(displayId, layerId, index); } int BinderServer::ServerCallback::setLayerZorder(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int layerId = data.readInt32(); int zorder = data.readInt32(); return mMesonCompositor->setLayerZorder(displayId, layerId, zorder); } int BinderServer::ServerCallback::setSourceCrop(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int layerId = data.readInt32(); struct rect crop = { 0 }; crop.x = data.readInt32(); crop.y = data.readInt32(); crop.w = data.readInt32(); crop.h = data.readInt32(); return mMesonCompositor->setSourceCrop(displayId, layerId, crop); } int BinderServer::ServerCallback::setDisplayFrame(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int layerId = data.readInt32(); struct rect frame = { 0 }; frame.x = data.readInt32(); frame.y = data.readInt32(); frame.w = data.readInt32(); frame.h = data.readInt32(); return mMesonCompositor->setDisplayFrame(displayId, layerId, frame); } int BinderServer::ServerCallback::getDelayLatency(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); int layerId = data.readInt32(); int latency; latency = mMesonCompositor->getDelayLatency(displayId, layerId); reply->writeInt32(latency); return 0; } int BinderServer::ServerCallback::setToMainPlane(const Parcel& data, Parcel* reply) { int displayId = data.readInt32(); return mMesonCompositor->setToMainPlane(displayId); } int BinderServer::ServerCallback::getUiSize(const Parcel& data, Parcel* reply) { int32_t displayId = data.readInt32(); int32_t width = 0; int32_t height = 0; int ret; ret = mMesonCompositor->getUiSize(displayId, &width, &height); if (!ret && reply != NULL) { reply->writeInt32(width); reply->writeInt32(height); } return ret; } void BinderServer::ServerCallback::setMesonCompositor(std::shared_ptr& c) { mMesonCompositor = c; } void BinderServer::ServerCallback::removeClient(int clientId) { auto client = mClients.find(clientId); if (client != mClients.end()) { auto [cc, deathRecipient] = client->second; if (cc.get()) cc.reset(); if (deathRecipient != NULL) deathRecipient.clear(); mClients.erase(client); } mBinders.erase(clientId); } status_t BinderServer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { auto cb = mServerFunc.find(code); if (cb == mServerFunc.end()) return BBinder::onTransact(code, data, reply, flags); return (mSCallback.get()->*(cb->second))(data, reply); } void BinderServer::setMesonCompositor(std::shared_ptr& c) { if (mSCallback.get()) mSCallback->setMesonCompositor(c); } void BinderServer::run(std::shared_ptr server) { sp proc(ProcessState::self()); sp serviceManager = defaultServiceManager(); serviceManager->addService(String16("compositor-service"), server.get()); proc->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }