1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H
16 #define GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #ifdef GPR_SUPPORT_BINDER_TRANSPORT
21 
22 #include "src/core/ext/transport/binder/utils/ndk_binder.h"
23 
24 namespace grpc_binder {
25 namespace ndk_util {
26 
27 ///
28 /// Represents one strong pointer to an AIBinder object.
29 /// Copied from binder/ndk/include_cpp/android/binder_auto_utils.h
30 ///
31 class SpAIBinder {
32  public:
SpAIBinder()33   SpAIBinder() : mBinder(nullptr) {}
SpAIBinder(AIBinder * binder)34   explicit SpAIBinder(AIBinder* binder) : mBinder(binder) {}
SpAIBinder(std::nullptr_t)35   SpAIBinder(std::nullptr_t)
36       : SpAIBinder() {}  // NOLINT(google-explicit-constructor)
SpAIBinder(const SpAIBinder & other)37   SpAIBinder(const SpAIBinder& other) { *this = other; }
38 
~SpAIBinder()39   ~SpAIBinder() { set(nullptr); }
40   SpAIBinder& operator=(const SpAIBinder& other) {
41     if (this == &other) {
42       return *this;
43     }
44     AIBinder_incStrong(other.mBinder);
45     set(other.mBinder);
46     return *this;
47   }
48 
set(AIBinder * binder)49   void set(AIBinder* binder) {
50     AIBinder* old = *const_cast<AIBinder* volatile*>(&mBinder);
51     if (old != nullptr) AIBinder_decStrong(old);
52     if (old != *const_cast<AIBinder* volatile*>(&mBinder)) {
53       __assert(__FILE__, __LINE__, "Race detected.");
54     }
55     mBinder = binder;
56   }
57 
get()58   AIBinder* get() const { return mBinder; }
getR()59   AIBinder** getR() { return &mBinder; }
60 
61   bool operator!=(const SpAIBinder& rhs) const { return get() != rhs.get(); }
62   bool operator<(const SpAIBinder& rhs) const { return get() < rhs.get(); }
63   bool operator<=(const SpAIBinder& rhs) const { return get() <= rhs.get(); }
64   bool operator==(const SpAIBinder& rhs) const { return get() == rhs.get(); }
65   bool operator>(const SpAIBinder& rhs) const { return get() > rhs.get(); }
66   bool operator>=(const SpAIBinder& rhs) const { return get() >= rhs.get(); }
67 
68  private:
69   AIBinder* mBinder = nullptr;
70 };
71 }  // namespace ndk_util
72 }  // namespace grpc_binder
73 
74 #endif
75 
76 #endif  // GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H
77