1 /* 2 * Copyright (C) 2018 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 #pragma once 18 19 #include <android/binder_auto_utils.h> 20 #include <android/binder_ibinder.h> 21 #include <gtest/gtest.h> 22 #include <nativetesthelper_jni/utils.h> 23 24 #include <functional> 25 26 // Helpers for testing 27 28 template <typename T> 29 static inline ::testing::AssertionResult isOk(T) = delete; 30 31 template <> 32 inline ::testing::AssertionResult isOk(::ndk::ScopedAStatus t) { 33 if (AStatus_isOk(t.get())) { 34 return ::testing::AssertionSuccess(); 35 } else { 36 return ::testing::AssertionFailure() 37 << "exception: " << AStatus_getExceptionCode(t.get()) 38 << " service specific: " << AStatus_getServiceSpecificError(t.get()) 39 << " status: " << AStatus_getStatus(t.get()); 40 } 41 } 42 43 template <> 44 inline ::testing::AssertionResult isOk(binder_status_t t) { 45 if (t == STATUS_OK) { 46 return ::testing::AssertionSuccess(); 47 } 48 return ::testing::AssertionFailure() << "Status: " << t; 49 } 50 51 #define EXPECT_OK(THING) EXPECT_TRUE(isOk(THING)) 52 #define ASSERT_OK(THING) ASSERT_TRUE(isOk(THING)) 53 54 // placeholder 55 constexpr transaction_code_t kCode = +1 + 918; 56 57 // Usually, things at this level would be generated by the aidl compiler. This 58 // class is merely to make testing the API easier. 59 60 struct SampleData; 61 62 typedef std::function<void(SampleData*)> OnDestroyFunc; 63 typedef std::function<binder_status_t(transaction_code_t code, 64 const AParcel* in, AParcel* out)> 65 OnTransactFunc; 66 67 typedef std::function<binder_status_t(AParcel*)> WriteParcel; 68 typedef std::function<binder_status_t(const AParcel*)> ReadParcel; 69 70 static inline binder_status_t WriteNothingToParcel(AParcel*) { 71 return STATUS_OK; 72 } 73 static inline binder_status_t ReadNothingFromParcel(const AParcel*) { 74 return STATUS_OK; 75 } 76 77 // There is an assert instances of this class are destroyed in NdkBinderTest 78 struct ThisShouldBeDestroyed { 79 static size_t numInstances(); 80 81 ThisShouldBeDestroyed(); 82 virtual ~ThisShouldBeDestroyed(); 83 }; 84 85 struct SampleData : ThisShouldBeDestroyed { 86 static const char* kDescriptor; 87 static const AIBinder_Class* kClass; 88 89 static const char* kAnotherDescriptor; 90 static const AIBinder_Class* kAnotherClass; 91 92 SampleData(const OnTransactFunc& oT = nullptr, 93 const OnDestroyFunc& oD = nullptr) 94 : onTransact(oT), onDestroy(oD) {} 95 96 // This is called when the class is transacted on if non-null. 97 // Otherwise, STATUS_FAILED_TRANSACTION is returned. 98 OnTransactFunc onTransact; 99 100 // This is called when the class is destroyed if non-null. 101 OnDestroyFunc onDestroy; 102 103 // Automatically updated by this class whenever a transaction is received. 104 int numberTransactions = 0; 105 106 __attribute__((warn_unused_result)) static AIBinder* newBinder( 107 OnTransactFunc onTransact = nullptr, OnDestroyFunc onDestroy = nullptr) { 108 SampleData* data = new SampleData(onTransact, onDestroy); 109 return AIBinder_new(kClass, static_cast<void*>(data)); 110 }; 111 112 // Helper method to simplify transaction logic 113 static binder_status_t transact(AIBinder* binder, transaction_code_t code, 114 WriteParcel writeFunc = WriteNothingToParcel, 115 ReadParcel readFunc = ReadNothingFromParcel, 116 binder_flags_t flags = 0) { 117 AParcel* in; 118 binder_status_t status = AIBinder_prepareTransaction(binder, &in); 119 if (status != STATUS_OK) return status; 120 121 status = writeFunc(in); 122 if (status != STATUS_OK) { 123 AParcel_delete(in); 124 return status; 125 } 126 127 AParcel* out; 128 status = AIBinder_transact(binder, code, &in, &out, flags); 129 if (status != STATUS_OK) return status; 130 131 status = readFunc(out); 132 AParcel_delete(out); 133 134 return status; 135 } 136 }; 137 138 static inline OnDestroyFunc ExpectLifetimeTransactions(size_t count) { 139 return [count](SampleData* data) { 140 EXPECT_EQ(count, data->numberTransactions) 141 << "Expected " << count 142 << " transaction(s), but over the lifetime of this object, it received " 143 << data->numberTransactions; 144 }; 145 } 146 147 static inline OnTransactFunc TransactionsReturn(binder_status_t result) { 148 return 149 [result](transaction_code_t, const AParcel*, AParcel*) { return result; }; 150 } 151 152 class NdkBinderTest : public ::testing::Test { 153 public: 154 void SetUp() override { instances = ThisShouldBeDestroyed::numInstances(); } 155 void TearDown() override { 156 EXPECT_EQ(instances, ThisShouldBeDestroyed::numInstances()); 157 } 158 159 private: 160 size_t instances = 0; 161 }; 162 163 JNIEnv* GetEnv(); 164