From cd8c135d8f4840e628afbb8c83546d94926ef537 Mon Sep 17 00:00:00 2001 From: Robert Quattlebaum Date: Wed, 4 Jan 2017 13:42:51 -0800 Subject: aidl-cpp: Add support for type Map Change-Id: I37e0d4778383277e02c9d8f0601e868514fb7989 --- docs/aidl-cpp.md | 7 +---- generate_java_binder.cpp | 2 ++ tests/aidl_test_client_primitives.cpp | 10 +++++++ tests/aidl_test_service.cpp | 11 ++++++++ tests/android/aidl/tests/ITestService.aidl | 1 + .../src/android/aidl/tests/TestServiceClient.java | 13 +++++++++ tests/test_helpers.h | 6 ++-- type_cpp.cpp | 32 ++++++++++++++++++++++ 8 files changed, 73 insertions(+), 9 deletions(-) diff --git a/docs/aidl-cpp.md b/docs/aidl-cpp.md index 65cc8e4..156b697 100644 --- a/docs/aidl-cpp.md +++ b/docs/aidl-cpp.md @@ -91,6 +91,7 @@ interfaces. | String | String16 | in | Supports null references. | | @utf8InCpp String | std::string | in | @utf8InCpp causes UTF16 to UTF8 conversion in C++. | | android.os.Parcelable | android::Parcelable | inout | | +| java.util.Map | android::binder::Map| inout | `std::map` | | T extends IBinder | sp | in | | | Arrays (T[]) | vector | inout | May contain only primitives, Strings and parcelables. | | List | vector | inout | | @@ -98,12 +99,6 @@ interfaces. | List | vector> | inout | | | FileDescriptor | unique_fd | inout | android-base/unique_fd.h from libbase | -Note that java.util.Map and java.utils.List are not good candidates for cross -language communication because they may contain arbitrary types on the Java -side. For instance, Map is cast to Map and then the object -values dynamically inspected and serialized as type/value pairs. Support -exists for sending arbitrary Java serializables, Android Bundles, etc. - Note that annotations may be placed at the interface level, as well as on a type by type basis. Interface level annotations will be applied opportunistically and be overridden by per type annotations. For instance, an diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp index 02a6922..2d2ba68 100644 --- a/generate_java_binder.cpp +++ b/generate_java_binder.cpp @@ -332,6 +332,8 @@ static void generate_method(const AidlMethod& method, Class* interface, realCall->arguments.push_back(v); } + cl = NULL; + // the real call Variable* _result = NULL; if (method.GetType().GetName() == "void") { diff --git a/tests/aidl_test_client_primitives.cpp b/tests/aidl_test_client_primitives.cpp index 6f70f43..528d3ba 100644 --- a/tests/aidl_test_client_primitives.cpp +++ b/tests/aidl_test_client_primitives.cpp @@ -21,6 +21,8 @@ #include #include +#include +#include #include "android/aidl/tests/INamedCallback.h" @@ -33,6 +35,8 @@ using android::String8; // libbinder: using android::binder::Status; +using android::binder::Value; +using android::binder::Map; // generated using android::aidl::tests::ITestService; @@ -51,6 +55,11 @@ namespace client { bool ConfirmPrimitiveRepeat(const sp& s) { cout << "Confirming passing and returning primitives works." << endl; + Map test_map; + test_map["first_val"] = int8_t{-128}; + test_map["second_val"] = int32_t{1 << 30}; + test_map["third_val"] = String16("OHAI"); + if (!RepeatPrimitive(s, &ITestService::RepeatBoolean, true) || !RepeatPrimitive(s, &ITestService::RepeatByte, int8_t{-128}) || !RepeatPrimitive(s, &ITestService::RepeatChar, char16_t{'A'}) || @@ -58,6 +67,7 @@ bool ConfirmPrimitiveRepeat(const sp& s) { !RepeatPrimitive(s, &ITestService::RepeatLong, int64_t{1ll << 60}) || !RepeatPrimitive(s, &ITestService::RepeatFloat, float{1.0f/3.0f}) || !RepeatPrimitive(s, &ITestService::RepeatDouble, double{1.0/3.0}) || + !RepeatPrimitive(s, &ITestService::RepeatMap, test_map) || !RepeatPrimitive( s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT) || !RepeatPrimitive( diff --git a/tests/aidl_test_service.cpp b/tests/aidl_test_service.cpp index 9e2304e..abea6ae 100644 --- a/tests/aidl_test_service.cpp +++ b/tests/aidl_test_service.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,7 @@ using android::aidl::tests::BnTestService; using android::aidl::tests::INamedCallback; using android::aidl::tests::SimpleParcelable; using android::os::PersistableBundle; +using android::binder::Map; // Standard library using std::map; @@ -117,6 +119,10 @@ class NativeService : public BnTestService { ALOGI("Repeating token %s", token_str.str().c_str()); } + void LogRepeatedMapToken(const Map& token) { + ALOGI("Repeating Map with %d elements", (int)token.size()); + } + Status RepeatBoolean(bool token, bool* _aidl_return) override { LogRepeatedToken(token ? 1 : 0); *_aidl_return = token; @@ -157,6 +163,11 @@ class NativeService : public BnTestService { *_aidl_return = token; return Status::ok(); } + Status RepeatMap(const Map& token, Map* _aidl_return) override { + LogRepeatedMapToken(token); + *_aidl_return = token; + return Status::ok(); + } Status RepeatSimpleParcelable(const SimpleParcelable& input, SimpleParcelable* repeat, diff --git a/tests/android/aidl/tests/ITestService.aidl b/tests/android/aidl/tests/ITestService.aidl index 4de6925..91b13b4 100644 --- a/tests/android/aidl/tests/ITestService.aidl +++ b/tests/android/aidl/tests/ITestService.aidl @@ -47,6 +47,7 @@ interface ITestService { float RepeatFloat(float token); double RepeatDouble(double token); String RepeatString(String token); + Map RepeatMap(in Map token); SimpleParcelable RepeatSimpleParcelable(in SimpleParcelable input, out SimpleParcelable repeat); diff --git a/tests/java_app/src/android/aidl/tests/TestServiceClient.java b/tests/java_app/src/android/aidl/tests/TestServiceClient.java index 4af4aa0..4f4d462 100644 --- a/tests/java_app/src/android/aidl/tests/TestServiceClient.java +++ b/tests/java_app/src/android/aidl/tests/TestServiceClient.java @@ -38,6 +38,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.HashMap; // Generated import android.aidl.tests.INamedCallback; @@ -154,6 +156,17 @@ public class TestServiceClient extends Activity { " responded " + response); } } + { + Map query = new HashMap(); + query.put("first_val", new Byte((byte)-128)); + query.put("second_val", new Integer(1<<30)); + query.put("third_val", "OHAI"); + Object response = service.RepeatMap(query); + if (!query.equals(response)) { + mLog.logAndThrow("Repeat with " + query + + " responded " + response); + } + } List queries = Arrays.asList( "not empty", "", "\0", diff --git a/tests/test_helpers.h b/tests/test_helpers.h index 7d5145b..b4f0084 100644 --- a/tests/test_helpers.h +++ b/tests/test_helpers.h @@ -28,12 +28,12 @@ namespace aidl { namespace tests { namespace client { -template +template bool RepeatPrimitive( const android::sp& service, - android::binder::Status(android::aidl::tests::ITestService::*func)(T, T*), + android::binder::Status(android::aidl::tests::ITestService::*func)(T, V*), U input) { - T reply; + V reply; android::binder::Status status = (*service.*func)(input, &reply); if (!status.isOk() || input != reply) { LOG(ERROR) << "Failed to repeat primitive. status=" << status.toString8() diff --git a/type_cpp.cpp b/type_cpp.cpp index e20f603..2ac1523 100644 --- a/type_cpp.cpp +++ b/type_cpp.cpp @@ -265,6 +265,36 @@ class ParcelableType : public Type { } }; +class NullableMap : public Type { + public: + NullableMap() + : Type(ValidatableType::KIND_BUILT_IN, + "java.util", "Map", + {"binder/Map.h", "binder/Value.h"}, + "::std::unique_ptr<::android::binder::Map>", + "readNullableMap", "writeNullableMap") {} + virtual ~NullableMap() = default; + bool CanBeOutParameter() const override { return true; } +}; + + +class MapType : public Type { + public: + MapType() + : Type(ValidatableType::KIND_BUILT_IN, + "java.util", "Map", + {"binder/Map.h","binder/Value.h"}, + "::android::binder::Map", + "readMap", "writeMap", + kNoArrayType, + new NullableMap() ) {} + virtual ~MapType() = default; + bool CanBeOutParameter() const override { return true; } + + private: + DISALLOW_COPY_AND_ASSIGN(MapType); +}; // class MapType + class NullableStringListType : public Type { public: NullableStringListType() @@ -457,6 +487,8 @@ void TypeNamespace::Init() { kNoArrayType, nullable_ibinder); Add(ibinder_type_); + Add(new MapType()); + Add(new BinderListType()); Add(new StringListType()); Add(new Utf8InCppStringListType()); -- cgit v1.2.3