blob: e52a1d69ae5ced92293f78cde20f9e059db0fb27 [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
Steven Morelande97106a2018-10-08 17:53:48 -070033#include <assert.h>
Steven Moreland063f2362018-10-18 12:49:11 -070034#include <unistd.h>
Steven Morelande97106a2018-10-08 17:53:48 -070035
Steven Moreland2648d202018-08-28 01:23:02 -070036#ifdef __cplusplus
37
38#include <cstddef>
39
Steven Moreland8b4f48a2018-10-08 14:30:42 -070040namespace ndk {
Steven Moreland2648d202018-08-28 01:23:02 -070041
42/**
43 * Represents one strong pointer to an AIBinder object.
44 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070045class SpAIBinder {
Steven Moreland2648d202018-08-28 01:23:02 -070046public:
47 /**
48 * Takes ownership of one strong refcount of binder.
49 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070050 explicit SpAIBinder(AIBinder* binder = nullptr) : mBinder(binder) {}
Steven Moreland2648d202018-08-28 01:23:02 -070051
52 /**
Steven Moreland8b4f48a2018-10-08 14:30:42 -070053 * Convenience operator for implicitly constructing an SpAIBinder from nullptr. This is not
Steven Moreland2648d202018-08-28 01:23:02 -070054 * explicit because it is not taking ownership of anything.
55 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070056 SpAIBinder(std::nullptr_t) : SpAIBinder() {}
Steven Moreland2648d202018-08-28 01:23:02 -070057
58 /**
59 * This will delete the underlying object if it exists. See operator=.
60 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070061 SpAIBinder(const SpAIBinder& other) { *this = other; }
Steven Moreland2648d202018-08-28 01:23:02 -070062
63 /**
64 * This deletes the underlying object if it exists. See set.
65 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070066 ~SpAIBinder() { set(nullptr); }
Steven Moreland2648d202018-08-28 01:23:02 -070067
68 /**
69 * This takes ownership of a binder from another AIBinder object but it does not affect the
70 * ownership of that other object.
71 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070072 SpAIBinder& operator=(const SpAIBinder& other) {
Steven Moreland2648d202018-08-28 01:23:02 -070073 AIBinder_incStrong(other.mBinder);
74 set(other.mBinder);
75 return *this;
76 }
77
78 /**
79 * Takes ownership of one strong refcount of binder
80 */
81 void set(AIBinder* binder) {
Steven Morelande97106a2018-10-08 17:53:48 -070082 AIBinder* old = *const_cast<AIBinder* volatile*>(&mBinder);
83 if (old != nullptr) AIBinder_decStrong(old);
84 if (old != *const_cast<AIBinder* volatile*>(&mBinder)) {
85 __assert(__FILE__, __LINE__, "Race detected.");
86 }
Steven Moreland2648d202018-08-28 01:23:02 -070087 mBinder = binder;
88 }
89
90 /**
91 * This returns the underlying binder object for transactions. If it is used to create another
Steven Moreland8b4f48a2018-10-08 14:30:42 -070092 * SpAIBinder object, it should first be incremented.
Steven Moreland2648d202018-08-28 01:23:02 -070093 */
94 AIBinder* get() const { return mBinder; }
95
96 /**
97 * This allows the value in this class to be set from beneath it. If you call this method and
98 * then change the value of T*, you must take ownership of the value you are replacing and add
99 * ownership to the object that is put in here.
100 *
101 * Recommended use is like this:
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700102 * SpAIBinder a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -0700103 * SomeInitFunction(a.getR()); // value is initialized with refcount
104 *
105 * Other usecases are discouraged.
106 *
107 */
108 AIBinder** getR() { return &mBinder; }
109
110private:
111 AIBinder* mBinder = nullptr;
112};
113
114/**
115 * This baseclass owns a single object, used to make various classes RAII.
116 */
Steven Moreland063f2362018-10-18 12:49:11 -0700117template <typename T, typename R, R (*Destroy)(T), T DEFAULT>
Steven Moreland1630c192018-10-09 11:54:52 -0700118class ScopedAResource {
Steven Moreland2648d202018-08-28 01:23:02 -0700119public:
120 /**
121 * Takes ownership of t.
122 */
Steven Moreland063f2362018-10-18 12:49:11 -0700123 explicit ScopedAResource(T t = DEFAULT) : mT(t) {}
Steven Moreland2648d202018-08-28 01:23:02 -0700124
125 /**
126 * This deletes the underlying object if it exists. See set.
127 */
Steven Moreland063f2362018-10-18 12:49:11 -0700128 ~ScopedAResource() { set(DEFAULT); }
Steven Moreland2648d202018-08-28 01:23:02 -0700129
130 /**
131 * Takes ownership of t.
132 */
Steven Moreland063f2362018-10-18 12:49:11 -0700133 void set(T t) {
Steven Moreland2648d202018-08-28 01:23:02 -0700134 Destroy(mT);
135 mT = t;
136 }
137
138 /**
139 * This returns the underlying object to be modified but does not affect ownership.
140 */
Steven Moreland063f2362018-10-18 12:49:11 -0700141 T get() { return mT; }
Steven Moreland2648d202018-08-28 01:23:02 -0700142
143 /**
144 * This returns the const underlying object but does not affect ownership.
145 */
Steven Moreland063f2362018-10-18 12:49:11 -0700146 const T get() const { return mT; }
Steven Moreland2648d202018-08-28 01:23:02 -0700147
148 /**
149 * This allows the value in this class to be set from beneath it. If you call this method and
150 * then change the value of T*, you must take ownership of the value you are replacing and add
151 * ownership to the object that is put in here.
152 *
153 * Recommended use is like this:
Steven Moreland1630c192018-10-09 11:54:52 -0700154 * ScopedAResource<T> a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -0700155 * SomeInitFunction(a.getR()); // value is initialized with refcount
156 *
157 * Other usecases are discouraged.
158 *
159 */
Steven Moreland063f2362018-10-18 12:49:11 -0700160 T* getR() { return &mT; }
Steven Moreland2648d202018-08-28 01:23:02 -0700161
162 // copy-constructing, or move/copy assignment is disallowed
Steven Moreland1630c192018-10-09 11:54:52 -0700163 ScopedAResource(const ScopedAResource&) = delete;
164 ScopedAResource& operator=(const ScopedAResource&) = delete;
165 ScopedAResource& operator=(ScopedAResource&&) = delete;
Steven Moreland2648d202018-08-28 01:23:02 -0700166
167 // move-constructing is okay
Steven Moreland1630c192018-10-09 11:54:52 -0700168 ScopedAResource(ScopedAResource&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700169
170private:
Steven Moreland063f2362018-10-18 12:49:11 -0700171 T mT;
Steven Moreland2648d202018-08-28 01:23:02 -0700172};
173
174/**
175 * Convenience wrapper. See AParcel.
176 */
Steven Moreland063f2362018-10-18 12:49:11 -0700177class ScopedAParcel : public ScopedAResource<AParcel*, void, AParcel_delete, nullptr> {
Steven Moreland2648d202018-08-28 01:23:02 -0700178public:
179 /**
180 * Takes ownership of a.
181 */
Steven Moreland1630c192018-10-09 11:54:52 -0700182 explicit ScopedAParcel(AParcel* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700183 ~ScopedAParcel() {}
184 ScopedAParcel(ScopedAParcel&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700185};
186
187/**
188 * Convenience wrapper. See AStatus.
189 */
Steven Moreland063f2362018-10-18 12:49:11 -0700190class ScopedAStatus : public ScopedAResource<AStatus*, void, AStatus_delete, nullptr> {
Steven Moreland2648d202018-08-28 01:23:02 -0700191public:
192 /**
193 * Takes ownership of a.
194 */
Steven Moreland1630c192018-10-09 11:54:52 -0700195 explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700196 ~ScopedAStatus() {}
197 ScopedAStatus(ScopedAStatus&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700198
199 /**
200 * See AStatus_isOk.
201 */
202 bool isOk() { return get() != nullptr && AStatus_isOk(get()); }
203};
204
205/**
206 * Convenience wrapper. See AIBinder_DeathRecipient.
207 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700208class ScopedAIBinder_DeathRecipient
Steven Moreland063f2362018-10-18 12:49:11 -0700209 : public ScopedAResource<AIBinder_DeathRecipient*, void, AIBinder_DeathRecipient_delete,
210 nullptr> {
Steven Moreland2648d202018-08-28 01:23:02 -0700211public:
212 /**
213 * Takes ownership of a.
214 */
Steven Moreland1630c192018-10-09 11:54:52 -0700215 explicit ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient* a = nullptr)
216 : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700217 ~ScopedAIBinder_DeathRecipient() {}
218 ScopedAIBinder_DeathRecipient(ScopedAIBinder_DeathRecipient&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700219};
220
221/**
222 * Convenience wrapper. See AIBinder_Weak.
223 */
Steven Moreland063f2362018-10-18 12:49:11 -0700224class ScopedAIBinder_Weak
225 : public ScopedAResource<AIBinder_Weak*, void, AIBinder_Weak_delete, nullptr> {
Steven Moreland2648d202018-08-28 01:23:02 -0700226public:
227 /**
228 * Takes ownership of a.
229 */
Steven Moreland1630c192018-10-09 11:54:52 -0700230 explicit ScopedAIBinder_Weak(AIBinder_Weak* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700231 ~ScopedAIBinder_Weak() {}
232 ScopedAIBinder_Weak(ScopedAIBinder_Weak&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700233
234 /**
235 * See AIBinder_Weak_promote.
236 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700237 SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); }
Steven Moreland2648d202018-08-28 01:23:02 -0700238};
239
Steven Moreland063f2362018-10-18 12:49:11 -0700240/**
241 * Convenience wrapper for a file descriptor.
242 */
243class ScopedFileDescriptor : public ScopedAResource<int, int, close, -1> {
244public:
245 /**
246 * Takes ownership of a.
247 */
248 explicit ScopedFileDescriptor(int a = -1) : ScopedAResource(a) {}
249 ~ScopedFileDescriptor() {}
250 ScopedFileDescriptor(ScopedFileDescriptor&&) = default;
251};
252
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700253} // namespace ndk
Steven Moreland2648d202018-08-28 01:23:02 -0700254
255#endif // __cplusplus
256
257/** @} */