232 lines
7.1 KiB
C++
232 lines
7.1 KiB
C++
/*
|
|||
|
|
* 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 <binder/IPCThreadState.h>
|
||
|
|
#include <binder/ProcessState.h>
|
||
|
|
#include <binder/IServiceManager.h>
|
||
|
|
|
||
|
|
#include "binderInfo.h"
|
||
|
|
|
||
|
|
BinderServer::BinderServer()
|
||
|
|
{
|
||
|
|
mSCallback = std::make_shared<ServerCallback>();
|
||
|
|
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<IBinder>& who)
|
||
|
|
{
|
||
|
|
if (mCb != NULL)
|
||
|
|
mCb->removeClient(mClientId);
|
||
|
|
}
|
||
|
|
|
||
|
|
int BinderServer::ServerCallback::registerCallback(const Parcel& data, Parcel* reply)
|
||
|
|
{
|
||
|
|
sp<IBinder> binder = data.readStrongBinder();
|
||
|
|
int callingPid = IPCThreadState::self()->getCallingPid();
|
||
|
|
|
||
|
|
sp<ServiceDeathRecipient> deathRecip = new ServiceDeathRecipient(this, callingPid);
|
||
|
|
std::shared_ptr<compositorClient> client = std::make_shared<compositorClient>(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<mesonVideoCompositor>& 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<mesonVideoCompositor>& c)
|
||
|
|
{
|
||
|
|
if (mSCallback.get())
|
||
|
|
mSCallback->setMesonCompositor(c);
|
||
|
|
}
|
||
|
|
|
||
|
|
void BinderServer::run(std::shared_ptr<BinderServer> server)
|
||
|
|
{
|
||
|
|
sp<ProcessState> proc(ProcessState::self());
|
||
|
|
sp<IServiceManager> serviceManager = defaultServiceManager();
|
||
|
|
|
||
|
|
serviceManager->addService(String16("compositor-service"), server.get());
|
||
|
|
proc->startThreadPool();
|
||
|
|
IPCThreadState::self()->joinThreadPool();
|
||
|
|
}
|