blob: 5c26039717af5e12be8cc0682fb0f859645309e1 [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 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 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -070054 SpAIBinder(std::nullptr_t) : SpAIBinder() {}
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
112/**
113 * This baseclass owns a single object, used to make various classes RAII.
114 */
Steven Moreland063f2362018-10-18 12:49:11 -0700115template <typename T, typename R, R (*Destroy)(T), T DEFAULT>
Steven Moreland1630c192018-10-09 11:54:52 -0700116class ScopedAResource {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700117 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700118 /**
119 * Takes ownership of t.
120 */
Steven Moreland063f2362018-10-18 12:49:11 -0700121 explicit ScopedAResource(T t = DEFAULT) : mT(t) {}
Steven Moreland2648d202018-08-28 01:23:02 -0700122
123 /**
124 * This deletes the underlying object if it exists. See set.
125 */
Steven Moreland063f2362018-10-18 12:49:11 -0700126 ~ScopedAResource() { set(DEFAULT); }
Steven Moreland2648d202018-08-28 01:23:02 -0700127
128 /**
129 * Takes ownership of t.
130 */
Steven Moreland063f2362018-10-18 12:49:11 -0700131 void set(T t) {
Steven Moreland2648d202018-08-28 01:23:02 -0700132 Destroy(mT);
133 mT = t;
134 }
135
136 /**
137 * This returns the underlying object to be modified but does not affect ownership.
138 */
Steven Moreland063f2362018-10-18 12:49:11 -0700139 T get() { return mT; }
Steven Moreland2648d202018-08-28 01:23:02 -0700140
141 /**
142 * This returns the const underlying object but does not affect ownership.
143 */
Steven Moreland063f2362018-10-18 12:49:11 -0700144 const T get() const { return mT; }
Steven Moreland2648d202018-08-28 01:23:02 -0700145
146 /**
147 * This allows the value in this class to be set from beneath it. If you call this method and
148 * then change the value of T*, you must take ownership of the value you are replacing and add
149 * ownership to the object that is put in here.
150 *
151 * Recommended use is like this:
Steven Moreland1630c192018-10-09 11:54:52 -0700152 * ScopedAResource<T> a; // will be nullptr
Steven Moreland2648d202018-08-28 01:23:02 -0700153 * SomeInitFunction(a.getR()); // value is initialized with refcount
154 *
155 * Other usecases are discouraged.
156 *
157 */
Steven Moreland063f2362018-10-18 12:49:11 -0700158 T* getR() { return &mT; }
Steven Moreland2648d202018-08-28 01:23:02 -0700159
160 // copy-constructing, or move/copy assignment is disallowed
Steven Moreland1630c192018-10-09 11:54:52 -0700161 ScopedAResource(const ScopedAResource&) = delete;
162 ScopedAResource& operator=(const ScopedAResource&) = delete;
163 ScopedAResource& operator=(ScopedAResource&&) = delete;
Steven Moreland2648d202018-08-28 01:23:02 -0700164
165 // move-constructing is okay
Steven Moreland1630c192018-10-09 11:54:52 -0700166 ScopedAResource(ScopedAResource&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700167
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700168 private:
Steven Moreland063f2362018-10-18 12:49:11 -0700169 T mT;
Steven Moreland2648d202018-08-28 01:23:02 -0700170};
171
172/**
173 * Convenience wrapper. See AParcel.
174 */
Steven Moreland063f2362018-10-18 12:49:11 -0700175class ScopedAParcel : public ScopedAResource<AParcel*, void, AParcel_delete, nullptr> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700176 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700177 /**
178 * Takes ownership of a.
179 */
Steven Moreland1630c192018-10-09 11:54:52 -0700180 explicit ScopedAParcel(AParcel* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700181 ~ScopedAParcel() {}
182 ScopedAParcel(ScopedAParcel&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700183};
184
185/**
186 * Convenience wrapper. See AStatus.
187 */
Steven Moreland063f2362018-10-18 12:49:11 -0700188class ScopedAStatus : public ScopedAResource<AStatus*, void, AStatus_delete, nullptr> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700189 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700190 /**
191 * Takes ownership of a.
192 */
Steven Moreland1630c192018-10-09 11:54:52 -0700193 explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700194 ~ScopedAStatus() {}
195 ScopedAStatus(ScopedAStatus&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700196
197 /**
198 * See AStatus_isOk.
199 */
200 bool isOk() { return get() != nullptr && AStatus_isOk(get()); }
201};
202
203/**
204 * Convenience wrapper. See AIBinder_DeathRecipient.
205 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700206class ScopedAIBinder_DeathRecipient
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700207 : public ScopedAResource<AIBinder_DeathRecipient*, void, AIBinder_DeathRecipient_delete,
208 nullptr> {
209 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700210 /**
211 * Takes ownership of a.
212 */
Steven Moreland1630c192018-10-09 11:54:52 -0700213 explicit ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient* a = nullptr)
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700214 : 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 Moreland063f2362018-10-18 12:49:11 -0700222class ScopedAIBinder_Weak
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700223 : public ScopedAResource<AIBinder_Weak*, void, AIBinder_Weak_delete, nullptr> {
224 public:
Steven Moreland2648d202018-08-28 01:23:02 -0700225 /**
226 * Takes ownership of a.
227 */
Steven Moreland1630c192018-10-09 11:54:52 -0700228 explicit ScopedAIBinder_Weak(AIBinder_Weak* a = nullptr) : ScopedAResource(a) {}
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700229 ~ScopedAIBinder_Weak() {}
230 ScopedAIBinder_Weak(ScopedAIBinder_Weak&&) = default;
Steven Moreland2648d202018-08-28 01:23:02 -0700231
232 /**
233 * See AIBinder_Weak_promote.
234 */
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700235 SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); }
Steven Moreland2648d202018-08-28 01:23:02 -0700236};
237
Steven Moreland063f2362018-10-18 12:49:11 -0700238/**
239 * Convenience wrapper for a file descriptor.
240 */
241class ScopedFileDescriptor : public ScopedAResource<int, int, close, -1> {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700242 public:
Steven Moreland063f2362018-10-18 12:49:11 -0700243 /**
244 * Takes ownership of a.
245 */
246 explicit ScopedFileDescriptor(int a = -1) : ScopedAResource(a) {}
247 ~ScopedFileDescriptor() {}
248 ScopedFileDescriptor(ScopedFileDescriptor&&) = default;
249};
250
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700251} // namespace ndk
Steven Moreland2648d202018-08-28 01:23:02 -0700252
Steven Moreland2648d202018-08-28 01:23:02 -0700253/** @} */