Add support for @nullable annotation

Using this annotation will now cause C++ types to be wrapped in
unique_ptr, and by extension be capable of handling null values.

Support extends to all arrays, Strings, Lists, and Parcelables.

Change-Id: I148a3666279c2badcba097b8925e55f8fcecb9c2
Test: Unit tests pass
Bug: 25969194
Signed-off-by: Casey Dahlin <sadmac@google.com>
diff --git a/tests/aidl_test_service.cpp b/tests/aidl_test_service.cpp
index d68842b..66ab2a6 100644
--- a/tests/aidl_test_service.cpp
+++ b/tests/aidl_test_service.cpp
@@ -66,6 +66,7 @@
 
 // Standard library
 using std::map;
+using std::unique_ptr;
 using std::vector;
 
 namespace android {
@@ -202,6 +203,19 @@
     return Status::ok();
   }
 
+  template<typename T>
+  Status RepeatNullable(const unique_ptr<T>& input,
+                        unique_ptr<T>* _aidl_return) {
+    ALOGI("Repeating nullable value");
+
+    _aidl_return->reset();
+    if (input) {
+      _aidl_return->reset(new T(*input));
+    }
+
+    return Status::ok();
+  }
+
   Status ReverseBoolean(const vector<bool>& input,
                         vector<bool>* repeated,
                         vector<bool>* _aidl_return) override {
@@ -306,6 +320,43 @@
     return Status::fromServiceSpecificError(code);
   }
 
+  Status RepeatNullableIntArray(const unique_ptr<vector<int32_t>>& input,
+                                unique_ptr<vector<int32_t>>* _aidl_return) {
+    return RepeatNullable(input, _aidl_return);
+  }
+
+  Status RepeatNullableStringList(
+             const unique_ptr<vector<unique_ptr<String16>>>& input,
+             unique_ptr<vector<unique_ptr<String16>>>* _aidl_return) {
+    ALOGI("Repeating nullable string list");
+    if (!input) {
+      _aidl_return->reset();
+      return Status::ok();
+    }
+
+    _aidl_return->reset(new vector<unique_ptr<String16>>);
+
+    for (const auto& item : *input) {
+      if (!item) {
+        (*_aidl_return)->emplace_back(nullptr);
+      } else {
+        (*_aidl_return)->emplace_back(new String16(*item));
+      }
+    }
+
+    return Status::ok();
+  }
+
+  Status RepeatNullableString(const unique_ptr<String16>& input,
+                              unique_ptr<String16>* _aidl_return) {
+    return RepeatNullable(input, _aidl_return);
+  }
+
+  Status RepeatNullableParcelable(const unique_ptr<SimpleParcelable>& input,
+                              unique_ptr<SimpleParcelable>* _aidl_return) {
+    return RepeatNullable(input, _aidl_return);
+  }
+
  private:
   map<String16, sp<INamedCallback>> service_map_;
 };