Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a30f2a25 authored by Oleg Blinnikov's avatar Oleg Blinnikov Committed by Android (Google) Code Review
Browse files

Merge "DisplayTopology propagation to IM" into main

parents f6c8514c 15d260fd
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -582,6 +582,15 @@ public final class DisplayTopology implements Parcelable {
        }
    }

    /** Returns the graph representation of the topology */
    public DisplayTopologyGraph getGraph() {
        // TODO(b/364907904): implement
        return new DisplayTopologyGraph(mPrimaryDisplayId,
                new DisplayTopologyGraph.DisplayNode[] { new DisplayTopologyGraph.DisplayNode(
                        mRoot == null ? Display.DEFAULT_DISPLAY : mRoot.mDisplayId,
                        new DisplayTopologyGraph.AdjacentDisplay[0])});
    }

    /**
     * Tests whether two brightness float values are within a small enough tolerance
     * of each other.
+43 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.display;

/**
 * Graph of the displays in {@link android.hardware.display.DisplayTopology} tree.
 *
 * @hide
 */
public record DisplayTopologyGraph(int primaryDisplayId, DisplayNode[] displayNodes) {
    /**
     * Display in the topology
     */
    public record DisplayNode(
            int displayId,
            AdjacentDisplay[] adjacentDisplays) {}

    /**
     * Edge to adjacent display
     */
    public record AdjacentDisplay(
            // The logical Id of this adjacent display
            int displayId,
            // Side of the other display which touches this adjacent display.
            @DisplayTopology.TreeNode.Position
            int position,
            // How many px this display is shifted along the touchingSide, can be negative.
            float offsetPx) {}
}
+1 −0
Original line number Diff line number Diff line
@@ -220,6 +220,7 @@ cc_library_shared_for_libandroid_runtime {
                "android_hardware_camera2_utils_SurfaceUtils.cpp",
                "android_hardware_display_DisplayManagerGlobal.cpp",
                "android_hardware_display_DisplayViewport.cpp",
                "android_hardware_display_DisplayTopology.cpp",
                "android_hardware_HardwareBuffer.cpp",
                "android_hardware_OverlayProperties.cpp",
                "android_hardware_SensorManager.cpp",
+155 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "DisplayTopology-JNI"

#include <android_hardware_display_DisplayTopology.h>
#include <nativehelper/ScopedLocalRef.h>
#include <utils/Errors.h>

#include "jni_wrappers.h"

namespace android {

// ----------------------------------------------------------------------------

static struct {
    jclass clazz;
    jfieldID primaryDisplayId;
    jfieldID displayNodes;
} gDisplayTopologyGraphClassInfo;

static struct {
    jclass clazz;
    jfieldID displayId;
    jfieldID adjacentDisplays;
} gDisplayTopologyGraphNodeClassInfo;

static struct {
    jclass clazz;
    jfieldID displayId;
    jfieldID position;
    jfieldID offsetPx;
} gDisplayTopologyGraphAdjacentDisplayClassInfo;

// ----------------------------------------------------------------------------

status_t android_hardware_display_DisplayTopologyAdjacentDisplay_toNative(
        JNIEnv* env, jobject adjacentDisplayObj, DisplayTopologyAdjacentDisplay* adjacentDisplay) {
    adjacentDisplay->displayId = ui::LogicalDisplayId{
            env->GetIntField(adjacentDisplayObj,
                             gDisplayTopologyGraphAdjacentDisplayClassInfo.displayId)};
    adjacentDisplay->position = static_cast<DisplayTopologyPosition>(
            env->GetIntField(adjacentDisplayObj,
                             gDisplayTopologyGraphAdjacentDisplayClassInfo.position));
    adjacentDisplay->offsetPx =
            env->GetFloatField(adjacentDisplayObj,
                               gDisplayTopologyGraphAdjacentDisplayClassInfo.offsetPx);
    return OK;
}

status_t android_hardware_display_DisplayTopologyGraphNode_toNative(
        JNIEnv* env, jobject nodeObj,
        std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&
                graph) {
    ui::LogicalDisplayId displayId = ui::LogicalDisplayId{
            env->GetIntField(nodeObj, gDisplayTopologyGraphNodeClassInfo.displayId)};

    jobjectArray adjacentDisplaysArray = static_cast<jobjectArray>(
            env->GetObjectField(nodeObj, gDisplayTopologyGraphNodeClassInfo.adjacentDisplays));

    if (adjacentDisplaysArray) {
        jsize length = env->GetArrayLength(adjacentDisplaysArray);
        for (jsize i = 0; i < length; i++) {
            ScopedLocalRef<jobject>
                    adjacentDisplayObj(env, env->GetObjectArrayElement(adjacentDisplaysArray, i));
            if (NULL != adjacentDisplayObj.get()) {
                break; // found null element indicating end of used portion of the array
            }

            DisplayTopologyAdjacentDisplay adjacentDisplay;
            android_hardware_display_DisplayTopologyAdjacentDisplay_toNative(env,
                                                                             adjacentDisplayObj
                                                                                     .get(),
                                                                             &adjacentDisplay);
            graph[displayId].push_back(adjacentDisplay);
        }
    }
    return OK;
}

DisplayTopologyGraph android_hardware_display_DisplayTopologyGraph_toNative(JNIEnv* env,
                                                                            jobject topologyObj) {
    DisplayTopologyGraph topology;
    topology.primaryDisplayId = ui::LogicalDisplayId{
            env->GetIntField(topologyObj, gDisplayTopologyGraphClassInfo.primaryDisplayId)};

    jobjectArray nodesArray = static_cast<jobjectArray>(
            env->GetObjectField(topologyObj, gDisplayTopologyGraphClassInfo.displayNodes));

    if (nodesArray) {
        jsize length = env->GetArrayLength(nodesArray);
        for (jsize i = 0; i < length; i++) {
            ScopedLocalRef<jobject> nodeObj(env, env->GetObjectArrayElement(nodesArray, i));
            if (NULL != nodeObj.get()) {
                break; // found null element indicating end of used portion of the array
            }

            android_hardware_display_DisplayTopologyGraphNode_toNative(env, nodeObj.get(),
                                                                       topology.graph);
        }
    }
    return topology;
}

// ----------------------------------------------------------------------------

int register_android_hardware_display_DisplayTopology(JNIEnv* env) {
    jclass graphClazz = FindClassOrDie(env, "android/hardware/display/DisplayTopologyGraph");
    gDisplayTopologyGraphClassInfo.clazz = MakeGlobalRefOrDie(env, graphClazz);

    gDisplayTopologyGraphClassInfo.primaryDisplayId =
            GetFieldIDOrDie(env, gDisplayTopologyGraphClassInfo.clazz, "primaryDisplayId", "I");
    gDisplayTopologyGraphClassInfo.displayNodes =
            GetFieldIDOrDie(env, gDisplayTopologyGraphClassInfo.clazz, "displayNodes",
                            "[Landroid/hardware/display/DisplayTopologyGraph$DisplayNode;");

    jclass displayNodeClazz =
            FindClassOrDie(env, "android/hardware/display/DisplayTopologyGraph$DisplayNode");
    gDisplayTopologyGraphNodeClassInfo.clazz = MakeGlobalRefOrDie(env, displayNodeClazz);
    gDisplayTopologyGraphNodeClassInfo.displayId =
            GetFieldIDOrDie(env, gDisplayTopologyGraphNodeClassInfo.clazz, "displayId", "I");
    gDisplayTopologyGraphNodeClassInfo.adjacentDisplays =
            GetFieldIDOrDie(env, gDisplayTopologyGraphNodeClassInfo.clazz, "adjacentDisplays",
                            "[Landroid/hardware/display/DisplayTopologyGraph$AdjacentDisplay;");

    jclass adjacentDisplayClazz =
            FindClassOrDie(env, "android/hardware/display/DisplayTopologyGraph$AdjacentDisplay");
    gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz =
            MakeGlobalRefOrDie(env, adjacentDisplayClazz);
    gDisplayTopologyGraphAdjacentDisplayClassInfo.displayId =
            GetFieldIDOrDie(env, gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz, "displayId",
                            "I");
    gDisplayTopologyGraphAdjacentDisplayClassInfo.position =
            GetFieldIDOrDie(env, gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz, "position",
                            "I");
    gDisplayTopologyGraphAdjacentDisplayClassInfo.offsetPx =
            GetFieldIDOrDie(env, gDisplayTopologyGraphAdjacentDisplayClassInfo.clazz, "offsetPx",
                            "F");
    return 0;
}

} // namespace android
+32 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <input/DisplayTopologyGraph.h>

#include "jni.h"

namespace android {

/**
 * Copies the contents of a DVM DisplayTopology object to a new native DisplayTopology instance.
 * Returns DisplayTopology.
 */
extern DisplayTopologyGraph android_hardware_display_DisplayTopologyGraph_toNative(
        JNIEnv* env, jobject eventObj);

} // namespace android
Loading