1 /**
2  * Copyright (C) 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 #define LOG_TAG "OverlayProperties"
18 // #define LOG_NDEBUG 0
19 
20 #include <android/gui/OverlayProperties.h>
21 #include <binder/Parcel.h>
22 #include <gui/SurfaceComposerClient.h>
23 #include <nativehelper/JNIHelp.h>
24 
25 #include "android_os_Parcel.h"
26 #include "core_jni_helpers.h"
27 #include "jni.h"
28 
29 using namespace android;
30 
31 // ----------------------------------------------------------------------------
32 // Types
33 // ----------------------------------------------------------------------------
34 static struct {
35     jclass clazz;
36     jmethodID ctor;
37 } gOverlayPropertiesClassInfo;
38 // ----------------------------------------------------------------------------
39 // OverlayProperties lifecycle
40 // ----------------------------------------------------------------------------
41 
destroyOverlayProperties(gui::OverlayProperties * overlayProperties)42 static void destroyOverlayProperties(gui::OverlayProperties* overlayProperties) {
43     delete overlayProperties;
44 }
45 
android_hardware_OverlayProperties_getDestructor(JNIEnv *,jclass)46 static jlong android_hardware_OverlayProperties_getDestructor(JNIEnv*, jclass) {
47     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyOverlayProperties));
48 }
49 
50 //----------------------------------------------------------------------------
51 // Accessors
52 // ----------------------------------------------------------------------------
53 
android_hardware_OverlayProperties_isCombinationSupported(JNIEnv * env,jobject thiz,jlong nativeObject,jint dataspace,jint format)54 static jboolean android_hardware_OverlayProperties_isCombinationSupported(JNIEnv* env, jobject thiz,
55                                                                           jlong nativeObject,
56                                                                           jint dataspace,
57                                                                           jint format) {
58     gui::OverlayProperties* properties = reinterpret_cast<gui::OverlayProperties*>(nativeObject);
59     if (properties != nullptr) {
60         for (const auto& i : properties->combinations) {
61             if (std::find(i.pixelFormats.begin(), i.pixelFormats.end(), format) !=
62                         i.pixelFormats.end() &&
63                 std::find(i.standards.begin(), i.standards.end(),
64                           dataspace & HAL_DATASPACE_STANDARD_MASK) != i.standards.end() &&
65                 std::find(i.transfers.begin(), i.transfers.end(),
66                           dataspace & HAL_DATASPACE_TRANSFER_MASK) != i.transfers.end() &&
67                 std::find(i.ranges.begin(), i.ranges.end(), dataspace & HAL_DATASPACE_RANGE_MASK) !=
68                         i.ranges.end()) {
69                 return true;
70             }
71         }
72     }
73     return false;
74 }
75 
android_hardware_OverlayProperties_supportMixedColorSpaces(JNIEnv * env,jobject thiz,jlong nativeObject)76 static jboolean android_hardware_OverlayProperties_supportMixedColorSpaces(JNIEnv* env,
77                                                                            jobject thiz,
78                                                                            jlong nativeObject) {
79     gui::OverlayProperties* properties = reinterpret_cast<gui::OverlayProperties*>(nativeObject);
80     if (properties != nullptr && properties->supportMixedColorSpaces) {
81         return true;
82     }
83     return false;
84 }
85 
android_hardware_OverlayProperties_createDefault(JNIEnv * env,jobject thiz)86 static jlong android_hardware_OverlayProperties_createDefault(JNIEnv* env, jobject thiz) {
87     gui::OverlayProperties* overlayProperties = new gui::OverlayProperties;
88     gui::OverlayProperties::SupportedBufferCombinations combination;
89     combination.pixelFormats = {HAL_PIXEL_FORMAT_RGBA_8888};
90     combination.standards = {HAL_DATASPACE_STANDARD_BT709};
91     combination.transfers = {HAL_DATASPACE_TRANSFER_SRGB};
92     combination.ranges = {HAL_DATASPACE_RANGE_FULL};
93     overlayProperties->combinations.emplace_back(combination);
94     overlayProperties->supportMixedColorSpaces = true;
95     return reinterpret_cast<jlong>(overlayProperties);
96 }
97 
98 // ----------------------------------------------------------------------------
99 // Serialization
100 // ----------------------------------------------------------------------------
101 
android_hardware_OverlayProperties_write(JNIEnv * env,jclass,jlong nativeObject,jobject dest)102 static void android_hardware_OverlayProperties_write(JNIEnv* env, jclass, jlong nativeObject,
103                                                      jobject dest) {
104     Parcel* parcel = parcelForJavaObject(env, dest);
105     if (parcel == nullptr) {
106         jniThrowNullPointerException(env, nullptr);
107         return;
108     }
109     gui::OverlayProperties* overlayProperties =
110             reinterpret_cast<gui::OverlayProperties*>(nativeObject);
111     if (overlayProperties != nullptr) {
112         overlayProperties->writeToParcel(parcel);
113     }
114 }
115 
android_hardware_OverlayProperties_read(JNIEnv * env,jclass,jobject in)116 static long android_hardware_OverlayProperties_read(JNIEnv* env, jclass, jobject in) {
117     Parcel* parcel = parcelForJavaObject(env, in);
118     if (parcel == nullptr) {
119         jniThrowNullPointerException(env, nullptr);
120         return 0;
121     }
122     gui::OverlayProperties* overlayProperties = new gui::OverlayProperties;
123     if (overlayProperties->readFromParcel(parcel) != NO_ERROR) {
124         delete overlayProperties;
125         return 0;
126     }
127     return reinterpret_cast<jlong>(overlayProperties);
128 }
129 
130 // ----------------------------------------------------------------------------
131 // Public functions
132 // ----------------------------------------------------------------------------
133 
134 namespace android {
135 
android_hardware_OverlayProperties_convertToJavaObject(JNIEnv * env,gui::OverlayProperties * overlayProperties)136 jobject android_hardware_OverlayProperties_convertToJavaObject(
137         JNIEnv* env, gui::OverlayProperties* overlayProperties) {
138     jobject overlayPropertiesObj =
139             env->NewObject(gOverlayPropertiesClassInfo.clazz, gOverlayPropertiesClassInfo.ctor,
140                            reinterpret_cast<jlong>(overlayProperties));
141     return overlayPropertiesObj;
142 }
143 
144 }; // namespace android
145 
146 // ----------------------------------------------------------------------------
147 // JNI Glue
148 // ----------------------------------------------------------------------------
149 
150 const char* const kClassPathName = "android/hardware/OverlayProperties";
151 
152 // clang-format off
153 static const JNINativeMethod gMethods[] = {
154     { "nGetDestructor", "()J", (void*) android_hardware_OverlayProperties_getDestructor },
155     { "nIsCombinationSupported",  "(JII)Z",
156             (void*)  android_hardware_OverlayProperties_isCombinationSupported },
157     { "nSupportMixedColorSpaces", "(J)Z",
158             (void*) android_hardware_OverlayProperties_supportMixedColorSpaces },
159     { "nWriteOverlayPropertiesToParcel", "(JLandroid/os/Parcel;)V",
160             (void*) android_hardware_OverlayProperties_write },
161     { "nReadOverlayPropertiesFromParcel", "(Landroid/os/Parcel;)J",
162             (void*) android_hardware_OverlayProperties_read },
163     {"nCreateDefault", "()J", (void*) android_hardware_OverlayProperties_createDefault },
164 };
165 // clang-format on
166 
register_android_hardware_OverlayProperties(JNIEnv * env)167 int register_android_hardware_OverlayProperties(JNIEnv* env) {
168     int err = RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
169 
170     jclass clazz = FindClassOrDie(env, "android/hardware/OverlayProperties");
171     gOverlayPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
172     gOverlayPropertiesClassInfo.ctor =
173             GetMethodIDOrDie(env, gOverlayPropertiesClassInfo.clazz, "<init>", "(J)V");
174     return err;
175 }
176