blob: d947e7b6eece2ec5b7dfc5cc0184e5cd32434a05 [file] [log] [blame]
Steven Moreland2648d202018-08-28 01:23:02 -07001/*
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/**
18 * @addtogroup NdkBinder
19 * @{
20 */
21
22/**
23 * @file binder_auto_utils.h
24 * @brief These objects provide a more C++-like thin interface to the .
25 */
26
27#pragma once
28
29#include <android/binder_ibinder.h>
30#include <android/binder_parcel.h>
31#include <android/binder_status.h>
32
33#ifdef __cplusplus
34
35#include <cstddef>
36
Steven Moreland8b4f48a2018-10-08 14:30:42 -070037namespace ndk {
Steven Moreland2648d202018-08-28 01:23:02 -070038
39/**
40 * Represents one strong pointer to an AIBinder object.
41 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070042class SpAIBinder {
Steven Moreland2648d202018-08-28 01:23:02 -070043public:
44 /**
45 * Takes ownership of one strong refcount of binder.
46 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070047 explicit SpAIBinder(AIBinder* binder = nullptr) : mBinder(binder) {}
Steven Moreland2648d202018-08-28 01:23:02 -070048
49 /**
Steven Moreland8b4f48a2018-10-08 14:30:42 -070050 * Convenience operator for implicitly constructing an SpAIBinder from nullptr. This is not
Steven Moreland2648d202018-08-28 01:23:02 -070051 * explicit because it is not taking ownership of anything.
52 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070053 SpAIBinder(std::nullptr_t) : SpAIBinder() {}
Steven Moreland2648d202018-08-28 01:23:02 -070054
55 /**
56 * This will delete the underlying object if it exists. See operator=.
57 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070058 SpAIBinder(const SpAIBinder& other) { *this = other; }
Steven Moreland2648d202018-08-28 01:23:02 -070059
60 /**
61 * This deletes the underlying object if it exists. See set.
62 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070063 ~SpAIBinder() { set(nullptr); }
Steven Moreland2648d202018-08-28 01:23:02 -070064
65 /**
66 * This takes ownership of a binder from another AIBinder object but it does not affect the
67 * ownership of that other object.
68 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070069 SpAIBinder& operator=(const SpAIBinder& other) {
Steven Moreland2648d202018-08-28 01:23:02 -070070 AIBinder_incStrong(other.mBinder);
71 set(other.mBinder);
72 return *this;
73 }
74
75 /**
76 * Takes ownership of one strong refcount of binder
77 */
78 void set(AIBinder* binder) {
79 if (mBinder != nullptr) AIBinder_decStrong(mBinder);
80 mBinder = binder;
81 }
82
83 /**
84 * This returns the underlying binder object for transactions. If it is used to create another
Steven Moreland8b4f48a2018-10-08 14:30:42 -070085 * SpAIBinder object, it should first be incremented.
Steven Moreland2648d202018-08-28 01:23:02 -070086 */
87 AIBinder* get() const { return mBinder; }
88
89 /**
90 * This allows the value in this class to be set from beneath it. If you call this method and
91 * then change the value of T*, you must take ownership of the value you are replacing and add
92 * ownership to the object that is put in here.
93 *
94 * Recommended use is like this:
Steven Moreland8b4f48a2018-10-08 14:30:42 -070095 * SpAIBinder a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -070096 * SomeInitFunction(a.getR()); // value is initialized with refcount
97 *
98 * Other usecases are discouraged.
99 *
100 */
101 AIBinder** getR() { return &mBinder; }
102
103private:
104 AIBinder* mBinder = nullptr;
105};
106
107/**
108 * This baseclass owns a single object, used to make various classes RAII.
109 */
110template <typename T, void (*Destroy)(T*)>
Steven Moreland1630c192018-10-09 11:54:52 -0700111class ScopedAResource {
Steven Moreland2648d202018-08-28 01:23:02 -0700112public:
113 /**
114 * Takes ownership of t.
115 */
Steven Moreland1630c192018-10-09 11:54:52 -0700116 explicit ScopedAResource(T* t = nullptr) : mT(t) {}
Steven Moreland2648d202018-08-28 01:23:02 -0700117
118 /**
119 * This deletes the underlying object if it exists. See set.
120 */
Steven Moreland1630c192018-10-09 11:54:52 -0700121 ~ScopedAResource() { set(nullptr); }
Steven Moreland2648d202018-08-28 01:23:02 -0700122
123 /**
124 * Takes ownership of t.
125 */
126 void set(T* t) {
127 Destroy(mT);
128 mT = t;
129 }
130
131 /**
132 * This returns the underlying object to be modified but does not affect ownership.
133 */
134 T* get() { return mT; }
135
136 /**
137 * This returns the const underlying object but does not affect ownership.
138 */
139 const T* get() const { return mT; }
140
141 /**
142 * This allows the value in this class to be set from beneath it. If you call this method and
143 * then change the value of T*, you must take ownership of the value you are replacing and add
144 * ownership to the object that is put in here.
145 *
146 * Recommended use is like this:
Steven Moreland1630c192018-10-09 11:54:52 -0700147 * ScopedAResource<T> a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -0700148 * SomeInitFunction(a.getR()); // value is initialized with refcount
149 *
150 * Other usecases are discouraged.
151 *
152 */
153 T** getR() { return &mT; }
154
155 // copy-constructing, or move/copy assignment is disallowed
Steven Moreland1630c192018-10-09 11:54:52 -0700156 ScopedAResource(const ScopedAResource&) = delete;
157 ScopedAResource& operator=(const ScopedAResource&) = delete;
158 ScopedAResource& operator=(ScopedAResource&&) = delete;
Steven Moreland2648d202018-08-28 01:23:02 -0700159
160 // move-constructing is okay
Steven Moreland1630c192018-10-09 11:54:52 -0700161 ScopedAResource(ScopedAResource&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700162
163private:
164 T* mT;
165};
166
167/**
168 * Convenience wrapper. See AParcel.
169 */
Steven Moreland1630c192018-10-09 11:54:52 -0700170class ScopedAParcel : public ScopedAResource<AParcel, AParcel_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700171public:
172 /**
173 * Takes ownership of a.
174 */
Steven Moreland1630c192018-10-09 11:54:52 -0700175 explicit ScopedAParcel(AParcel* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700176 ~ScopedAParcel() {}
177 ScopedAParcel(ScopedAParcel&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700178};
179
180/**
181 * Convenience wrapper. See AStatus.
182 */
Steven Moreland1630c192018-10-09 11:54:52 -0700183class ScopedAStatus : public ScopedAResource<AStatus, AStatus_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700184public:
185 /**
186 * Takes ownership of a.
187 */
Steven Moreland1630c192018-10-09 11:54:52 -0700188 explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700189 ~ScopedAStatus() {}
190 ScopedAStatus(ScopedAStatus&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700191
192 /**
193 * See AStatus_isOk.
194 */
195 bool isOk() { return get() != nullptr && AStatus_isOk(get()); }
196};
197
198/**
199 * Convenience wrapper. See AIBinder_DeathRecipient.
200 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700201class ScopedAIBinder_DeathRecipient
Steven Moreland1630c192018-10-09 11:54:52 -0700202 : public ScopedAResource<AIBinder_DeathRecipient, AIBinder_DeathRecipient_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700203public:
204 /**
205 * Takes ownership of a.
206 */
Steven Moreland1630c192018-10-09 11:54:52 -0700207 explicit ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient* a = nullptr)
208 : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700209 ~ScopedAIBinder_DeathRecipient() {}
210 ScopedAIBinder_DeathRecipient(ScopedAIBinder_DeathRecipient&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700211};
212
213/**
214 * Convenience wrapper. See AIBinder_Weak.
215 */
Steven Moreland1630c192018-10-09 11:54:52 -0700216class ScopedAIBinder_Weak : public ScopedAResource<AIBinder_Weak, AIBinder_Weak_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700217public:
218 /**
219 * Takes ownership of a.
220 */
Steven Moreland1630c192018-10-09 11:54:52 -0700221 explicit ScopedAIBinder_Weak(AIBinder_Weak* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700222 ~ScopedAIBinder_Weak() {}
223 ScopedAIBinder_Weak(ScopedAIBinder_Weak&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700224
225 /**
226 * See AIBinder_Weak_promote.
227 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700228 SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); }
Steven Moreland2648d202018-08-28 01:23:02 -0700229};
230
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700231} // namespace ndk
Steven Moreland2648d202018-08-28 01:23:02 -0700232
233#endif // __cplusplus
234
235/** @} */