| /* |
| * 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. |
| */ |
| |
| #include "BinderServer.h" |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #include <string> |
| #include <iostream> |
| |
| #include <utils/RefBase.h> |
| #define LOG_TAG "VtsFuzzerBinderServer" |
| #include <utils/Log.h> |
| #include <utils/String8.h> |
| |
| #include <binder/TextOutput.h> |
| #include <binder/IInterface.h> |
| #include <binder/IBinder.h> |
| #include <binder/ProcessState.h> |
| #include <binder/IServiceManager.h> |
| #include <binder/IPCThreadState.h> |
| |
| #include "binder/VtsFuzzerBinderService.h" |
| #include "specification_parser/SpecificationBuilder.h" |
| |
| #include <google/protobuf/text_format.h> |
| #include "test/vts/sysfuzzer/common/proto/InterfaceSpecificationMessage.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", __FUNCTION__, code, flags); |
| |
| data.checkInterface(this); |
| #ifdef VTS_FUZZER_BINDER_DEBUG |
| data.print(PLOG); |
| endl(PLOG); |
| #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(); |
| int32_t result = LoadHal(string(path), target_class, target_type, |
| target_version); |
| ALOGD("BnVtsFuzzer::%s LoadHal(%s) -> %i", |
| __FUNCTION__, path, result); |
| if (reply == NULL) { |
| ALOGE("reply == NULL"); |
| abort(); |
| } |
| #ifdef VTS_FUZZER_BINDER_DEBUG |
| reply->print(PLOG); |
| endl(PLOG); |
| #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 |
| reply->print(PLOG); |
| endl(PLOG); |
| #endif |
| reply->writeInt32(result); |
| break; |
| } |
| case CALL: { |
| const char* arg = data.readCString(); |
| const char* result = Call(arg); |
| |
| ALOGD("BnVtsFuzzer::%s call(%s) = %i", |
| __FUNCTION__, arg, result); |
| if (reply == NULL) { |
| ALOGE("reply == NULL"); |
| abort(); |
| } |
| #ifdef VTS_FUZZER_BINDER_DEBUG |
| reply->print(PLOG); |
| endl(PLOG); |
| #endif |
| reply->writeCString(result); |
| break; |
| } |
| case GET_FUNCTIONS: { |
| const char* result = GetFunctions(); |
| |
| if (reply == NULL) { |
| ALOGE("reply == NULL"); |
| abort(); |
| } |
| #ifdef VTS_FUZZER_BINDER_DEBUG |
| reply->print(PLOG); |
| endl(PLOG); |
| #endif |
| reply->writeCString(result); |
| break; |
| } |
| default: |
| return BBinder::onTransact(code, data, reply, flags); |
| } |
| return NO_ERROR; |
| } |
| |
| |
| class VtsFuzzerServer : public BnVtsFuzzer { |
| |
| public: |
| VtsFuzzerServer(android::vts::SpecificationBuilder& spec_builder, |
| const char* lib_path) |
| : spec_builder_(spec_builder), |
| 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) { |
| printf("VtsFuzzerServer::LoadHal(%s)\n", path.c_str()); |
| bool success = spec_builder_.LoadTargetComponent( |
| path.c_str(), lib_path_, target_class, target_type, target_version); |
| 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; |
| } |
| |
| const char* Call(const string& arg) { |
| printf("VtsFuzzerServer::Call(%s)\n", arg.c_str()); |
| FunctionSpecificationMessage* func_msg = new FunctionSpecificationMessage(); |
| google::protobuf::TextFormat::MergeFromString(arg, func_msg); |
| printf("call!!!\n"); |
| spec_builder_.CallFunction(func_msg); |
| return arg.c_str(); |
| } |
| |
| const char* GetFunctions() { |
| printf("Get functions*"); |
| vts::InterfaceSpecificationMessage* spec = |
| spec_builder_.GetInterfaceSpecification(); |
| 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::SpecificationBuilder& spec_builder_; |
| const char* lib_path_; |
| }; |
| |
| |
| void StartBinderServer(android::vts::SpecificationBuilder& spec_builder, |
| const char* lib_path) { |
| defaultServiceManager()->addService( |
| String16(VTS_FUZZER_BINDER_SERVICE_NAME), |
| new VtsFuzzerServer(spec_builder, lib_path)); |
| android::ProcessState::self()->startThreadPool(); |
| IPCThreadState::self()->joinThreadPool(); |
| } |
| |
| } // namespace vts |
| } // namespace android |