• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 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 "DisplayTopology-JNI"
18 
19 #include <android_hardware_display_DisplayTopology.h>
20 #include <nativehelper/ScopedLocalRef.h>
21 #include <utils/Errors.h>
22 
23 #include "jni_wrappers.h"
24 
25 namespace android {
26 
27 // ----------------------------------------------------------------------------
28 
29 static struct {
30     jclass clazz;
31     jfieldID primaryDisplayId;
32     jfieldID displayNodes;
33 } gDisplayTopologyGraphClassInfo;
34 
35 static struct {
36     jclass clazz;
37     jfieldID displayId;
38     jfieldID density;
39     jfieldID adjacentDisplays;
40 } gDisplayTopologyGraphNodeClassInfo;
41 
42 static struct {
43     jclass clazz;
44     jfieldID displayId;
45     jfieldID position;
46     jfieldID offsetDp;
47 } gDisplayTopologyGraphAdjacentDisplayClassInfo;
48 
49 // ----------------------------------------------------------------------------
50 
android_hardware_display_DisplayTopologyAdjacentDisplay_toNative(JNIEnv * env,jobject adjacentDisplayObj,DisplayTopologyAdjacentDisplay * adjacentDisplay)51 status_t android_hardware_display_DisplayTopologyAdjacentDisplay_toNative(
52         JNIEnv* env, jobject adjacentDisplayObj, DisplayTopologyAdjacentDisplay* adjacentDisplay) {
53     adjacentDisplay->displayId = ui::LogicalDisplayId{
54             env->GetIntField(adjacentDisplayObj,
55                              gDisplayTopologyGraphAdjacentDisplayClassInfo.displayId)};
56     adjacentDisplay->position = static_cast<DisplayTopologyPosition>(
57             env->GetIntField(adjacentDisplayObj,
58                              gDisplayTopologyGraphAdjacentDisplayClassInfo.position));
59     adjacentDisplay->offsetDp =
60             env->GetFloatField(adjacentDisplayObj,
61                                gDisplayTopologyGraphAdjacentDisplayClassInfo.offsetDp);
62     return OK;
63 }
64 
android_hardware_display_DisplayTopologyGraphNode_toNative(JNIEnv * env,jobject nodeObj,std::unordered_map<ui::LogicalDisplayId,std::vector<DisplayTopologyAdjacentDisplay>> & graph,std::unordered_map<ui::LogicalDisplayId,int> & displaysDensity)65 status_t android_hardware_display_DisplayTopologyGraphNode_toNative(
66         JNIEnv* env, jobject nodeObj,
67         std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&
68                 graph,
69         std::unordered_map<ui::LogicalDisplayId, int>& displaysDensity) {
70     ui::LogicalDisplayId displayId = ui::LogicalDisplayId{
71             env->GetIntField(nodeObj, gDisplayTopologyGraphNodeClassInfo.displayId)};
72 
73     displaysDensity[displayId] =
74             env->GetIntField(nodeObj, gDisplayTopologyGraphNodeClassInfo.density);
75 
76     jobjectArray adjacentDisplaysArray = static_cast<jobjectArray>(
77             env->GetObjectField(nodeObj, gDisplayTopologyGraphNodeClassInfo.adjacentDisplays));
78 
79     if (adjacentDisplaysArray) {
80         jsize length = env->GetArrayLength(adjacentDisplaysArray);
81         for (jsize i = 0; i < length; i++) {
82             ScopedLocalRef<jobject>
83                     adjacentDisplayObj(env, env->GetObjectArrayElement(adjacentDisplaysArray, i));
84             if (NULL == adjacentDisplayObj.get()) {
85                 break; // found null element indicating end of used portion of the array
86             }
87 
88             DisplayTopologyAdjacentDisplay adjacentDisplay;
89             android_hardware_display_DisplayTopologyAdjacentDisplay_toNative(env,
90                                                                              adjacentDisplayObj
91                                                                                      .get(),
92                                                                              &adjacentDisplay);
93             graph[displayId].push_back(adjacentDisplay);
94         }
95     }
96     return OK;
97 }
98 
android_hardware_display_DisplayTopologyGraph_toNative(JNIEnv * env,jobject topologyObj)99 DisplayTopologyGraph android_hardware_display_DisplayTopologyGraph_toNative(JNIEnv* env,
100                                                                             jobject topologyObj) {
101     DisplayTopologyGraph topology;
102     topology.primaryDisplayId = ui::LogicalDisplayId{
103             env->GetIntField(topologyObj, gDisplayTopologyGraphClassInfo.primaryDisplayId)};
104 
105     jobjectArray nodesArray = static_cast<jobjectArray>(
106             env->GetObjectField(topologyObj, gDisplayTopologyGraphClassInfo.displayNodes));
107 
108     if (nodesArray) {
109         jsize length = env->GetArrayLength(nodesArray);
110         for (jsize i = 0; i < length; i++) {
111             ScopedLocalRef<jobject> nodeObj(env, env->GetObjectArrayElement(nodesArray, i));
112             if (NULL == nodeObj.get()) {
113                 break; // found null element indicating end of used portion of the array
114             }
115 
116             android_hardware_display_DisplayTopologyGraphNode_toNative(env, nodeObj.get(),
117                                                                        topology.graph,
118                                                                        topology.displaysDensity);
119         }
120     }
121     return topology;
122 }
123 
124 // ----------------------------------------------------------------------------
125 
register_android_hardware_display_DisplayTopology(JNIEnv * env)126 int register_android_hardware_display_DisplayTopology(JNIEnv* env) {
127     jclass graphClazz = FindClassOrDie(env, "android/hardware/display/DisplayTopologyGraph");
128     gDisplayTopologyGraphClassInfo.clazz = MakeGlobalRefOrDie(env, graphClazz);
129 
130     gDisplayTopologyGraphClassInfo.primaryDisplayId =
131             GetFieldIDOrDie(env, gDisplayTopologyGraphClassInfo.clazz, "primaryDisplayId", "I");
132     gDisplayTopologyGraphClassInfo.displayNodes =
133             GetFieldIDOrDie(env, gDisplayTopologyGraphClassInfo.clazz, "displayNodes",
134                             "[Landroid/hardware/display/DisplayTopologyGraph$DisplayNode;");
135 
136     jclass displayNodeClazz =
137             FindClassOrDie(env, "android/hardware/display/DisplayTopologyGraph$DisplayNode");
138     gDisplayTopologyGraphNodeClassInfo.clazz = MakeGlobalRefOrDie(env, displayNodeClazz);
139     gDisplayTopologyGraphNodeClassInfo.displayId =
140             GetFieldIDOrDie(env, gDisplayTopologyGraphNodeClassInfo.clazz, "displayId", "I");
141     gDisplayTopologyGraphNodeClassInfo.density =
142             GetFieldIDOrDie(env, gDisplayTopologyGraphNodeClassInfo.clazz, "density", "I");
143     gDisplayTopologyGraphNodeClassInfo.adjacentDisplays =
144             GetFieldIDOrDie(env, gDisplayTopologyGraphNodeClassInfo.clazz, "adjacentDisplays",
145                             "[Landroid/hardware/display/DisplayTopologyGraph$AdjacentDisplay;");
146 
147     jclass adjacentDisplayClazz =
148             FindClassOrDie(env, "android/hardware/display/DisplayTopologyGraph$AdjacentDisplay");
149     gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz =
150             MakeGlobalRefOrDie(env, adjacentDisplayClazz);
151     gDisplayTopologyGraphAdjacentDisplayClassInfo.displayId =
152             GetFieldIDOrDie(env, gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz, "displayId",
153                             "I");
154     gDisplayTopologyGraphAdjacentDisplayClassInfo.position =
155             GetFieldIDOrDie(env, gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz, "position",
156                             "I");
157     gDisplayTopologyGraphAdjacentDisplayClassInfo.offsetDp =
158             GetFieldIDOrDie(env, gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz, "offsetDp",
159                             "F");
160     return 0;
161 }
162 
163 } // namespace android
164