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 // Only required by the AIDL glue helper 38 #ifdef __cplusplus 39 #include <sstream> 40 #include <string> 41 #endif // __cplusplus 42 43 __BEGIN_DECLS 44 45 /** 46 * Read an ANativeWindow from a AParcel. The output buffer will have an 47 * initial reference acquired and will need to be released with 48 * ANativeWindow_release. 49 * 50 * Available since API level 34. 51 * 52 * \return STATUS_OK on success 53 * STATUS_BAD_VALUE if the parcel or outBuffer is null, or if there's an 54 * issue deserializing (eg, corrupted parcel) 55 * STATUS_BAD_TYPE if the parcel's current data position is not that of 56 * an ANativeWindow type 57 * STATUS_NO_MEMORY if an allocation fails 58 */ 59 binder_status_t ANativeWindow_readFromParcel(const AParcel* _Nonnull parcel, 60 ANativeWindow* _Nullable* _Nonnull outWindow) __INTRODUCED_IN(__ANDROID_API_U__); 61 62 /** 63 * Write an ANativeWindow to an AParcel. 64 * 65 * Available since API level 34. 66 * 67 * \return STATUS_OK on success. 68 * STATUS_BAD_VALUE if either buffer or parcel is null, or if the ANativeWindow* 69 * fails to serialize (eg, internally corrupted) 70 * STATUS_NO_MEMORY if the parcel runs out of space to store the buffer & is 71 * unable to allocate more 72 * STATUS_FDS_NOT_ALLOWED if the parcel does not allow storing FDs 73 */ 74 binder_status_t ANativeWindow_writeToParcel(ANativeWindow* _Nonnull window, 75 AParcel* _Nonnull parcel) __INTRODUCED_IN(__ANDROID_API_U__); 76 77 __END_DECLS 78 79 // Only enable the AIDL glue helper if this is C++ 80 #ifdef __cplusplus 81 82 namespace aidl::android::hardware { 83 84 /** 85 * Wrapper class that enables interop with AIDL NDK generation 86 * Takes ownership of the ANativeWindow* given to it in reset() and will automatically 87 * destroy it in the destructor, similar to a smart pointer container 88 */ 89 class NativeWindow final { 90 public: NativeWindow()91 NativeWindow() noexcept {} NativeWindow(ANativeWindow * _Nullable window)92 explicit NativeWindow(ANativeWindow* _Nullable window) { 93 reset(window); 94 } 95 NativeWindow(NativeWindow && other)96 explicit NativeWindow(NativeWindow&& other) noexcept { 97 mWindow = other.release(); // steal ownership from r-value 98 } 99 ~NativeWindow()100 ~NativeWindow() { 101 reset(); 102 } 103 readFromParcel(const AParcel * _Nonnull parcel)104 binder_status_t readFromParcel(const AParcel* _Nonnull parcel) { 105 reset(); 106 if (__builtin_available(android __ANDROID_API_U__, *)) { 107 return ANativeWindow_readFromParcel(parcel, &mWindow); 108 } else { 109 return STATUS_INVALID_OPERATION; 110 } 111 } 112 writeToParcel(AParcel * _Nonnull parcel)113 binder_status_t writeToParcel(AParcel* _Nonnull parcel) const { 114 if (!mWindow) { 115 return STATUS_BAD_VALUE; 116 } 117 if (__builtin_available(android __ANDROID_API_U__, *)) { 118 return ANativeWindow_writeToParcel(mWindow, parcel); 119 } else { 120 return STATUS_INVALID_OPERATION; 121 } 122 } 123 124 /** 125 * Destroys any currently owned ANativeWindow* and takes ownership of the given 126 * ANativeWindow* 127 * 128 * @param buffer The buffer to take ownership of 129 */ 130 void reset(ANativeWindow* _Nullable window = nullptr) noexcept { 131 if (mWindow) { 132 ANativeWindow_release(mWindow); 133 mWindow = nullptr; 134 } 135 if (window != nullptr) { 136 ANativeWindow_acquire(window); 137 } 138 mWindow = window; 139 } 140 get()141 inline ANativeWindow* _Nullable get() const { return mWindow; } 142 143 NativeWindow& operator=(NativeWindow&& other) noexcept { 144 mWindow = other.release(); // steal ownership from r-value 145 return *this; 146 } 147 148 inline ANativeWindow* _Nullable operator->() const { return mWindow; } 149 inline explicit operator bool() const { return mWindow != nullptr; } 150 inline bool operator==(const NativeWindow& rhs) const { return mWindow == rhs.mWindow; } 151 inline bool operator!=(const NativeWindow& rhs) const { return !(*this == rhs); } 152 inline bool operator<(const NativeWindow& rhs) const { return mWindow < rhs.mWindow; } 153 inline bool operator>(const NativeWindow& rhs) const { return rhs < *this; } 154 inline bool operator>=(const NativeWindow& rhs) const { return !(*this < rhs); } 155 inline bool operator<=(const NativeWindow& rhs) const { return !(*this > rhs); } 156 toString()157 std::string toString() const { 158 std::ostringstream ss; 159 ss << "NativeWindow: " << mWindow; 160 return ss.str(); 161 } 162 163 /** 164 * Stops managing any contained ANativeWindow*, returning it to the caller. Ownership 165 * is released. 166 * @return ANativeWindow* or null if this was empty 167 */ release()168 [[nodiscard]] ANativeWindow* _Nullable release() noexcept { 169 ANativeWindow* _Nullable ret = mWindow; 170 mWindow = nullptr; 171 return ret; 172 } 173 private: 174 ANativeWindow* _Nullable mWindow = nullptr; 175 NativeWindow(const NativeWindow &other) = delete; 176 NativeWindow& operator=(const NativeWindow &other) = delete; 177 }; 178 179 } // aidl::android::hardware 180 // 181 namespace aidl::android::view { 182 using Surface = aidl::android::hardware::NativeWindow; 183 } 184 185 #endif // __cplusplus 186 187 #endif // ANDROID_NATIVE_WINDOW_AIDL_H 188 189 /** @} */ 190