1 /*
2 * Copyright (C) 2015, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <memory>
18 #include <set>
19 #include <string>
20 #include <vector>
21
22 #include <android-base/stringprintf.h>
23 #include <gtest/gtest.h>
24
25 #include "aidl.h"
26 #include "aidl_apicheck.h"
27 #include "aidl_language.h"
28 #include "aidl_to_cpp.h"
29 #include "tests/fake_io_delegate.h"
30 #include "type_cpp.h"
31 #include "type_java.h"
32 #include "type_namespace.h"
33
34 using android::aidl::test::FakeIoDelegate;
35 using android::base::StringPrintf;
36 using std::set;
37 using std::string;
38 using std::unique_ptr;
39 using std::vector;
40 using android::aidl::internals::parse_preprocessed_file;
41
42 namespace android {
43 namespace aidl {
44 namespace {
45
46 const char kExpectedDepFileContents[] =
47 R"(place/for/output/p/IFoo.java : \
48 p/IFoo.aidl
49
50 p/IFoo.aidl :
51 )";
52
53 const char kExpectedNinjaDepFileContents[] =
54 R"(place/for/output/p/IFoo.java : \
55 p/IFoo.aidl
56 )";
57
58 const char kExpectedParcelableDepFileContents[] =
59 R"(place/for/output/p/Foo.java : \
60 p/Foo.aidl
61
62 p/Foo.aidl :
63 )";
64
65 const char kExepectedJavaParcelableOutputContests[] =
66 R"(/*
67 * This file is auto-generated. DO NOT MODIFY.
68 */
69 @android.annotation.SystemApi
70 public class Rect implements android.os.Parcelable
71 {
72 // Comment
73
74 @android.annotation.SystemApi
75 public int x = 5;
76
77 @android.annotation.UnsupportedAppUsage
78 @android.annotation.SystemApi
79 public int y;
80 public static final android.os.Parcelable.Creator<Rect> CREATOR = new android.os.Parcelable.Creator<Rect>() {
81 @Override
82 public Rect createFromParcel(android.os.Parcel _aidl_source) {
83 Rect _aidl_out = new Rect();
84 _aidl_out.readFromParcel(_aidl_source);
85 return _aidl_out;
86 }
87 @Override
88 public Rect[] newArray(int _aidl_size) {
89 return new Rect[_aidl_size];
90 }
91 };
92 @Override public final void writeToParcel(android.os.Parcel _aidl_parcel, int _aidl_flag)
93 {
94 int _aidl_start_pos = _aidl_parcel.dataPosition();
95 _aidl_parcel.writeInt(0);
96 _aidl_parcel.writeInt(x);
97 _aidl_parcel.writeInt(y);
98 int _aidl_end_pos = _aidl_parcel.dataPosition();
99 _aidl_parcel.setDataPosition(_aidl_start_pos);
100 _aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);
101 _aidl_parcel.setDataPosition(_aidl_end_pos);
102 }
103 public final void readFromParcel(android.os.Parcel _aidl_parcel)
104 {
105 int _aidl_start_pos = _aidl_parcel.dataPosition();
106 int _aidl_parcelable_size = _aidl_parcel.readInt();
107 if (_aidl_parcelable_size < 0) return;
108 try {
109 x = _aidl_parcel.readInt();
110 if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
111 y = _aidl_parcel.readInt();
112 if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
113 } finally {
114 _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);
115 }
116 }
117 @Override public int describeContents()
118 {
119 return 0;
120 }
121 }
122 )";
123
124 } // namespace
125
126 class AidlTest : public ::testing::Test {
127 protected:
SetUp()128 void SetUp() override {
129 java_types_.Init();
130 cpp_types_.Init();
131 }
132
Parse(const string & path,const string & contents,TypeNamespace * types,AidlError * error=nullptr,const vector<string> additional_arguments={})133 AidlDefinedType* Parse(const string& path, const string& contents, TypeNamespace* types,
134 AidlError* error = nullptr,
135 const vector<string> additional_arguments = {}) {
136 io_delegate_.SetFileContents(path, contents);
137 vector<string> args;
138 if (types == &java_types_) {
139 args.emplace_back("aidl");
140 } else {
141 args.emplace_back("aidl-cpp");
142 }
143 for (const string& s : additional_arguments) {
144 args.emplace_back(s);
145 }
146 for (const string& f : preprocessed_files_) {
147 args.emplace_back("--preprocessed=" + f);
148 }
149 for (const string& i : import_paths_) {
150 args.emplace_back("--include=" + i);
151 }
152 args.emplace_back(path);
153 Options options = Options::From(args);
154 vector<AidlDefinedType*> defined_types;
155 vector<string> imported_files;
156 ImportResolver import_resolver{io_delegate_, path, import_paths_, {}};
157 AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
158 path, options, io_delegate_, types, &defined_types, &imported_files);
159
160 if (error != nullptr) {
161 *error = actual_error;
162 }
163
164 if (actual_error != AidlError::OK) {
165 return nullptr;
166 }
167
168 EXPECT_EQ(1ul, defined_types.size());
169
170 return defined_types.front();
171 }
172
173 FakeIoDelegate io_delegate_;
174 vector<string> preprocessed_files_;
175 set<string> import_paths_;
176 java::JavaTypeNamespace java_types_;
177 cpp::TypeNamespace cpp_types_;
178 };
179
TEST_F(AidlTest,AcceptMissingPackage)180 TEST_F(AidlTest, AcceptMissingPackage) {
181 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &java_types_));
182 EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &cpp_types_));
183 }
184
TEST_F(AidlTest,RejectsArraysOfBinders)185 TEST_F(AidlTest, RejectsArraysOfBinders) {
186 import_paths_.emplace("");
187 io_delegate_.SetFileContents("bar/IBar.aidl",
188 "package bar; interface IBar {}");
189 string path = "foo/IFoo.aidl";
190 string contents = "package foo;\n"
191 "import bar.IBar;\n"
192 "interface IFoo { void f(in IBar[] input); }";
193 EXPECT_EQ(nullptr, Parse(path, contents, &java_types_));
194 EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types_));
195 }
196
TEST_F(AidlTest,RejectsOnewayOutParameters)197 TEST_F(AidlTest, RejectsOnewayOutParameters) {
198 string oneway_interface =
199 "package a; oneway interface IFoo { void f(out int bar); }";
200 string oneway_method =
201 "package a; interface IBar { oneway void f(out int bar); }";
202 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &cpp_types_));
203 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &java_types_));
204 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &cpp_types_));
205 EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &java_types_));
206 }
207
TEST_F(AidlTest,RejectsOnewayNonVoidReturn)208 TEST_F(AidlTest, RejectsOnewayNonVoidReturn) {
209 string oneway_method = "package a; interface IFoo { oneway int f(); }";
210 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
211 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
212 }
213
TEST_F(AidlTest,RejectsNullablePrimitive)214 TEST_F(AidlTest, RejectsNullablePrimitive) {
215 string oneway_method = "package a; interface IFoo { @nullable int f(); }";
216 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
217 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
218 }
219
TEST_F(AidlTest,RejectsDuplicatedArgumentNames)220 TEST_F(AidlTest, RejectsDuplicatedArgumentNames) {
221 string method = "package a; interface IFoo { void f(int a, int a); }";
222 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, &cpp_types_));
223 EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, &java_types_));
224 }
225
TEST_F(AidlTest,ParsesNullableAnnotation)226 TEST_F(AidlTest, ParsesNullableAnnotation) {
227 for (auto is_nullable: {true, false}) {
228 auto parse_result = Parse(
229 "a/IFoo.aidl",
230 StringPrintf( "package a; interface IFoo {%s String f(); }",
231 (is_nullable) ? "@nullable" : ""),
232 &cpp_types_);
233 ASSERT_NE(nullptr, parse_result);
234 const AidlInterface* interface = parse_result->AsInterface();
235 ASSERT_NE(nullptr, interface);
236 ASSERT_FALSE(interface->GetMethods().empty());
237 EXPECT_EQ(interface->GetMethods()[0]->GetType().IsNullable(), is_nullable);
238 cpp_types_.typenames_.Reset();
239 }
240 }
241
TEST_F(AidlTest,ParsesUtf8Annotations)242 TEST_F(AidlTest, ParsesUtf8Annotations) {
243 for (auto is_utf8: {true, false}) {
244 auto parse_result = Parse(
245 "a/IFoo.aidl",
246 StringPrintf( "package a; interface IFoo {%s String f(); }",
247 (is_utf8) ? "@utf8InCpp" : ""),
248 &cpp_types_);
249 ASSERT_NE(nullptr, parse_result);
250 const AidlInterface* interface = parse_result->AsInterface();
251 ASSERT_NE(nullptr, interface);
252 ASSERT_FALSE(interface->GetMethods().empty());
253 EXPECT_EQ(interface->GetMethods()[0]->GetType().IsUtf8InCpp(), is_utf8);
254 cpp_types_.typenames_.Reset();
255 }
256 }
257
TEST_F(AidlTest,AcceptsOneway)258 TEST_F(AidlTest, AcceptsOneway) {
259 string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
260 string oneway_interface =
261 "package a; oneway interface IBar { void f(int a); }";
262 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
263 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
264 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &cpp_types_));
265 EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &java_types_));
266 }
267
TEST_F(AidlTest,ParsesPreprocessedFile)268 TEST_F(AidlTest, ParsesPreprocessedFile) {
269 string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
270 io_delegate_.SetFileContents("path", simple_content);
271 EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
272 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
273 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
274 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
275 }
276
TEST_F(AidlTest,ParsesPreprocessedFileWithWhitespace)277 TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
278 string simple_content = "parcelable a.Foo;\n interface b.IBar ;\t";
279 io_delegate_.SetFileContents("path", simple_content);
280 EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
281 EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
282 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
283 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
284 }
285
TEST_F(AidlTest,PreferImportToPreprocessed)286 TEST_F(AidlTest, PreferImportToPreprocessed) {
287 io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
288 io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
289 "interface IBar {}");
290 preprocessed_files_.push_back("preprocessed");
291 import_paths_.emplace("");
292 auto parse_result = Parse(
293 "p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
294 &java_types_);
295 EXPECT_NE(nullptr, parse_result);
296 // We expect to know about both kinds of IBar
297 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("one.IBar"));
298 EXPECT_TRUE(java_types_.HasTypeByCanonicalName("another.IBar"));
299 // But if we request just "IBar" we should get our imported one.
300 AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, "");
301 const java::Type* type = java_types_.Find(ambiguous_type);
302 ASSERT_TRUE(type);
303 EXPECT_EQ("one.IBar", type->CanonicalName());
304 }
305
TEST_F(AidlTest,WritePreprocessedFile)306 TEST_F(AidlTest, WritePreprocessedFile) {
307 io_delegate_.SetFileContents("p/Outer.aidl",
308 "package p; parcelable Outer.Inner;");
309 io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
310 "interface IBar {}");
311
312 vector<string> args {
313 "aidl",
314 "--preprocess",
315 "preprocessed",
316 "p/Outer.aidl",
317 "one/IBar.aidl"};
318 Options options = Options::From(args);
319 EXPECT_TRUE(::android::aidl::preprocess_aidl(options, io_delegate_));
320
321 string output;
322 EXPECT_TRUE(io_delegate_.GetWrittenContents("preprocessed", &output));
323 EXPECT_EQ("parcelable p.Outer.Inner;\ninterface one.IBar;\n", output);
324 }
325
TEST_F(AidlTest,JavaParcelableOutput)326 TEST_F(AidlTest, JavaParcelableOutput) {
327 io_delegate_.SetFileContents("Rect.aidl",
328 "@SystemApi\n"
329 "parcelable Rect {\n"
330 " // Comment\n"
331 " @SystemApi\n"
332 " int x=5;\n"
333 " @SystemApi\n"
334 " @UnsupportedAppUsage\n"
335 " int y;\n"
336 "}");
337
338 vector<string> args{"aidl", "Rect.aidl"};
339 Options options = Options::From(args);
340 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
341
342 string output;
343 EXPECT_TRUE(io_delegate_.GetWrittenContents("Rect.java", &output));
344 EXPECT_EQ(kExepectedJavaParcelableOutputContests, output);
345 }
346
TEST_F(AidlTest,RequireOuterClass)347 TEST_F(AidlTest, RequireOuterClass) {
348 io_delegate_.SetFileContents("p/Outer.aidl",
349 "package p; parcelable Outer.Inner;");
350 import_paths_.emplace("");
351 auto parse_result = Parse(
352 "p/IFoo.aidl",
353 "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
354 &java_types_);
355 EXPECT_EQ(nullptr, parse_result);
356 }
357
TEST_F(AidlTest,ParseCompoundParcelableFromPreprocess)358 TEST_F(AidlTest, ParseCompoundParcelableFromPreprocess) {
359 io_delegate_.SetFileContents("preprocessed",
360 "parcelable p.Outer.Inner;");
361 preprocessed_files_.push_back("preprocessed");
362 auto parse_result = Parse(
363 "p/IFoo.aidl",
364 "package p; interface IFoo { void f(in Inner c); }",
365 &java_types_);
366 // TODO(wiley): This should actually return nullptr because we require
367 // the outer class name. However, for legacy reasons,
368 // this behavior must be maintained. b/17415692
369 EXPECT_NE(nullptr, parse_result);
370 }
371
TEST_F(AidlTest,FailOnParcelable)372 TEST_F(AidlTest, FailOnParcelable) {
373 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; parcelable IFoo;");
374
375 // By default, we shouldn't fail on parcelable.
376 Options options1 = Options::From("aidl p/IFoo.aidl");
377 EXPECT_EQ(0, ::android::aidl::compile_aidl(options1, io_delegate_));
378
379 // -b considers this an error
380 Options options2 = Options::From("aidl -b p/IFoo.aidl");
381 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
382
383 io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
384
385 // Regardless of '-b', a parcelable and an interface should fail.
386 Options options3 = Options::From("aidl p/IBar.aidl");
387 EXPECT_EQ(0, ::android::aidl::compile_aidl(options3, io_delegate_));
388 Options options4 = Options::From("aidl -b p/IBar.aidl");
389 EXPECT_NE(0, ::android::aidl::compile_aidl(options4, io_delegate_));
390 }
391
TEST_F(AidlTest,StructuredFailOnUnstructuredParcelable)392 TEST_F(AidlTest, StructuredFailOnUnstructuredParcelable) {
393 io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl", "package o; parcelable WhoKnowsWhat;");
394 import_paths_.emplace("");
395 AidlError reported_error;
396 auto parse_result =
397 Parse("p/IFoo.aidl",
398 "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
399 &java_types_, &reported_error, {"--structured"});
400 EXPECT_EQ(nullptr, parse_result);
401 EXPECT_EQ(AidlError::NOT_STRUCTURED, reported_error);
402 }
403
TEST_F(AidlTest,FailOnDuplicateConstantNames)404 TEST_F(AidlTest, FailOnDuplicateConstantNames) {
405 AidlError reported_error;
406 EXPECT_EQ(nullptr,
407 Parse("p/IFoo.aidl",
408 R"(package p;
409 interface IFoo {
410 const String DUPLICATED = "d";
411 const int DUPLICATED = 1;
412 }
413 )",
414 &cpp_types_,
415 &reported_error));
416 EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
417 }
418
TEST_F(AidlTest,FailOnManyDefinedTypes)419 TEST_F(AidlTest, FailOnManyDefinedTypes) {
420 AidlError reported_error;
421 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
422 R"(package p;
423 interface IFoo {}
424 parcelable Bar;
425 parcelable IBar {}
426 parcelable StructuredParcelable {}
427 interface IBaz {}
428 )",
429 &cpp_types_, &reported_error));
430 // Parse success is important for clear error handling even if the cases aren't
431 // actually supported in code generation.
432 EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
433 }
434
TEST_F(AidlTest,FailOnNoDefinedTypes)435 TEST_F(AidlTest, FailOnNoDefinedTypes) {
436 AidlError reported_error;
437 EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", &cpp_types_, &reported_error));
438 EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
439 }
440
TEST_F(AidlTest,FailOnMalformedConstHexValue)441 TEST_F(AidlTest, FailOnMalformedConstHexValue) {
442 AidlError reported_error;
443 EXPECT_EQ(nullptr,
444 Parse("p/IFoo.aidl",
445 R"(package p;
446 interface IFoo {
447 const int BAD_HEX_VALUE = 0xffffffffffffffffff;
448 }
449 )",
450 &cpp_types_,
451 &reported_error));
452 EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
453 }
454
TEST_F(AidlTest,ParsePositiveConstHexValue)455 TEST_F(AidlTest, ParsePositiveConstHexValue) {
456 AidlError reported_error;
457 auto cpp_parse_result =
458 Parse("p/IFoo.aidl",
459 R"(package p;
460 interface IFoo {
461 const int POSITIVE_HEX_VALUE = 0xf5;
462 }
463 )",
464 &cpp_types_,
465 &reported_error);
466 EXPECT_NE(nullptr, cpp_parse_result);
467 const AidlInterface* interface = cpp_parse_result->AsInterface();
468 ASSERT_NE(nullptr, interface);
469 const auto& cpp_constants = interface->GetConstantDeclarations();
470 EXPECT_EQ((size_t)1, cpp_constants.size());
471 EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
472 EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
473 }
474
TEST_F(AidlTest,ParseNegativeConstHexValue)475 TEST_F(AidlTest, ParseNegativeConstHexValue) {
476 AidlError reported_error;
477 auto cpp_parse_result =
478 Parse("p/IFoo.aidl",
479 R"(package p;
480 interface IFoo {
481 const int NEGATIVE_HEX_VALUE = 0xffffffff;
482 }
483 )",
484 &cpp_types_,
485 &reported_error);
486 EXPECT_NE(nullptr, cpp_parse_result);
487 const AidlInterface* interface = cpp_parse_result->AsInterface();
488 ASSERT_NE(nullptr, interface);
489 const auto& cpp_constants = interface->GetConstantDeclarations();
490 EXPECT_EQ((size_t)1, cpp_constants.size());
491 EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
492 EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
493 }
494
TEST_F(AidlTest,UnderstandsNestedParcelables)495 TEST_F(AidlTest, UnderstandsNestedParcelables) {
496 io_delegate_.SetFileContents(
497 "p/Outer.aidl",
498 "package p; parcelable Outer.Inner cpp_header \"baz/header\";");
499 import_paths_.emplace("");
500 const string input_path = "p/IFoo.aidl";
501 const string input = "package p; import p.Outer; interface IFoo"
502 " { Outer.Inner get(); }";
503
504 auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
505 EXPECT_NE(nullptr, cpp_parse_result);
506 auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Outer.Inner");
507 ASSERT_NE(nullptr, cpp_type);
508 // C++ uses "::" instead of "." to refer to a inner class.
509 EXPECT_EQ("::p::Outer::Inner", cpp_type->CppType());
510 }
511
TEST_F(AidlTest,UnderstandsNativeParcelables)512 TEST_F(AidlTest, UnderstandsNativeParcelables) {
513 io_delegate_.SetFileContents(
514 "p/Bar.aidl",
515 "package p; parcelable Bar cpp_header \"baz/header\";");
516 import_paths_.emplace("");
517 const string input_path = "p/IFoo.aidl";
518 const string input = "package p; import p.Bar; interface IFoo { }";
519
520 // C++ understands C++ specific stuff
521 auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
522 EXPECT_NE(nullptr, cpp_parse_result);
523 auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Bar");
524 ASSERT_NE(nullptr, cpp_type);
525 EXPECT_EQ("::p::Bar", cpp_type->CppType());
526 set<string> headers;
527 cpp_type->GetHeaders(&headers);
528 EXPECT_EQ(1u, headers.size());
529 EXPECT_EQ(1u, headers.count("baz/header"));
530
531 // Java ignores C++ specific stuff
532 auto java_parse_result = Parse(input_path, input, &java_types_);
533 EXPECT_NE(nullptr, java_parse_result);
534 auto java_type = java_types_.FindTypeByCanonicalName("p.Bar");
535 ASSERT_NE(nullptr, java_type);
536 EXPECT_EQ("p.Bar", java_type->InstantiableName());
537 }
538
TEST_F(AidlTest,WritesCorrectDependencyFile)539 TEST_F(AidlTest, WritesCorrectDependencyFile) {
540 // While the in tree build system always gives us an output file name,
541 // other android tools take advantage of our ability to infer the intended
542 // file name. This test makes sure we handle this correctly.
543 vector<string> args = {
544 "aidl",
545 "-d dep/file/path",
546 "-o place/for/output",
547 "p/IFoo.aidl"};
548 Options options = Options::From(args);
549 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
550 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
551 string actual_dep_file_contents;
552 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
553 EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
554 }
555
TEST_F(AidlTest,WritesCorrectDependencyFileNinja)556 TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
557 // While the in tree build system always gives us an output file name,
558 // other android tools take advantage of our ability to infer the intended
559 // file name. This test makes sure we handle this correctly.
560 vector<string> args = {
561 "aidl",
562 "-d dep/file/path",
563 "--ninja",
564 "-o place/for/output",
565 "p/IFoo.aidl"};
566 Options options = Options::From(args);
567 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
568 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
569 string actual_dep_file_contents;
570 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
571 EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
572 }
573
TEST_F(AidlTest,WritesTrivialDependencyFileForParcelable)574 TEST_F(AidlTest, WritesTrivialDependencyFileForParcelable) {
575 // The SDK uses aidl to decide whether a .aidl file is a parcelable. It does
576 // this by calling aidl with every .aidl file it finds, then parsing the
577 // generated dependency files. Those that reference .java output files are
578 // for interfaces and those that do not are parcelables. However, for both
579 // parcelables and interfaces, we *must* generate a non-empty dependency file.
580 vector<string> args = {
581 "aidl",
582 "-o place/for/output",
583 "-d dep/file/path",
584 "p/Foo.aidl"};
585 Options options = Options::From(args);
586 io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
587 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
588 string actual_dep_file_contents;
589 EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
590 EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDepFileContents);
591 }
592
593 /* not working until type_namespace.h is fixed
594 TEST_F(AidlTest, AcceptsNestedContainerType) {
595 string nested_in_iface = "package a; interface IFoo {\n"
596 " List<int, List<String, bool>> foo(); }";
597 string nested_in_parcelable = "package a; parcelable IData {\n"
598 " List<int, List<String, bool>> foo;}";
599 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &java_types_));
600 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &cpp_types_));
601 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &java_types_));
602 EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &cpp_types_));
603 }
604 */
605
TEST_F(AidlTest,ApiDump)606 TEST_F(AidlTest, ApiDump) {
607 io_delegate_.SetFileContents(
608 "foo/bar/IFoo.aidl",
609 "package foo.bar;\n"
610 "import foo.bar.Data;\n"
611 "// comment\n"
612 "interface IFoo {\n"
613 " int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
614 " int foo2(@utf8InCpp String x, inout List<String> y);\n"
615 " IFoo foo3(IFoo foo);\n"
616 " Data getData();\n"
617 " const int A = 1;\n"
618 " const String STR = \"Hello\";\n"
619 "}\n");
620 io_delegate_.SetFileContents("foo/bar/Data.aidl",
621 "package foo.bar;\n"
622 "import foo.bar.IFoo;\n"
623 "parcelable Data {\n"
624 " int x = 10;\n"
625 " int y;\n"
626 " IFoo foo;\n"
627 " List<IFoo> a;\n"
628 " List<foo.bar.IFoo> b;\n"
629 " @nullable String[] c;\n"
630 "}\n");
631 io_delegate_.SetFileContents("api.aidl", "");
632 vector<string> args = {"aidl", "--dumpapi", "--out=dump", "foo/bar/IFoo.aidl",
633 "foo/bar/Data.aidl"};
634 Options options = Options::From(args);
635 bool result = dump_api(options, io_delegate_);
636 ASSERT_TRUE(result);
637 string actual;
638 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
639 EXPECT_EQ(actual, R"(package foo.bar;
640 interface IFoo {
641 int foo(out int[] a, String b, boolean c, inout List<String> d);
642 int foo2(@utf8InCpp String x, inout List<String> y);
643 foo.bar.IFoo foo3(foo.bar.IFoo foo);
644 foo.bar.Data getData();
645 const int A = 1;
646 const String STR = "Hello";
647 }
648 )");
649
650 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
651 EXPECT_EQ(actual, R"(package foo.bar;
652 parcelable Data {
653 int x = 10;
654 int y;
655 foo.bar.IFoo foo;
656 List<foo.bar.IFoo> a;
657 List<foo.bar.IFoo> b;
658 @nullable String[] c;
659 }
660 )");
661 }
662
TEST_F(AidlTest,ApiDumpWithManualIds)663 TEST_F(AidlTest, ApiDumpWithManualIds) {
664 io_delegate_.SetFileContents(
665 "foo/bar/IFoo.aidl",
666 "package foo.bar;\n"
667 "interface IFoo {\n"
668 " int foo() = 1;\n"
669 " int bar() = 2;\n"
670 " int baz() = 10;\n"
671 "}\n");
672
673 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
674 Options options = Options::From(args);
675 bool result = dump_api(options, io_delegate_);
676 ASSERT_TRUE(result);
677 string actual;
678 EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
679 EXPECT_EQ(actual, R"(package foo.bar;
680 interface IFoo {
681 int foo() = 1;
682 int bar() = 2;
683 int baz() = 10;
684 }
685 )");
686 }
687
TEST_F(AidlTest,ApiDumpWithManualIdsOnlyOnSomeMethods)688 TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
689 io_delegate_.SetFileContents(
690 "foo/bar/IFoo.aidl",
691 "package foo.bar;\n"
692 "interface IFoo {\n"
693 " int foo() = 1;\n"
694 " int bar();\n"
695 " int baz() = 10;\n"
696 "}\n");
697
698 vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
699 Options options = Options::From(args);
700 EXPECT_FALSE(dump_api(options, io_delegate_));
701 }
702
TEST_F(AidlTest,CheckNumGenericTypeSecifier)703 TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
704 Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
705 io_delegate_.SetFileContents(options.InputFiles().front(),
706 "package p; interface IFoo {"
707 "void foo(List<String, String> a);}");
708 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
709
710 io_delegate_.SetFileContents(options.InputFiles().front(),
711 "package p; interface IFoo {"
712 "void foo(Map<String> a);}");
713 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
714
715 Options options2 = Options::From("aidl p/Data.aidl Data.java");
716 io_delegate_.SetFileContents(options2.InputFiles().front(),
717 "package p; parcelable Data {"
718 "List<String, String> foo;}");
719 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
720
721 io_delegate_.SetFileContents(options2.InputFiles().front(),
722 "package p; parcelable Data {"
723 "Map<String> foo;}");
724 EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
725 }
726
TEST_F(AidlTest,MultipleTypesInSingleFile)727 TEST_F(AidlTest, MultipleTypesInSingleFile) {
728 Options options = Options::From("aidl --lang=java -o out foo/bar/Foo.aidl");
729 io_delegate_.SetFileContents(options.InputFiles().front(),
730 "package foo.bar;\n"
731 "interface IFoo1 { int foo(); }\n"
732 "interface IFoo2 { int foo(); }\n"
733 "parcelable Data { int a; int b;}\n");
734
735 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
736
737 string content;
738 for (const auto file :
739 {"out/foo/bar/IFoo1.java", "out/foo/bar/IFoo2.java", "out/foo/bar/Data.java"}) {
740 content.clear();
741 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
742 EXPECT_FALSE(content.empty());
743 }
744 }
745
TEST_F(AidlTest,MultipleTypesInSingleFileCpp)746 TEST_F(AidlTest, MultipleTypesInSingleFileCpp) {
747 Options options = Options::From("aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl");
748 io_delegate_.SetFileContents(options.InputFiles().front(),
749 "package foo.bar;\n"
750 "interface IFoo1 { int foo(); }\n"
751 "interface IFoo2 { int foo(); }\n"
752 "parcelable Data { int a; int b;}\n");
753
754 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
755
756 string content;
757 for (const auto file : {
758 "out/foo/bar/IFoo1.cpp", "out/foo/bar/IFoo2.cpp", "out/foo/bar/Data.cpp",
759 "out/include/foo/bar/IFoo1.h", "out/include/foo/bar/IFoo2.h", "out/include/foo/bar/Data.h",
760 "out/include/foo/bar/BpFoo1.h", "out/include/foo/bar/BpFoo2.h", "out/include/foo/bar/BpData.h",
761 "out/include/foo/bar/BnFoo1.h", "out/include/foo/bar/BnFoo2.h", "out/include/foo/bar/BnData.h"}) {
762 content.clear();
763 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
764 EXPECT_FALSE(content.empty());
765 }
766 }
767
TEST_F(AidlTest,MultipleInputFiles)768 TEST_F(AidlTest, MultipleInputFiles) {
769 Options options = Options::From(
770 "aidl --lang=java -o out foo/bar/IFoo.aidl foo/bar/Data.aidl");
771
772 io_delegate_.SetFileContents(options.InputFiles().at(0),
773 "package foo.bar;\n"
774 "import foo.bar.Data;\n"
775 "interface IFoo { Data getData(); }\n");
776
777 io_delegate_.SetFileContents(options.InputFiles().at(1),
778 "package foo.bar;\n"
779 "import foo.bar.IFoo;\n"
780 "parcelable Data { IFoo foo; }\n");
781
782 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
783
784 string content;
785 for (const auto file : {
786 "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
787 content.clear();
788 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
789 EXPECT_FALSE(content.empty());
790 }
791 }
792
TEST_F(AidlTest,MultipleInputFilesCpp)793 TEST_F(AidlTest, MultipleInputFilesCpp) {
794 Options options = Options::From("aidl --lang=cpp -o out -h out/include "
795 "foo/bar/IFoo.aidl foo/bar/Data.aidl");
796
797 io_delegate_.SetFileContents(options.InputFiles().at(0),
798 "package foo.bar;\n"
799 "import foo.bar.Data;\n"
800 "interface IFoo { Data getData(); }\n");
801
802 io_delegate_.SetFileContents(options.InputFiles().at(1),
803 "package foo.bar;\n"
804 "import foo.bar.IFoo;\n"
805 "parcelable Data { IFoo foo; }\n");
806
807 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
808
809 string content;
810 for (const auto file : {
811 "out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp",
812 "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
813 "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
814 "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
815 content.clear();
816 EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
817 EXPECT_FALSE(content.empty());
818 }
819 }
820
TEST_F(AidlTest,ConflictWithMetaTransactions)821 TEST_F(AidlTest, ConflictWithMetaTransactions) {
822 Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
823 // int getInterfaceVersion() is one of the meta transactions
824 io_delegate_.SetFileContents(options.InputFiles().front(),
825 "package p; interface IFoo {"
826 "int getInterfaceVersion(); }");
827 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
828
829 // boolean getInterfaceVersion() is not, but should be prevented
830 // because return type is not part of a method signature
831 io_delegate_.SetFileContents(options.InputFiles().front(),
832 "package p; interface IFoo {"
833 "boolean getInterfaceVersion(); }");
834 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
835
836 // this is another reserved name
837 io_delegate_.SetFileContents(options.InputFiles().front(),
838 "package p; interface IFoo {"
839 "String getTransactionName(int code); }");
840 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
841
842 // this is not a meta interface method as it differs type arguments
843 io_delegate_.SetFileContents(options.InputFiles().front(),
844 "package p; interface IFoo {"
845 "String getTransactionName(); }");
846 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
847 }
848
TEST_F(AidlTest,DiffrentOrderAnnotationsInCheckAPI)849 TEST_F(AidlTest, DiffrentOrderAnnotationsInCheckAPI) {
850 Options options = Options::From("aidl --checkapi old new");
851 io_delegate_.SetFileContents("old/p/IFoo.aidl",
852 "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
853 io_delegate_.SetFileContents("new/p/IFoo.aidl",
854 "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
855
856 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
857 }
858
TEST_F(AidlTest,SuccessOnIdenticalApiDumps)859 TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
860 Options options = Options::From("aidl --checkapi old new");
861 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
862 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
863
864 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
865 }
866
TEST_F(AidlTest,SuccessOnCompatibleChanges)867 TEST_F(AidlTest, SuccessOnCompatibleChanges) {
868 Options options = Options::From("aidl --checkapi old new");
869 io_delegate_.SetFileContents("old/p/IFoo.aidl",
870 "package p;"
871 "interface IFoo {"
872 " void foo(int a);"
873 "}");
874 io_delegate_.SetFileContents("old/p/Data.aidl",
875 "package p;"
876 "parcelable Data {"
877 " int foo;"
878 "}");
879
880 // new type
881 io_delegate_.SetFileContents("new/p/IFoo.aidl",
882 "package p;"
883 "interface IFoo {"
884 " void foo(int a);"
885 "}");
886 io_delegate_.SetFileContents("new/p/Data.aidl",
887 "package p;"
888 "parcelable Data {"
889 " int foo;"
890 "}");
891 io_delegate_.SetFileContents("new/p/IBar.aidl",
892 "package p;"
893 "interface IBar {"
894 " void bar();"
895 "}");
896 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
897 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
898 io_delegate_.SetFileContents("new/p/Data.aidl", "");
899 io_delegate_.SetFileContents("new/p/IBar.aidl", "");
900
901 // new method
902 io_delegate_.SetFileContents("new/p/IFoo.aidl",
903 "package p;"
904 "interface IFoo {"
905 " void foo(int a);"
906 " void bar();"
907 "}");
908 io_delegate_.SetFileContents("new/p/Data.aidl",
909 "package p;"
910 "parcelable Data {"
911 " int foo;"
912 "}");
913 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
914 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
915 io_delegate_.SetFileContents("new/p/Data.aidl", "");
916
917 // new field
918 io_delegate_.SetFileContents("new/p/IFoo.aidl",
919 "package p;"
920 "interface IFoo {"
921 " void foo(int a);"
922 "}");
923 io_delegate_.SetFileContents("new/p/Data.aidl",
924 "package p;"
925 "parcelable Data {"
926 " int foo;"
927 " int bar;"
928 "}");
929 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
930 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
931 io_delegate_.SetFileContents("new/p/Data.aidl", "");
932
933 // new package
934 io_delegate_.SetFileContents("new/p/IFoo.aidl",
935 "package p;"
936 "interface IFoo {"
937 " void foo(int a);"
938 "}");
939 io_delegate_.SetFileContents("new/p/Data.aidl",
940 "package p;"
941 "parcelable Data {"
942 " int foo;"
943 "}");
944 io_delegate_.SetFileContents("new/q/IFoo.aidl",
945 "package q;"
946 "interface IFoo {"
947 " void foo(int a);"
948 "}");
949 io_delegate_.SetFileContents("new/q/Data.aidl",
950 "package q;"
951 "parcelable Data {"
952 " int foo;"
953 "}");
954 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
955 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
956 io_delegate_.SetFileContents("new/p/Data.aidl", "");
957 io_delegate_.SetFileContents("new/q/IFoo.aidl", "");
958 io_delegate_.SetFileContents("new/q/Data.aidl", "");
959
960 // arg name change
961 io_delegate_.SetFileContents("new/p/IFoo.aidl",
962 "package p;"
963 "interface IFoo {"
964 " void foo(int b);"
965 "}");
966 io_delegate_.SetFileContents("new/p/Data.aidl",
967 "package p;"
968 "parcelable Data {"
969 " int foo;"
970 "}");
971 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
972 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
973 io_delegate_.SetFileContents("new/p/Data.aidl", "");
974
975 io_delegate_.SetFileContents("old/p/IFoo.aidl", "");
976 io_delegate_.SetFileContents("old/p/Data.aidl", "");
977
978 // added const value
979 io_delegate_.SetFileContents("old/p/I.aidl",
980 "package p; interface I {"
981 "const int A = 1; }");
982 io_delegate_.SetFileContents("new/p/I.aidl",
983 "package p ; interface I {"
984 "const int A = 1; const int B = 2;}");
985 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
986 io_delegate_.SetFileContents("old/p/I.aidl", "");
987 io_delegate_.SetFileContents("new/p/I.aidl", "");
988
989 // changed const value order
990 io_delegate_.SetFileContents("old/p/I.aidl",
991 "package p; interface I {"
992 "const int A = 1; const int B = 2;}");
993 io_delegate_.SetFileContents("new/p/I.aidl",
994 "package p ; interface I {"
995 "const int B = 2; const int A = 1;}");
996 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
997 }
998
TEST_F(AidlTest,FailOnIncompatibleChanges)999 TEST_F(AidlTest, FailOnIncompatibleChanges) {
1000 Options options = Options::From("aidl --checkapi old new");
1001 io_delegate_.SetFileContents("old/p/IFoo.aidl",
1002 "package p;"
1003 "interface IFoo {"
1004 " void foo(in String[] str);"
1005 " void bar(@utf8InCpp String str);"
1006 "}");
1007 io_delegate_.SetFileContents("old/p/Data.aidl",
1008 "package p;"
1009 "parcelable Data {"
1010 " int foo;"
1011 " int bar;"
1012 "}");
1013
1014 // removed type
1015 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1016 "package p;"
1017 "interface IFoo {"
1018 " void foo(in String[] str);"
1019 " void bar(@utf8InCpp String str);"
1020 "}");
1021 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1022 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1023
1024 // removed method
1025 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1026 "package p;"
1027 "interface IFoo {"
1028 " void foo(in String[] str);"
1029 "}");
1030 io_delegate_.SetFileContents("new/p/Data.aidl",
1031 "package p;"
1032 "parcelable Data {"
1033 " int foo;"
1034 " int bar;"
1035 "}");
1036 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1037 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1038 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1039
1040 // removed field
1041 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1042 "package p;"
1043 "interface IFoo {"
1044 " void foo(in String[] str);"
1045 " void bar(@utf8InCpp String str);"
1046 "}");
1047 io_delegate_.SetFileContents("new/p/Data.aidl",
1048 "package p;"
1049 "parcelable Data {"
1050 " int foo;"
1051 "}");
1052 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1053 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1054 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1055
1056 // renamed method
1057 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1058 "package p;"
1059 "interface IFoo {"
1060 " void foo(in String[] str);"
1061 " void bar2(@utf8InCpp String str);"
1062 "}");
1063 io_delegate_.SetFileContents("new/p/Data.aidl",
1064 "package p;"
1065 "parcelable Data {"
1066 " int foo;"
1067 " int bar;"
1068 "}");
1069 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1070 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1071 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1072
1073 // renamed field
1074 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1075 "package p;"
1076 "interface IFoo {"
1077 " void foo(in String[] str);"
1078 " void bar(@utf8InCpp String str);"
1079 "}");
1080 io_delegate_.SetFileContents("new/p/Data.aidl",
1081 "package p;"
1082 "parcelable Data {"
1083 " int foo;"
1084 " int bar2;"
1085 "}");
1086 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1087 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1088 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1089
1090 // renamed type
1091 io_delegate_.SetFileContents("new/p/IFoo2.aidl",
1092 "package p;"
1093 "interface IFoo2 {"
1094 " void foo(in String[] str);"
1095 " void bar(@utf8InCpp String str);"
1096 "}");
1097 io_delegate_.SetFileContents("new/p/Data.aidl",
1098 "package p;"
1099 "parcelable Data {"
1100 " int foo;"
1101 " int bar;"
1102 "}");
1103 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1104 io_delegate_.SetFileContents("new/p/IFoo2.aidl", "");
1105 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1106
1107 // reorderd method
1108 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1109 "package p;"
1110 "interface IFoo {"
1111 " void bar(@utf8InCpp String str);"
1112 " void foo(in String[] str);"
1113 "}");
1114 io_delegate_.SetFileContents("new/p/Data.aidl",
1115 "package p;"
1116 "parcelable Data {"
1117 " int foo;"
1118 " int bar;"
1119 "}");
1120 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1121 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1122 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1123
1124 // reorderd field
1125 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1126 "package p;"
1127 "interface IFoo {"
1128 " void foo(in String[] str);"
1129 " void bar(@utf8InCpp String str);"
1130 "}");
1131 io_delegate_.SetFileContents("new/p/Data.aidl",
1132 "package p;"
1133 "parcelable Data {"
1134 " int bar;"
1135 " int foo;"
1136 "}");
1137 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1138 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1139 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1140
1141 // changed direction specifier
1142 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1143 "package p;"
1144 "interface IFoo {"
1145 " void foo(out String[] str);"
1146 " void bar(@utf8InCpp String str);"
1147 "}");
1148 io_delegate_.SetFileContents("new/p/Data.aidl",
1149 "package p;"
1150 "parcelable Data {"
1151 " int foo;"
1152 " int bar;"
1153 "}");
1154 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1155 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1156 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1157
1158 // added annotation
1159 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1160 "package p;"
1161 "interface IFoo {"
1162 " void foo(in @utf8InCpp String[] str);"
1163 " void bar(@utf8InCpp String str);"
1164 "}");
1165 io_delegate_.SetFileContents("new/p/Data.aidl",
1166 "package p;"
1167 "parcelable Data {"
1168 " int foo;"
1169 " int bar;"
1170 "}");
1171 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1172 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1173 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1174
1175 // removed annotation
1176 io_delegate_.SetFileContents("new/p/IFoo.aidl",
1177 "package p;"
1178 "interface IFoo {"
1179 " void foo(in String[] str);"
1180 " void bar(String str);"
1181 "}");
1182 io_delegate_.SetFileContents("new/p/Data.aidl",
1183 "package p;"
1184 "parcelable Data {"
1185 " int foo;"
1186 " int bar;"
1187 "}");
1188 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1189 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1190 io_delegate_.SetFileContents("new/p/Data.aidl", "");
1191
1192 // removed package
1193 io_delegate_.SetFileContents("old/p/Data.aidl", "");
1194 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
1195 io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
1196
1197 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
1198 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1199 io_delegate_.SetFileContents("old/p/IFoo.aidl", "");
1200 io_delegate_.SetFileContents("old/q/IFoo.aidl", "");
1201 io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
1202
1203 // changed default value
1204 io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
1205 io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
1206 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1207 io_delegate_.SetFileContents("old/p/D.aidl", "");
1208 io_delegate_.SetFileContents("new/p/D.aidl", "");
1209
1210 // removed const value
1211 io_delegate_.SetFileContents("old/p/I.aidl",
1212 "package p; interface I {"
1213 "const int A = 1; const int B = 2;}");
1214 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
1215 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1216 io_delegate_.SetFileContents("old/p/I.aidl", "");
1217 io_delegate_.SetFileContents("new/p/I.aidl", "");
1218
1219 // changed const value
1220 io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
1221 io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
1222 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1223 io_delegate_.SetFileContents("old/p/I.aidl", "");
1224 io_delegate_.SetFileContents("new/p/I.aidl", "");
1225 }
1226
TEST_F(AidlTest,RejectAmbiguousImports)1227 TEST_F(AidlTest, RejectAmbiguousImports) {
1228 Options options = Options::From("aidl --lang=java -o out -I dir1 -I dir2 p/IFoo.aidl");
1229 io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
1230 io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
1231 io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
1232
1233 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1234 }
1235
TEST_F(AidlTest,HandleManualIdAssignments)1236 TEST_F(AidlTest, HandleManualIdAssignments) {
1237 Options options = Options::From("aidl --checkapi old new");
1238 io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
1239 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
1240
1241 EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1242
1243 io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
1244 EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1245 }
1246
TEST_F(AidlTest,ParcelFileDescriptorIsBuiltinType)1247 TEST_F(AidlTest, ParcelFileDescriptorIsBuiltinType) {
1248 Options javaOptions = Options::From("aidl --lang=java -o out p/IFoo.aidl");
1249 Options cppOptions = Options::From("aidl --lang=cpp -h out -o out p/IFoo.aidl");
1250
1251 // use without import
1252 io_delegate_.SetFileContents("p/IFoo.aidl",
1253 "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
1254 EXPECT_EQ(0, ::android::aidl::compile_aidl(javaOptions, io_delegate_));
1255 EXPECT_EQ(0, ::android::aidl::compile_aidl(cppOptions, io_delegate_));
1256
1257 // use without impot but with full name
1258 io_delegate_.SetFileContents(
1259 "p/IFoo.aidl",
1260 "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
1261 EXPECT_EQ(0, ::android::aidl::compile_aidl(javaOptions, io_delegate_));
1262 EXPECT_EQ(0, ::android::aidl::compile_aidl(cppOptions, io_delegate_));
1263
1264 // use with import (as before)
1265 io_delegate_.SetFileContents("p/IFoo.aidl",
1266 "package p;"
1267 "import android.os.ParcelFileDescriptor;"
1268 "interface IFoo{"
1269 " void foo(in ParcelFileDescriptor fd);"
1270 "}");
1271 EXPECT_EQ(0, ::android::aidl::compile_aidl(javaOptions, io_delegate_));
1272 EXPECT_EQ(0, ::android::aidl::compile_aidl(cppOptions, io_delegate_));
1273 }
1274
TEST_F(AidlTest,ManualIds)1275 TEST_F(AidlTest, ManualIds) {
1276 Options options = Options::From("aidl --lang=java -o out IFoo.aidl");
1277 io_delegate_.SetFileContents("IFoo.aidl",
1278 "interface IFoo {\n"
1279 " void foo() = 0;\n"
1280 " void bar() = 1;\n"
1281 "}");
1282 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1283 }
1284
TEST_F(AidlTest,ManualIdsWithMetaTransactions)1285 TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
1286 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
1287 io_delegate_.SetFileContents("IFoo.aidl",
1288 "interface IFoo {\n"
1289 " void foo() = 0;\n"
1290 " void bar() = 1;\n"
1291 "}");
1292 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1293 }
1294
TEST_F(AidlTest,FailOnDuplicatedIds)1295 TEST_F(AidlTest, FailOnDuplicatedIds) {
1296 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
1297 io_delegate_.SetFileContents("IFoo.aidl",
1298 "interface IFoo {\n"
1299 " void foo() = 3;\n"
1300 " void bar() = 3;\n"
1301 "}");
1302 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1303 }
1304
TEST_F(AidlTest,FailOnOutOfRangeIds)1305 TEST_F(AidlTest, FailOnOutOfRangeIds) {
1306 // 16777115 is kLastMetaMethodId + 1
1307 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
1308 io_delegate_.SetFileContents("IFoo.aidl",
1309 "interface IFoo {\n"
1310 " void foo() = 3;\n"
1311 " void bar() = 16777115;\n"
1312 "}");
1313 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1314 }
1315
TEST_F(AidlTest,FailOnPartiallyAssignedIds)1316 TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
1317 Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
1318 io_delegate_.SetFileContents("IFoo.aidl",
1319 "interface IFoo {\n"
1320 " void foo() = 3;\n"
1321 " void bar();\n"
1322 "}");
1323 EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1324 }
1325
1326 class AidlOutputPathTest : public AidlTest {
1327 protected:
SetUp()1328 void SetUp() override {
1329 AidlTest::SetUp();
1330 io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
1331 }
1332
Test(const Options & options,const std::string expected_output_path)1333 void Test(const Options& options, const std::string expected_output_path) {
1334 EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1335 // check the existence
1336 EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
1337 }
1338 };
1339
TEST_F(AidlOutputPathTest,OutDirWithNoOutputFile)1340 TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
1341 // <out_dir> / <package_name> / <type_name>.java
1342 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
1343 }
1344
TEST_F(AidlOutputPathTest,OutDirWithOutputFile)1345 TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
1346 // when output file is explicitly set, it is always respected. -o option is
1347 // ignored.
1348 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
1349 }
1350
TEST_F(AidlOutputPathTest,NoOutDirWithOutputFile)1351 TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
1352 Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
1353 }
1354
TEST_F(AidlOutputPathTest,NoOutDirWithNoOutputFile)1355 TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
1356 // output is the same as the input file except for the suffix
1357 Test(Options::From("aidl sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
1358 }
1359
1360 } // namespace aidl
1361 } // namespace android
1362