blob: cc0a29d18abd34970f0b4a9a307c81575595c598 [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>
34
Steven Moreland2648d202018-08-28 01:23:02 -070035#ifdef __cplusplus
36
37#include <cstddef>
38
Steven Moreland8b4f48a2018-10-08 14:30:42 -070039namespace ndk {
Steven Moreland2648d202018-08-28 01:23:02 -070040
41/**
42 * Represents one strong pointer to an AIBinder object.
43 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070044class SpAIBinder {
Steven Moreland2648d202018-08-28 01:23:02 -070045public:
46 /**
47 * Takes ownership of one strong refcount of binder.
48 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070049 explicit SpAIBinder(AIBinder* binder = nullptr) : mBinder(binder) {}
Steven Moreland2648d202018-08-28 01:23:02 -070050
51 /**
Steven Moreland8b4f48a2018-10-08 14:30:42 -070052 * Convenience operator for implicitly constructing an SpAIBinder from nullptr. This is not
Steven Moreland2648d202018-08-28 01:23:02 -070053 * explicit because it is not taking ownership of anything.
54 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070055 SpAIBinder(std::nullptr_t) : SpAIBinder() {}
Steven Moreland2648d202018-08-28 01:23:02 -070056
57 /**
58 * This will delete the underlying object if it exists. See operator=.
59 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070060 SpAIBinder(const SpAIBinder& other) { *this = other; }
Steven Moreland2648d202018-08-28 01:23:02 -070061
62 /**
63 * This deletes the underlying object if it exists. See set.
64 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070065 ~SpAIBinder() { set(nullptr); }
Steven Moreland2648d202018-08-28 01:23:02 -070066
67 /**
68 * This takes ownership of a binder from another AIBinder object but it does not affect the
69 * ownership of that other object.
70 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070071 SpAIBinder& operator=(const SpAIBinder& other) {
Steven Moreland2648d202018-08-28 01:23:02 -070072 AIBinder_incStrong(other.mBinder);
73 set(other.mBinder);
74 return *this;
75 }
76
77 /**
78 * Takes ownership of one strong refcount of binder
79 */
80 void set(AIBinder* binder) {
Steven Morelande97106a2018-10-08 17:53:48 -070081 AIBinder* old = *const_cast<AIBinder* volatile*>(&mBinder);
82 if (old != nullptr) AIBinder_decStrong(old);
83 if (old != *const_cast<AIBinder* volatile*>(&mBinder)) {
84 __assert(__FILE__, __LINE__, "Race detected.");
85 }
Steven Moreland2648d202018-08-28 01:23:02 -070086 mBinder = binder;
87 }
88
89 /**
90 * This returns the underlying binder object for transactions. If it is used to create another
Steven Moreland8b4f48a2018-10-08 14:30:42 -070091 * SpAIBinder object, it should first be incremented.
Steven Moreland2648d202018-08-28 01:23:02 -070092 */
93 AIBinder* get() const { return mBinder; }
94
95 /**
96 * This allows the value in this class to be set from beneath it. If you call this method and
97 * then change the value of T*, you must take ownership of the value you are replacing and add
98 * ownership to the object that is put in here.
99 *
100 * Recommended use is like this:
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700101 * SpAIBinder a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -0700102 * SomeInitFunction(a.getR()); // value is initialized with refcount
103 *
104 * Other usecases are discouraged.
105 *
106 */
107 AIBinder** getR() { return &mBinder; }
108
109private:
110 AIBinder* mBinder = nullptr;
111};
112
113/**
114 * This baseclass owns a single object, used to make various classes RAII.
115 */
116template <typename T, void (*Destroy)(T*)>
Steven Moreland1630c192018-10-09 11:54:52 -0700117class ScopedAResource {
Steven Moreland2648d202018-08-28 01:23:02 -0700118public:
119 /**
120 * Takes ownership of t.
121 */
Steven Moreland1630c192018-10-09 11:54:52 -0700122 explicit ScopedAResource(T* t = nullptr) : mT(t) {}
Steven Moreland2648d202018-08-28 01:23:02 -0700123
124 /**
125 * This deletes the underlying object if it exists. See set.
126 */
Steven Moreland1630c192018-10-09 11:54:52 -0700127 ~ScopedAResource() { set(nullptr); }
Steven Moreland2648d202018-08-28 01:23:02 -0700128
129 /**
130 * Takes ownership of t.
131 */
132 void set(T* t) {
133 Destroy(mT);
134 mT = t;
135 }
136
137 /**
138 * This returns the underlying object to be modified but does not affect ownership.
139 */
140 T* get() { return mT; }
141
142 /**
143 * This returns the const underlying object but does not affect ownership.
144 */
145 const T* get() const { return mT; }
146
147 /**
148 * This allows the value in this class to be set from beneath it. If you call this method and
149 * then change the value of T*, you must take ownership of the value you are replacing and add
150 * ownership to the object that is put in here.
151 *
152 * Recommended use is like this:
Steven Moreland1630c192018-10-09 11:54:52 -0700153 * ScopedAResource<T> a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -0700154 * SomeInitFunction(a.getR()); // value is initialized with refcount
155 *
156 * Other usecases are discouraged.
157 *
158 */
159 T** getR() { return &mT; }
160
161 // copy-constructing, or move/copy assignment is disallowed
Steven Moreland1630c192018-10-09 11:54:52 -0700162 ScopedAResource(const ScopedAResource&) = delete;
163 ScopedAResource& operator=(const ScopedAResource&) = delete;
164 ScopedAResource& operator=(ScopedAResource&&) = delete;
Steven Moreland2648d202018-08-28 01:23:02 -0700165
166 // move-constructing is okay
Steven Moreland1630c192018-10-09 11:54:52 -0700167 ScopedAResource(ScopedAResource&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700168
169private:
170 T* mT;
171};
172
173/**
174 * Convenience wrapper. See AParcel.
175 */
Steven Moreland1630c192018-10-09 11:54:52 -0700176class ScopedAParcel : public ScopedAResource<AParcel, AParcel_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700177public:
178 /**
179 * Takes ownership of a.
180 */
Steven Moreland1630c192018-10-09 11:54:52 -0700181 explicit ScopedAParcel(AParcel* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700182 ~ScopedAParcel() {}
183 ScopedAParcel(ScopedAParcel&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700184};
185
186/**
187 * Convenience wrapper. See AStatus.
188 */
Steven Moreland1630c192018-10-09 11:54:52 -0700189class ScopedAStatus : public ScopedAResource<AStatus, AStatus_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700190public:
191 /**
192 * Takes ownership of a.
193 */
Steven Moreland1630c192018-10-09 11:54:52 -0700194 explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700195 ~ScopedAStatus() {}
196 ScopedAStatus(ScopedAStatus&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700197
198 /**
199 * See AStatus_isOk.
200 */
201 bool isOk() { return get() != nullptr && AStatus_isOk(get()); }
202};
203
204/**
205 * Convenience wrapper. See AIBinder_DeathRecipient.
206 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700207class ScopedAIBinder_DeathRecipient
Steven Moreland1630c192018-10-09 11:54:52 -0700208 : public ScopedAResource<AIBinder_DeathRecipient, AIBinder_DeathRecipient_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700209public:
210 /**
211 * Takes ownership of a.
212 */
Steven Moreland1630c192018-10-09 11:54:52 -0700213 explicit ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient* a = nullptr)
214 : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700215 ~ScopedAIBinder_DeathRecipient() {}
216 ScopedAIBinder_DeathRecipient(ScopedAIBinder_DeathRecipient&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700217};
218
219/**
220 * Convenience wrapper. See AIBinder_Weak.
221 */
Steven Moreland1630c192018-10-09 11:54:52 -0700222class ScopedAIBinder_Weak : public ScopedAResource<AIBinder_Weak, AIBinder_Weak_delete> {
Steven Moreland2648d202018-08-28 01:23:02 -0700223public:
224 /**
225 * Takes ownership of a.
226 */
Steven Moreland1630c192018-10-09 11:54:52 -0700227 explicit ScopedAIBinder_Weak(AIBinder_Weak* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700228 ~ScopedAIBinder_Weak() {}
229 ScopedAIBinder_Weak(ScopedAIBinder_Weak&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700230
231 /**
232 * See AIBinder_Weak_promote.
233 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700234 SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); }
Steven Moreland2648d202018-08-28 01:23:02 -0700235};
236
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700237} // namespace ndk
Steven Moreland2648d202018-08-28 01:23:02 -0700238
239#endif // __cplusplus
240
241/** @} */