blob: 825841a07989c1c763343ea2e80249fb8bddf37a [file] [log] [blame]
/*
* 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.
*/
#include "gles_gfx_api.h"
#include "gles_renderer.h"
#include "server_connection.h"
#include "server_listener.h"
#include <gapic/connection.h>
#include <gapic/log.h>
#include <gapic/supported_abis.h>
#include <string.h>
#include <memory>
#include <sstream>
#include <string>
namespace {
const uint32_t kProtocolVersion = 1;
const char kAuthTokenHeader[] = { 'A', 'U', 'T', 'H' };
} // anonymous namespace
namespace gapir {
ServerListener::ServerListener(std::unique_ptr<gapic::Connection> conn, uint64_t maxMemorySize) :
mConn(std::move(conn)),
mMaxMemorySize(maxMemorySize) {
}
std::unique_ptr<ServerConnection> ServerListener::acceptConnection(int idleTimeoutMs, const char* authToken) {
while (true) {
GAPID_INFO("Waiting for new connection...");
std::unique_ptr<gapic::Connection> client = mConn->accept(idleTimeoutMs);
if (client == nullptr) {
return nullptr;
}
if (authToken != nullptr) {
GAPID_INFO("Checking auth-token...");
char header[sizeof(kAuthTokenHeader)];
if (client->recv(&header, sizeof(header)) != sizeof(header)) {
GAPID_WARNING("Failed to read auth-token header");
continue;
}
if (memcmp(header, kAuthTokenHeader, sizeof(kAuthTokenHeader)) != 0) {
GAPID_WARNING("Invalid auth-token header");
continue;
}
std::string gotAuthToken;
if (!client->readString(&gotAuthToken) || gotAuthToken != authToken) {
GAPID_WARNING("Invalid auth-token");
continue;
}
}
uint8_t connectionType;
if (client->recv(&connectionType, sizeof(connectionType)) != sizeof(connectionType)) {
GAPID_WARNING("Failed to read connection type");
continue;
}
switch (connectionType) {
case DEVICE_INFO: {
GAPID_INFO("Sending device info");
uint8_t ptrSize = sizeof(void*);
uint8_t ptrAlign = std::alignment_of<void*>::value;
uint8_t targetOs = TARGET_OS;
// TODO(antiagainst): also return information about Vulkan implementation.
std::unique_ptr<GlesRenderer> gl(GlesRenderer::create());
gl->bind();
Gles::GLint glUniformBufferAlignment = 1;
gl->getApi<Gles>()->mFunctionStubs.glGetIntegerv(
Gles::GLenum::GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
&glUniformBufferAlignment
);
bool ok = client->send(kProtocolVersion);
ok = ok && client->sendString(gapic::supportedABIs());
bool glSupport = true;
ok = ok && client->send(static_cast<uint8_t>(glSupport));
if (glSupport) {
ok = ok && client->sendString(gl->extensions());
ok = ok && client->sendString(gl->name());
ok = ok && client->sendString(gl->vendor());
ok = ok && client->sendString(gl->version());
ok = ok && client->send(static_cast<uint16_t>(glUniformBufferAlignment));
}
gl->unbind();
bool vkSupport = true; // TODO
ok = ok && client->send(static_cast<uint8_t>(vkSupport));
if (vkSupport) {
ok = ok && client->sendString("TODO: extensions");
ok = ok && client->sendString("TODO: name");
ok = ok && client->sendString("TODO: vendor");
ok = ok && client->sendString("TODO: version");
}
if (!ok) {
GAPID_WARNING("Failed to send device info");
break;
}
GAPID_INFO("Sent device info");
break;
}
case REPLAY_REQUEST: {
GAPID_INFO("Replay requested");
std::unique_ptr<ServerConnection> conn = ServerConnection::create(std::move(client));
if (conn != nullptr) {
return conn;
} else {
GAPID_WARNING("Loading ServerConnection failed!");
}
break;
}
case SHUTDOWN_REQUEST: {
GAPID_INFO("Shutdown request received!");
return nullptr;
}
case PING: {
client->sendString("PONG");
break;
}
default: {
GAPID_WARNING("Unknown connection type %d ignored", connectionType);
}
}
}
}
} // namespace gapir