blob: 0ba8f7a5117053acfd46d55ceb31b64b716cd0e4 [file] [log] [blame]
/*
* Copyright (C) 2015, 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 <string>
#include <gtest/gtest.h>
#include "aidl.h"
#include "aidl_language.h"
#include "ast_cpp.h"
#include "code_writer.h"
#include "generate_cpp.h"
#include "tests/fake_io_delegate.h"
#include "type_cpp.h"
using android::aidl::test::FakeIoDelegate;
using std::string;
using std::unique_ptr;
namespace android {
namespace aidl {
namespace cpp {
namespace {
const char kTrivialInterfaceAIDL[] =
R"(interface IPingResponder {
int Ping(String token);
})";
const char kExpectedTrivialClientSourceOutput[] =
R"(#include <BpPingResponder.h>
#include <binder/Parcel.h>
namespace android {
namespace generated {
BpPingResponder::BpPingResponder(const android::sp<android::IBinder>& impl)
: BpInterface<IPingResponder>(impl){
}
android::status_t BpPingResponder::Ping(android::String16 token, int32_t* _aidl_return) {
android::Parcel data;
android::Parcel reply;
android::status_t status;
status = data.writeString16(token);
if (status != android::OK) { return status; }
status = remote()->transact(IPingResponder::PING, data, &reply);
if (status != android::OK) { return status; }
status = reply.readInt32(_aidl_return);
if (status != android::OK) { return status; }
return status;
}
} // namespace generated
} // namespace android
)";
const char kExpectedTrivialServerHeaderOutput[] =
R"(#ifndef AIDL_GENERATED__BN_PING_RESPONDER_H_
#define AIDL_GENERATED__BN_PING_RESPONDER_H_
#include <binder/IInterface.h>
#include <IPingResponder.h>
namespace android {
namespace generated {
class BnPingResponder : public android::BnInterface<IPingResponder> {
public:
android::status_t onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags = 0) override;
}; // class BnPingResponder
} // namespace generated
} // namespace android
#endif // AIDL_GENERATED__BN_PING_RESPONDER_H_)";
const char kExpectedTrivialServerSourceOutput[] =
R"(#include <BnPingResponder.h>
#include <binder/Parcel.h>
namespace android {
namespace generated {
android::status_t BnPingResponder::onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags) {
android::status_t status;
switch (code) {
case Call::PING:
{
android::String16 in_token;
int32_t _aidl_return;
status = data.readString16(&in_token);
if (status != android::OK) { break; }
status = Ping(in_token, &_aidl_return);
if (status != android::OK) { break; }
status = reply->writeInt32(_aidl_return);
if (status != android::OK) { break; }
}
break;
default:
{
status = android::BBinder::onTransact(code, data, reply, flags);
}
break;
}
return status;
}
} // namespace generated
} // namespace android
)";
const char kExpectedTrivialClientHeaderOutput[] =
R"(#ifndef AIDL_GENERATED__BP_PING_RESPONDER_H_
#define AIDL_GENERATED__BP_PING_RESPONDER_H_
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <utils/Errors.h>
#include <IPingResponder.h>
namespace android {
namespace generated {
class BpPingResponder : public android::BpInterface<IPingResponder> {
public:
explicit BpPingResponder(const android::sp<android::IBinder>& impl);
virtual ~BpPingResponder() = default;
android::status_t Ping(android::String16 token, int32_t* _aidl_return) override;
}; // class BpPingResponder
} // namespace generated
} // namespace android
#endif // AIDL_GENERATED__BP_PING_RESPONDER_H_)";
const char kExpectedTrivialInterfaceHeaderOutput[] =
R"(#ifndef AIDL_GENERATED__I_PING_RESPONDER_H_
#define AIDL_GENERATED__I_PING_RESPONDER_H_
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <cstdint>
#include <utils/String16.h>
namespace android {
namespace generated {
class IPingResponder : public android::IInterface {
public:
DECLARE_META_INTERFACE(PingResponder);
virtual android::status_t Ping(android::String16 token, int32_t* _aidl_return) = 0;
enum Call {
PING = android::IBinder::FIRST_CALL_TRANSACTION + 0,
};
}; // class IPingResponder
} // namespace generated
} // namespace android
#endif // AIDL_GENERATED__I_PING_RESPONDER_H_)";
const char kExpectedTrivialInterfaceSourceOutput[] =
R"(#include <IPingResponder.h>
#include <BpPingResponder.h>
namespace android {
namespace generated {
IMPLEMENT_META_INTERFACE(PingResponder, "IPingResponder");
} // namespace generated
} // namespace android
)";
} // namespace
class TrivialInterfaceASTTest : public ::testing::Test {
protected:
AidlInterface* Parse() {
FakeIoDelegate io_delegate;
io_delegate.SetFileContents("IPingResponder.aidl", kTrivialInterfaceAIDL);
cpp::TypeNamespace types;
AidlInterface* ret = nullptr;
std::vector<std::unique_ptr<AidlImport>> imports;
int err = ::android::aidl::internals::load_and_validate_aidl(
{}, // no preprocessed files
{}, // no import paths
"IPingResponder.aidl",
io_delegate,
&types,
&ret,
&imports);
if (err)
return nullptr;
return ret;
}
void Compare(Document* doc, const char* expected) {
string output;
unique_ptr<CodeWriter> cw = GetStringWriter(&output);
doc->Write(cw.get());
EXPECT_EQ(expected, output);
}
};
TEST_F(TrivialInterfaceASTTest, GeneratesClientHeader) {
AidlInterface* interface = Parse();
ASSERT_NE(interface, nullptr);
TypeNamespace types;
unique_ptr<Document> doc = internals::BuildClientHeader(types, *interface);
Compare(doc.get(), kExpectedTrivialClientHeaderOutput);
}
TEST_F(TrivialInterfaceASTTest, GeneratesClientSource) {
AidlInterface* interface = Parse();
ASSERT_NE(interface, nullptr);
TypeNamespace types;
unique_ptr<Document> doc = internals::BuildClientSource(types, *interface);
Compare(doc.get(), kExpectedTrivialClientSourceOutput);
}
TEST_F(TrivialInterfaceASTTest, GeneratesServerHeader) {
AidlInterface* interface = Parse();
ASSERT_NE(interface, nullptr);
TypeNamespace types;
unique_ptr<Document> doc = internals::BuildServerHeader(types, *interface);
Compare(doc.get(), kExpectedTrivialServerHeaderOutput);
}
TEST_F(TrivialInterfaceASTTest, GeneratesServerSource) {
AidlInterface* interface = Parse();
ASSERT_NE(interface, nullptr);
TypeNamespace types;
unique_ptr<Document> doc = internals::BuildServerSource(types, *interface);
Compare(doc.get(), kExpectedTrivialServerSourceOutput);
}
TEST_F(TrivialInterfaceASTTest, GeneratesInterfaceHeader) {
AidlInterface* interface = Parse();
ASSERT_NE(interface, nullptr);
TypeNamespace types;
unique_ptr<Document> doc = internals::BuildInterfaceHeader(types, *interface);
Compare(doc.get(), kExpectedTrivialInterfaceHeaderOutput);
}
TEST_F(TrivialInterfaceASTTest, GeneratesInterfaceSource) {
AidlInterface* interface = Parse();
ASSERT_NE(interface, nullptr);
TypeNamespace types;
unique_ptr<Document> doc = internals::BuildInterfaceSource(types, *interface);
Compare(doc.get(), kExpectedTrivialInterfaceSourceOutput);
}
} // namespace cpp
} // namespace aidl
} // namespace android