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