blob: 946ccb79a5f1b8fca3187b7d2e8369b50b96f020 [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
Elliott Hughes05565472019-10-29 08:59:39 -070024 * @brief These objects provide a more C++-like thin interface to the binder.
Steven Moreland2648d202018-08-28 01:23:02 -070025 */
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 Moreland86ae9e72018-11-05 11:12:40 -080034
Steven Moreland063f2362018-10-18 12:49:11 -070035#include <unistd.h>
Steven Moreland2648d202018-08-28 01:23:02 -070036#include <cstddef>
37
Steven Moreland8b4f48a2018-10-08 14:30:42 -070038namespace ndk {
Steven Moreland2648d202018-08-28 01:23:02 -070039
40/**
41 * Represents one strong pointer to an AIBinder object.
42 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070043class SpAIBinder {
Steven Moreland6cf66ac2018-11-02 18:14:54 -070044 public:
Steven Moreland2648d202018-08-28 01:23:02 -070045 /**
46 * Takes ownership of one strong refcount of binder.
47 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070048 explicit SpAIBinder(AIBinder* binder = nullptr) : mBinder(binder) {}
Steven Moreland2648d202018-08-28 01:23:02 -070049
50 /**
Steven Moreland8b4f48a2018-10-08 14:30:42 -070051 * Convenience operator for implicitly constructing an SpAIBinder from nullptr. This is not
Steven Moreland2648d202018-08-28 01:23:02 -070052 * explicit because it is not taking ownership of anything.
53 */
Chih-Hung Hsieh5ca1ea42018-12-20 15:42:22 -080054 SpAIBinder(std::nullptr_t) : SpAIBinder() {} // NOLINT(google-explicit-constructor)
Steven Moreland2648d202018-08-28 01:23:02 -070055
56 /**
57 * This will delete the underlying object if it exists. See operator=.
58 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070059 SpAIBinder(const SpAIBinder& other) { *this = other; }
Steven Moreland2648d202018-08-28 01:23:02 -070060
61 /**
62 * This deletes the underlying object if it exists. See set.
63 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070064 ~SpAIBinder() { set(nullptr); }
Steven Moreland2648d202018-08-28 01:23:02 -070065
66 /**
67 * This takes ownership of a binder from another AIBinder object but it does not affect the
68 * ownership of that other object.
69 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070070 SpAIBinder& operator=(const SpAIBinder& other) {
Steven Moreland2648d202018-08-28 01:23:02 -070071 AIBinder_incStrong(other.mBinder);
72 set(other.mBinder);
73 return *this;
74 }
75
76 /**
77 * Takes ownership of one strong refcount of binder
78 */
79 void set(AIBinder* binder) {
Steven Morelande97106a2018-10-08 17:53:48 -070080 AIBinder* old = *const_cast<AIBinder* volatile*>(&mBinder);
81 if (old != nullptr) AIBinder_decStrong(old);
82 if (old != *const_cast<AIBinder* volatile*>(&mBinder)) {
83 __assert(__FILE__, __LINE__, "Race detected.");
84 }
Steven Moreland2648d202018-08-28 01:23:02 -070085 mBinder = binder;
86 }
87
88 /**
89 * This returns the underlying binder object for transactions. If it is used to create another
Steven Moreland8b4f48a2018-10-08 14:30:42 -070090 * SpAIBinder object, it should first be incremented.
Steven Moreland2648d202018-08-28 01:23:02 -070091 */
92 AIBinder* get() const { return mBinder; }
93
94 /**
95 * This allows the value in this class to be set from beneath it. If you call this method and
96 * then change the value of T*, you must take ownership of the value you are replacing and add
97 * ownership to the object that is put in here.
98 *
99 * Recommended use is like this:
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700100 * SpAIBinder a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -0700101 * SomeInitFunction(a.getR()); // value is initialized with refcount
102 *
103 * Other usecases are discouraged.
104 *
105 */
106 AIBinder** getR() { return &mBinder; }
107
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700108 private:
Steven Moreland2648d202018-08-28 01:23:02 -0700109 AIBinder* mBinder = nullptr;
110};
111
Steven Moreland26c4df12019-01-30 12:29:53 -0800112namespace impl {
113
Steven Moreland2648d202018-08-28 01:23:02 -0700114/**
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 Moreland6cf66ac2018-11-02 18:14:54 -0700119 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700120 /**
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
Steven Morelandd329d052019-11-05 18:28:47 -0800162 // copy-constructing/assignment is disallowed
Steven Moreland1630c192018-10-09 11:54:52 -0700163 ScopedAResource(const ScopedAResource&) = delete;
164 ScopedAResource& operator=(const ScopedAResource&) = delete;
Steven Moreland2648d202018-08-28 01:23:02 -0700165
Steven Morelandd329d052019-11-05 18:28:47 -0800166 // move-constructing/assignment is okay
Steven Morelandcd056e42018-12-11 11:31:12 -0800167 ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) { other.mT = DEFAULT; }
Steven Morelandd329d052019-11-05 18:28:47 -0800168 ScopedAResource& operator=(ScopedAResource&& other) {
169 set(other.mT);
170 other.mT = DEFAULT;
171 return *this;
172 }
Steven Moreland2648d202018-08-28 01:23:02 -0700173
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700174 private:
Steven Moreland063f2362018-10-18 12:49:11 -0700175 T mT;
Steven Moreland2648d202018-08-28 01:23:02 -0700176};
177
Steven Moreland26c4df12019-01-30 12:29:53 -0800178} // namespace impl
179
Steven Moreland2648d202018-08-28 01:23:02 -0700180/**
181 * Convenience wrapper. See AParcel.
182 */
Steven Moreland26c4df12019-01-30 12:29:53 -0800183class ScopedAParcel : public impl::ScopedAResource<AParcel*, void, AParcel_delete, nullptr> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700184 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700185 /**
186 * Takes ownership of a.
187 */
Steven Moreland1630c192018-10-09 11:54:52 -0700188 explicit ScopedAParcel(AParcel* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700189 ~ScopedAParcel() {}
190 ScopedAParcel(ScopedAParcel&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700191};
192
193/**
194 * Convenience wrapper. See AStatus.
195 */
Steven Moreland26c4df12019-01-30 12:29:53 -0800196class ScopedAStatus : public impl::ScopedAResource<AStatus*, void, AStatus_delete, nullptr> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700197 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700198 /**
199 * Takes ownership of a.
200 */
Steven Moreland1630c192018-10-09 11:54:52 -0700201 explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700202 ~ScopedAStatus() {}
203 ScopedAStatus(ScopedAStatus&&) = default;
Steven Morelandd329d052019-11-05 18:28:47 -0800204 ScopedAStatus& operator=(ScopedAStatus&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700205
206 /**
207 * See AStatus_isOk.
208 */
Steven Moreland190f4f22019-10-16 16:27:26 -0700209 bool isOk() const { return get() != nullptr && AStatus_isOk(get()); }
210
211 /**
212 * See AStatus_getExceptionCode
213 */
214 binder_exception_t getExceptionCode() const { return AStatus_getExceptionCode(get()); }
215
216 /**
217 * See AStatus_getServiceSpecificError
218 */
219 int32_t getServiceSpecificError() const { return AStatus_getServiceSpecificError(get()); }
220
221 /**
222 * See AStatus_getStatus
223 */
224 binder_status_t getStatus() const { return AStatus_getStatus(get()); }
Steven Moreland9450a482018-11-15 15:17:53 -0800225
226 /**
Steven Moreland09773672019-10-30 16:59:06 -0700227 * See AStatus_getMessage
228 */
229 const char* getMessage() const { return AStatus_getMessage(get()); }
230
231 /**
232 * Convenience methods for creating scoped statuses.
Steven Moreland9450a482018-11-15 15:17:53 -0800233 */
234 static ScopedAStatus ok() { return ScopedAStatus(AStatus_newOk()); }
Steven Moreland09773672019-10-30 16:59:06 -0700235 static ScopedAStatus fromExceptionCode(binder_exception_t exception) {
236 return ScopedAStatus(AStatus_fromExceptionCode(exception));
237 }
238 static ScopedAStatus fromExceptionCodeWithMessage(binder_exception_t exception,
239 const char* message) {
240 return ScopedAStatus(AStatus_fromExceptionCodeWithMessage(exception, message));
241 }
242 static ScopedAStatus fromServiceSpecificError(int32_t serviceSpecific) {
243 return ScopedAStatus(AStatus_fromServiceSpecificError(serviceSpecific));
244 }
245 static ScopedAStatus fromServiceSpecificErrorWithMessage(int32_t serviceSpecific,
246 const char* message) {
247 return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(serviceSpecific, message));
248 }
249 static ScopedAStatus fromStatus(binder_status_t status) {
250 return ScopedAStatus(AStatus_fromStatus(status));
251 }
Steven Moreland2648d202018-08-28 01:23:02 -0700252};
253
254/**
255 * Convenience wrapper. See AIBinder_DeathRecipient.
256 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700257class ScopedAIBinder_DeathRecipient
Steven Moreland26c4df12019-01-30 12:29:53 -0800258 : public impl::ScopedAResource<AIBinder_DeathRecipient*, void, AIBinder_DeathRecipient_delete,
259 nullptr> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700260 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700261 /**
262 * Takes ownership of a.
263 */
Steven Moreland1630c192018-10-09 11:54:52 -0700264 explicit ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient* a = nullptr)
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700265 : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700266 ~ScopedAIBinder_DeathRecipient() {}
267 ScopedAIBinder_DeathRecipient(ScopedAIBinder_DeathRecipient&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700268};
269
270/**
271 * Convenience wrapper. See AIBinder_Weak.
272 */
Steven Moreland063f2362018-10-18 12:49:11 -0700273class ScopedAIBinder_Weak
Steven Moreland26c4df12019-01-30 12:29:53 -0800274 : public impl::ScopedAResource<AIBinder_Weak*, void, AIBinder_Weak_delete, nullptr> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700275 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700276 /**
277 * Takes ownership of a.
278 */
Steven Moreland1630c192018-10-09 11:54:52 -0700279 explicit ScopedAIBinder_Weak(AIBinder_Weak* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700280 ~ScopedAIBinder_Weak() {}
281 ScopedAIBinder_Weak(ScopedAIBinder_Weak&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700282
283 /**
284 * See AIBinder_Weak_promote.
285 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700286 SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); }
Steven Moreland2648d202018-08-28 01:23:02 -0700287};
288
Steven Moreland063f2362018-10-18 12:49:11 -0700289/**
290 * Convenience wrapper for a file descriptor.
291 */
Steven Moreland26c4df12019-01-30 12:29:53 -0800292class ScopedFileDescriptor : public impl::ScopedAResource<int, int, close, -1> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700293 public:
Steven Moreland063f2362018-10-18 12:49:11 -0700294 /**
295 * Takes ownership of a.
296 */
297 explicit ScopedFileDescriptor(int a = -1) : ScopedAResource(a) {}
298 ~ScopedFileDescriptor() {}
299 ScopedFileDescriptor(ScopedFileDescriptor&&) = default;
300};
301
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700302} // namespace ndk
Steven Moreland2648d202018-08-28 01:23:02 -0700303
Steven Moreland2648d202018-08-28 01:23:02 -0700304/** @} */