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

Commit 57928e6a authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Verify SurfaceView BlastBufferQueue behavior

Initial code to easily configure buffer producers to generate buffers
with different properties inorder exercise and validate
BlastBufferQueue adapter.

The test captures surface flinger traces and verifies properties of a
single buffer. This will allow us to verify buffer presentation order,
buffer rejection, buffer properties and so on.

Test: atest SurfaceViewBufferTests
Bug: 168504870
Change-Id: I9714d7b6f5ffbe5fecca5d93e8184f0e6ac2b4c1
parent 4be3ece8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
               libs/input/
               services/core/jni/
               services/incremental/
               tests/
               tools/

[Hook Scripts]
+58 −0
Original line number Diff line number Diff line
// Copyright (C) 2020 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.

android_test {
    name: "SurfaceViewBufferTests",
    srcs: ["**/*.java","**/*.kt"],
    manifest: "AndroidManifest.xml",
    test_config: "AndroidTest.xml",
    platform_apis: true,
    certificate: "platform",
    use_embedded_native_libs: true,
    jni_libs: [
        "libsurface_jni",
    ],

    static_libs: [
        "androidx.appcompat_appcompat",
        "androidx.test.rules",
        "androidx.test.runner",
        "androidx.test.ext.junit",
        "kotlin-stdlib",
        "kotlinx-coroutines-android",
        "flickerlib",
        "truth-prebuilt",
    ],
}

cc_library_shared {
    name: "libsurface_jni",
    srcs: [
        "cpp/SurfaceProxy.cpp",
    ],
    shared_libs: [
        "libutils",
        "libgui",
        "liblog",
        "libandroid",
    ],
    include_dirs: [
        "system/core/include"
    ],
    stl: "libc++_static",
    cflags: [
        "-Werror",
        "-Wall",
    ],
}
+46 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 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.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.test">

    <uses-sdk android:minSdkVersion="29"
         android:targetSdkVersion="29"/>
    <!-- Enable / Disable tracing !-->
    <uses-permission android:name="android.permission.DUMP" />
    <!-- Enable / Disable sv blast adapter !-->
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

    <application android:allowBackup="false"
         android:supportsRtl="true">
        <activity android:name=".MainActivity"
                  android:taskAffinity="com.android.test.MainActivity"
                  android:theme="@style/AppTheme"
                  android:label="SurfaceViewBufferTestApp"
                  android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <uses-library android:name="android.test.runner"/>
    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="com.android.test"
                     android:label="SurfaceViewBufferTests">
    </instrumentation>
</manifest>
+35 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 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.
-->
<configuration description="Runs SurfaceView Buffer Tests">
    <option name="test-tag" value="SurfaceViewBufferTests" />
    <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
        <!-- keeps the screen on during tests -->
        <option name="screen-always-on" value="on" />
        <!-- prevents the phone from restarting -->
        <option name="force-skip-system-props" value="true" />
    </target_preparer>
    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
        <option name="cleanup-apks" value="false"/>
        <option name="test-file-name" value="SurfaceViewBufferTests.apk"/>
    </target_preparer>
    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
        <option name="package" value="com.android.test"/>
        <option name="exclude-annotation" value="androidx.test.filters.FlakyTest" />
        <option name="shell-timeout" value="6600s" />
        <option name="test-timeout" value="6000s" />
        <option name="hidden-api-checks" value="false" />
    </test>
</configuration>
+102 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.
 */

#include <android/log.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <android/window.h>
#include <gui/Surface.h>
#include <jni.h>
#include <system/window.h>
#include <utils/RefBase.h>
#include <cassert>
#include <chrono>
#include <thread>

#define TAG "SurfaceViewBufferTests"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)

extern "C" {
int i = 0;
static ANativeWindow* sAnw;

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_setSurface(JNIEnv* env, jclass,
                                                                     jobject surfaceObject) {
    sAnw = ANativeWindow_fromSurface(env, surfaceObject);
    assert(sAnw);
    android::sp<android::Surface> surface = static_cast<android::Surface*>(sAnw);
    surface->enableFrameTimestamps(true);
    return 0;
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_waitUntilBufferDisplayed(
        JNIEnv*, jclass, jint jFrameNumber, jint timeoutSec) {
    using namespace std::chrono_literals;
    assert(sAnw);
    android::sp<android::Surface> surface = static_cast<android::Surface*>(sAnw);

    uint64_t frameNumber = static_cast<uint64_t>(jFrameNumber);
    nsecs_t outRequestedPresentTime, outAcquireTime, outLatchTime, outFirstRefreshStartTime;
    nsecs_t outLastRefreshStartTime, outGlCompositionDoneTime, outDequeueReadyTime;
    nsecs_t outDisplayPresentTime = -1;
    nsecs_t outReleaseTime;

    auto start = std::chrono::steady_clock::now();
    while (outDisplayPresentTime < 0) {
        std::this_thread::sleep_for(8ms);
        surface->getFrameTimestamps(frameNumber, &outRequestedPresentTime, &outAcquireTime,
                                    &outLatchTime, &outFirstRefreshStartTime,
                                    &outLastRefreshStartTime, &outGlCompositionDoneTime,
                                    &outDisplayPresentTime, &outDequeueReadyTime, &outReleaseTime);
        if (outDisplayPresentTime < 0) {
            auto end = std::chrono::steady_clock::now();
            if (std::chrono::duration_cast<std::chrono::seconds>(end - start).count() >
                timeoutSec) {
                return -1;
            }
        }
    }
    return 0;
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_draw(JNIEnv*, jclass) {
    assert(sAnw);
    ANativeWindow_Buffer outBuffer;
    ANativeWindow_lock(sAnw, &outBuffer, nullptr);
    return 0;
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_ANativeWindowLock(JNIEnv*, jclass) {
    assert(sAnw);
    ANativeWindow_Buffer outBuffer;
    ANativeWindow_lock(sAnw, &outBuffer, nullptr);
    return 0;
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_ANativeWindowUnlockAndPost(JNIEnv*,
                                                                                     jclass) {
    assert(sAnw);
    ANativeWindow_unlockAndPost(sAnw);
    return 0;
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_ANativeWindowSetBuffersGeometry(
        JNIEnv* /* env */, jclass /* clazz */, jobject /* surfaceObject */, jint w, jint h,
        jint format) {
    assert(sAnw);
    return ANativeWindow_setBuffersGeometry(sAnw, w, h, format);
}
}
 No newline at end of file
Loading