Home | History | Annotate | Download | only in libbinder_ndk_test
      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