1dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley/*
2dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * Copyright (C) 2016 The Android Open Source Project
3dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley *
4dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * Licensed under the Apache License, Version 2.0 (the "License");
5dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * you may not use this file except in compliance with the License.
6dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * You may obtain a copy of the License at
7dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley *
8dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley *      http://www.apache.org/licenses/LICENSE-2.0
9dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley *
10dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * Unless required by applicable law or agreed to in writing, software
11dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * distributed under the License is distributed on an "AS IS" BASIS,
12dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * See the License for the specific language governing permissions and
14dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley * limitations under the License.
15dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley */
16dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
17dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include "aidl_test_client_utf8_strings.h"
18dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
19dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include <android-base/logging.h>
20dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include <binder/Status.h>
21dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include <utils/StrongPointer.h>
22dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
23dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include <memory>
24dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include <string>
25dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include <vector>
26dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
27dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include "android/aidl/tests/ITestService.h"
28dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley#include "test_helpers.h"
29dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
30dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley// libutils:
31dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileyusing android::sp;
32dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
33dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley// libbinder:
34dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileyusing android::binder::Status;
35dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
36dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley// generated
37dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileyusing android::aidl::tests::ITestService;
38dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
39dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileyusing std::unique_ptr;
40dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileyusing std::string;
41dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileyusing std::vector;
42dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
43dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileynamespace android {
44dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileynamespace aidl {
45dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileynamespace tests {
46dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileynamespace client {
47dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
48dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileybool ConfirmUtf8InCppStringRepeat(const sp<ITestService>& s) {
49dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  const vector<string> utf8_inputs = {
50dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    string("Deliver us from evil."),
51dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    string(),
52dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    string("\0\0", 2),
53dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    // Similarly, the utf8 encodings of the small letter yee and euro sign.
54dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    string("\xF0\x90\x90\xB7\xE2\x82\xAC"),
55dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  };
56dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  LOG(INFO) << "Confirming repeating utf8 strings works.";
57dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
58dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  for (const auto& input : utf8_inputs) {
59dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    string reply;
60dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    Status status = s->RepeatUtf8CppString(input, &reply);
61dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    if (!status.isOk() || input != reply) {
62dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      LOG(ERROR) << "Failed while requesting service to repeat utf8 string=\""
63dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                 << input
64dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                 << "\". Got status=" << status.toString8()
65dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                 << " and output=" << reply;
66dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      return false;
67dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    }
68dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  }
69dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
70dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  unique_ptr<string> ret;
71dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  Status repeat_null_status = s->RepeatNullableUtf8CppString(nullptr, &ret);
72dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  if (!repeat_null_status.isOk() || ret) {
73dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    LOG(ERROR) << "RepeatNullableUtf8CppString(null) did not return null";
74dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    return false;
75dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  }
76dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
77dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  for (const auto& input : utf8_inputs) {
78dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    unique_ptr<string> reply;
79dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    Status status = s->RepeatNullableUtf8CppString(
80dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley        unique_ptr<string>(new string(input)), &reply);
81dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    if (!status.isOk()) {
82dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      LOG(ERROR) << "Got status=" << status.toString8() << " while repeating "
83dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                    "nullable utf8 string " << input;
84dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      return false;
85dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    }
86dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    if (!reply) {
87dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      LOG(ERROR) << "Got null reply while repeating nullable utf8 string "
88dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                 << input;
89dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      return false;
90dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    }
91dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    if (input != *reply) {
92dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      LOG(ERROR) << "Failed while requesting service to repeat utf8 string=\""
93dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                 << input
94dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                 << "\". Got status=" << status.toString8()
95dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                 << " and output=" << *reply;
96dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley      return false;
97dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    }
98dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  }
99dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
100dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  return true;
101dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley}
102dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
103dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wileybool ConfirmUtf8InCppStringArrayReverse(const sp<ITestService>& s) {
104dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  LOG(INFO) << "Confirming passing and returning utf8 string arrays works.";
105dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  if (!ReverseArray(s, &ITestService::ReverseUtf8CppString,
106dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley                    {string{"a"}, string{}, string{"\xc3\xb8"}})) {
107dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley    return false;
108dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  }
109dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
110dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley  return true;
111dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley}
112dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley
11399d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wileybool ConfirmUtf8InCppStringListReverse(const sp<ITestService>& s) {
11499d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  LOG(INFO) << "Confirming reversing a list of utf8 strings works";
11599d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  unique_ptr<vector<unique_ptr<string>>> input, reversed, repeated;
11699d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  Status status = s->ReverseUtf8CppStringList(input, &reversed, &repeated);
11799d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  if (!status.isOk() || reversed || repeated) {
11899d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    LOG(ERROR) << "Reversing null list of utf8 strings failed.";
11999d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    return false;
12099d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  }
12199d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley
12299d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  input.reset(new vector<unique_ptr<string>>);
12399d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  input->emplace_back(new string("Deliver us from evil."));
12499d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  input->emplace_back(nullptr);
12599d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  input->emplace_back(new string("\xF0\x90\x90\xB7\xE2\x82\xAC"));
12699d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley
12799d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  status = s->ReverseUtf8CppStringList(input, &repeated, &reversed);
12899d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  if (!status.isOk() || !reversed || !repeated) {
12999d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    LOG(ERROR) << "Reversing list of utf8 strings failed.";
13099d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    return false;
13199d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  }
13299d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  if (reversed->size() != input->size() || repeated->size() != input->size()) {
13399d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    LOG(ERROR) << "Bad output sizes.";
13499d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    return false;
13599d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  }
13699d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley
13799d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  for (size_t i = 0; i < input->size(); ++i) {
13899d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    const string* input_str = (*input)[i].get();
13999d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    const string* repeated_str = (*repeated)[i].get();
14099d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    const string* reversed_str = (*reversed)[(reversed->size() - 1) - i].get();
14199d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    if (!input_str) {
14299d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      if(repeated_str || reversed_str) {
14399d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley        LOG(ERROR) << "Expected null values, but got non-null.";
14499d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley        return false;
14599d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      }
14699d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      // 3 nullptrs to strings.  No need to compare values.
14799d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      continue;
14899d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    }
14999d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    if (!repeated_str || !reversed_str) {
15099d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      LOG(ERROR) << "Expected non-null values, but got null.";
15199d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      return false;
15299d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    }
15399d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    if (*input_str != *repeated_str || *input_str != *reversed_str) {
15499d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      LOG(ERROR) << "Expected '" << *input_str << "' but got "
15599d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley                 << "repeated='" << *repeated_str << "' and "
15699d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley                 << "reversed='" << *reversed_str;
15799d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley      return false;
15899d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley    }
15999d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  }
16099d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley  return true;
16199d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley}
16299d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley
16399d699bef10f2455931fdd46861a25742a8fd7eaChristopher Wiley
164dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley}  // namespace client
165dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley}  // namespace tests
166dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley}  // namespace aidl
167dca2ecf2883771b4c895e52a9f07e2467d603f77Christopher Wiley}  // namespace android
168