• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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  * @file native_window_aidl.h
19  * @brief NativeWindow NDK AIDL glue code
20  */
21 
22 /**
23  * @addtogroup ANativeWindow
24  *
25  * Parcelable support for ANativeWindow. Can be used with libbinder_ndk
26  *
27  * @{
28  */
29 
30 #ifndef ANDROID_NATIVE_WINDOW_AIDL_H
31 #define ANDROID_NATIVE_WINDOW_AIDL_H
32 
33 #include <android/binder_parcel.h>
34 #include <android/native_window.h>
35 #include <sys/cdefs.h>
36 
37 __BEGIN_DECLS
38 
39 /**
40  * Read an ANativeWindow from a AParcel. The output buffer will have an
41  * initial reference acquired and will need to be released with
42  * ANativeWindow_release.
43  *
44  * Available since API level 34.
45  *
46  * \return STATUS_OK on success
47  *         STATUS_BAD_VALUE if the parcel or outBuffer is null, or if there's an
48  *                          issue deserializing (eg, corrupted parcel)
49  *         STATUS_BAD_TYPE if the parcel's current data position is not that of
50  *                         an ANativeWindow type
51  *         STATUS_NO_MEMORY if an allocation fails
52  */
53 binder_status_t ANativeWindow_readFromParcel(const AParcel* _Nonnull parcel,
54         ANativeWindow* _Nullable* _Nonnull outWindow) __INTRODUCED_IN(__ANDROID_API_U__);
55 
56 /**
57  * Write an ANativeWindow to an AParcel.
58  *
59  * Available since API level 34.
60  *
61  * \return STATUS_OK on success.
62  *         STATUS_BAD_VALUE if either buffer or parcel is null, or if the ANativeWindow*
63  *                          fails to serialize (eg, internally corrupted)
64  *         STATUS_NO_MEMORY if the parcel runs out of space to store the buffer & is
65  *                          unable to allocate more
66  *         STATUS_FDS_NOT_ALLOWED if the parcel does not allow storing FDs
67  */
68 binder_status_t ANativeWindow_writeToParcel(ANativeWindow* _Nonnull window,
69         AParcel* _Nonnull parcel) __INTRODUCED_IN(__ANDROID_API_U__);
70 
71 __END_DECLS
72 
73 // Only enable the AIDL glue helper if this is C++
74 #ifdef __cplusplus
75 
76 namespace aidl::android::hardware {
77 
78 /**
79  * Wrapper class that enables interop with AIDL NDK generation
80  * Takes ownership of the ANativeWindow* given to it in reset() and will automatically
81  * destroy it in the destructor, similar to a smart pointer container
82  */
83 class NativeWindow {
84 public:
NativeWindow()85     NativeWindow() noexcept {}
NativeWindow(ANativeWindow * _Nullable window)86     explicit NativeWindow(ANativeWindow* _Nullable window) {
87         reset(window);
88     }
89 
NativeWindow(NativeWindow && other)90     explicit NativeWindow(NativeWindow&& other) noexcept {
91         mWindow = other.release(); // steal ownership from r-value
92     }
93 
~NativeWindow()94     ~NativeWindow() {
95         reset();
96     }
97 
readFromParcel(const AParcel * _Nonnull parcel)98     binder_status_t readFromParcel(const AParcel* _Nonnull parcel) {
99         reset();
100         return ANativeWindow_readFromParcel(parcel, &mWindow);
101     }
102 
writeToParcel(AParcel * _Nonnull parcel)103     binder_status_t writeToParcel(AParcel* _Nonnull parcel) const {
104         if (!mWindow) {
105             return STATUS_BAD_VALUE;
106         }
107         return ANativeWindow_writeToParcel(mWindow, parcel);
108     }
109 
110     /**
111      * Destroys any currently owned ANativeWindow* and takes ownership of the given
112      * ANativeWindow*
113      *
114      * @param buffer The buffer to take ownership of
115      */
116     void reset(ANativeWindow* _Nullable window = nullptr) noexcept {
117         if (mWindow) {
118             ANativeWindow_release(mWindow);
119             mWindow = nullptr;
120         }
121         if (window != nullptr) {
122             ANativeWindow_acquire(window);
123         }
124         mWindow = window;
125     }
126     inline ANativeWindow* _Nullable operator-> () const { return mWindow;  }
get()127     inline ANativeWindow* _Nullable get() const { return mWindow; }
128     inline explicit operator bool () const { return mWindow != nullptr; }
129 
130     NativeWindow& operator=(NativeWindow&& other) noexcept {
131         mWindow = other.release(); // steal ownership from r-value
132         return *this;
133     }
134 
135     /**
136      * Stops managing any contained ANativeWindow*, returning it to the caller. Ownership
137      * is released.
138      * @return ANativeWindow* or null if this was empty
139      */
release()140     [[nodiscard]] ANativeWindow* _Nullable release() noexcept {
141         ANativeWindow* _Nullable ret = mWindow;
142         mWindow = nullptr;
143         return ret;
144     }
145 private:
146     ANativeWindow* _Nullable mWindow = nullptr;
147     NativeWindow(const NativeWindow &other) = delete;
148     NativeWindow& operator=(const NativeWindow &other) = delete;
149 };
150 
151 } // aidl::android::hardware
152   //
153 namespace aidl::android::view {
154     using Surface = aidl::android::hardware::NativeWindow;
155 }
156 
157 #endif // __cplusplus
158 
159 #endif // ANDROID_NATIVE_WINDOW_AIDL_H
160 
161 /** @} */
162