/*
* Copyright 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.
*/
#ifdef VTS_AGENT_DRIVER_COMM_BINDER // binder
#include "BinderServer.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <utils/RefBase.h>
#define LOG_TAG "VtsFuzzerBinderServer"
#include <utils/Log.h>
#include <utils/String8.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/TextOutput.h>
#include "binder/VtsFuzzerBinderService.h"
#include <google/protobuf/text_format.h>
#include "test/vts/proto/ComponentSpecificationMessage.pb.h"
using namespace std;
namespace android {
namespace vts {
class BnVtsFuzzer : public BnInterface<IVtsFuzzer> {
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags = 0);
};
status_t BnVtsFuzzer::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
ALOGD("BnVtsFuzzer::%s(%i) %i", __func__, code, flags);
data.checkInterface(this);
#ifdef VTS_FUZZER_BINDER_DEBUG
alog << data << endl;
#endif
switch (code) {
case EXIT:
Exit();
break;
case LOAD_HAL: {
const char* path = data.readCString();
const int target_class = data.readInt32();
const int target_type = data.readInt32();
const float target_version = data.readFloat();
const char* module_name = data.readCString();
int32_t result = LoadHal(string(path), target_class, target_type,
target_version, string(module_name));
ALOGD("BnVtsFuzzer::%s LoadHal(%s) -> %i", __FUNCTION__, path, result);
if (reply == NULL) {
ALOGE("reply == NULL");
abort();
}
#ifdef VTS_FUZZER_BINDER_DEBUG
alog << reply << endl;
#endif
reply->writeInt32(result);
break;
}
case STATUS: {
int32_t type = data.readInt32();
int32_t result = Status(type);
ALOGD("BnVtsFuzzer::%s status(%i) -> %i", __FUNCTION__, type, result);
if (reply == NULL) {
ALOGE("reply == NULL");
abort();
}
#ifdef VTS_FUZZER_BINDER_DEBUG
alog << reply << endl;
#endif
reply->writeInt32(result);
break;
}
case CALL: {
const char* arg = data.readCString();
const string& result = Call(arg);
ALOGD("BnVtsFuzzer::%s call(%s) = %i", __FUNCTION__, arg, result.c_str());
if (reply == NULL) {
ALOGE("reply == NULL");
abort();
}
#ifdef VTS_FUZZER_BINDER_DEBUG
alog << reply << endl;
#endif
reply->writeCString(result.c_str());
break;
}
case GET_FUNCTIONS: {
const char* result = GetFunctions();
if (reply == NULL) {
ALOGE("reply == NULL");
abort();
}
#ifdef VTS_FUZZER_BINDER_DEBUG
alog << reply << endl;
#endif
reply->writeCString(result);
break;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
return NO_ERROR;
}
class VtsFuzzerServer : public BnVtsFuzzer {
public:
VtsFuzzerServer(android::vts::VtsHalDriverManager* driver_manager,
const char* lib_path)
: driver_manager_(driver_manager), lib_path_(lib_path) {}
void Exit() { printf("VtsFuzzerServer::Exit\n"); }
int32_t LoadHal(const string& path, int target_class, int target_type,
float target_version, const string& module_name) {
printf("VtsFuzzerServer::LoadHal(%s)\n", path.c_str());
bool success = driver_manager_->LoadTargetComponent(
path.c_str(), lib_path_, target_class, target_type, target_version, "",
"", "", module_name.c_str());
cout << "Result: " << success << std::endl;
if (success) {
return 0;
} else {
return -1;
}
}
int32_t Status(int32_t type) {
printf("VtsFuzzerServer::Status(%i)\n", type);
return 0;
}
string Call(const string& arg) {
printf("VtsFuzzerServer::Call(%s)\n", arg.c_str());
FunctionCallMessage* call_msg = new FunctionCallMessage();
google::protobuf::TextFormat::MergeFromString(arg, call_msg);
return driver_manager_->CallFunction(call_msg);
}
const char* GetFunctions() {
printf("Get functions*");
vts::ComponentSpecificationMessage* spec =
driver_manager_->GetComponentSpecification();
if (!spec) {
return NULL;
}
string* output = new string();
printf("getfunctions serial1\n");
if (google::protobuf::TextFormat::PrintToString(*spec, output)) {
printf("getfunctions length %d\n", output->length());
return output->c_str();
} else {
printf("can't serialize the interface spec message to a string.\n");
return NULL;
}
}
private:
android::vts::VtsHalDriverManager* driver_manager_;
const char* lib_path_;
};
void StartBinderServer(const string& service_name,
android::vts::VtsHalDriverManager* driver_manager,
const char* lib_path) {
defaultServiceManager()->addService(
String16(service_name.c_str()),
new VtsFuzzerServer(driver_manager, lib_path));
android::ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
} // namespace vts
} // namespace android
#endif