Tests: Change screen orientation for traces on Android

This CL adds a reverse JNI call to our Android Native Activity that
sets the orientation of the screen based on width and height.

To achieve this we:
* Attach to the java thread once at the beginning to grab JNI env.
* Detach from the thread once when platform sends APP_CMD_DESTROY
* Set the orientation during test init

Bug: angleproject:4327
Change-Id: Ifbe31a6a84dd60a0dfe7d7032962c99b290d8b81
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2289054
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com>
Commit-Queue: Cody Northrop <cnorthrop@google.com>
This commit is contained in:
Cody Northrop 2020-07-10 09:13:39 -06:00 коммит произвёл Commit Bot
Родитель dc9743fb97
Коммит 6fe87f4a22
14 изменённых файлов: 100 добавлений и 4 удалений

Просмотреть файл

@ -145,6 +145,12 @@ void TracePerfTest::initializeBenchmark()
std::string testDataDir = testDataDirStr.str();
SetBinaryDataDir(params.testID, testDataDir.c_str());
if (IsAndroid())
{
// On Android, set the orientation used by the app, based on width/height
getWindow()->setOrientation(mTestParams.windowWidth, mTestParams.windowHeight);
}
// Potentially slow. Can load a lot of resources.
SetupReplay(params.testID);
glFinish();

Просмотреть файл

@ -54,10 +54,11 @@ class ANGLE_UTIL_EXPORT OSWindow
bool popEvent(Event *event);
virtual void pushEvent(Event event);
virtual void setMousePosition(int x, int y) = 0;
virtual bool setPosition(int x, int y) = 0;
virtual bool resize(int width, int height) = 0;
virtual void setVisible(bool isVisible) = 0;
virtual void setMousePosition(int x, int y) = 0;
virtual bool setOrientation(int width, int height) = 0;
virtual bool setPosition(int x, int y) = 0;
virtual bool resize(int width, int height) = 0;
virtual void setVisible(bool isVisible) = 0;
virtual void signalTestEvent() = 0;

Просмотреть файл

@ -19,6 +19,41 @@ struct android_app *sApp = nullptr;
pthread_mutex_t sInitWindowMutex;
pthread_cond_t sInitWindowCond;
bool sInitWindowDone = false;
JNIEnv *gJni = nullptr;
// SCREEN_ORIENTATION_LANDSCAPE and SCREEN_ORIENTATION_PORTRAIT are
// available from Android API level 1
// https://developer.android.com/reference/android/app/Activity#setRequestedOrientation(int)
const int kScreenOrientationLandscape = 0;
const int kScreenOrientationPortrait = 1;
JNIEnv *GetJniEnv()
{
if (gJni)
return gJni;
sApp->activity->vm->AttachCurrentThread(&gJni, NULL);
return gJni;
}
int SetScreenOrientation(struct android_app *app, int orientation)
{
// Use reverse JNI to call the Java entry point that rotates the
// display to respect width and height
JNIEnv *jni = GetJniEnv();
if (!jni)
{
WARN() << "Failed to get JNI env for screen rotation";
return JNI_ERR;
}
jclass clazz = jni->GetObjectClass(app->activity->clazz);
jmethodID methodID = jni->GetMethodID(clazz, "setRequestedOrientation", "(I)V");
jni->CallVoidMethod(app->activity->clazz, methodID, orientation);
return 0;
}
} // namespace
AndroidWindow::AndroidWindow() {}
@ -58,6 +93,14 @@ void AndroidWindow::setMousePosition(int x, int y)
UNIMPLEMENTED();
}
bool AndroidWindow::setOrientation(int width, int height)
{
// Set tests to run in correct orientation
int32_t err = SetScreenOrientation(
sApp, (width > height) ? kScreenOrientationLandscape : kScreenOrientationPortrait);
return err == 0;
}
bool AndroidWindow::setPosition(int x, int y)
{
UNIMPLEMENTED();
@ -100,6 +143,14 @@ static void onAppCmd(struct android_app *app, int32_t cmd)
pthread_cond_broadcast(&sInitWindowCond);
pthread_mutex_unlock(&sInitWindowMutex);
break;
case APP_CMD_DESTROY:
if (gJni)
{
sApp->activity->vm->DetachCurrentThread();
}
gJni = nullptr;
break;
// TODO: process other commands and pass them to AndroidWindow for handling
// TODO: figure out how to handle APP_CMD_PAUSE,
// which should immediately halt all the rendering,

Просмотреть файл

@ -28,6 +28,7 @@ class AndroidWindow : public OSWindow
void messageLoop() override;
void setMousePosition(int x, int y) override;
bool setOrientation(int width, int height) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;

Просмотреть файл

@ -165,6 +165,12 @@ void ScenicWindow::setMousePosition(int x, int y)
UNIMPLEMENTED();
}
bool ScenicWindow::setOrientation(int width, int height)
{
UNIMPLEMENTED();
return false;
}
bool ScenicWindow::setPosition(int x, int y)
{
UNIMPLEMENTED();

Просмотреть файл

@ -49,6 +49,7 @@ class ANGLE_UTIL_EXPORT ScenicWindow : public OSWindow
EGLNativeDisplayType getNativeDisplay() const override;
void messageLoop() override;
void setMousePosition(int x, int y) override;
bool setOrientation(int width, int height) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;

Просмотреть файл

@ -46,6 +46,7 @@ class OSXWindow : public OSWindow
void messageLoop() override;
void setMousePosition(int x, int y) override;
bool setOrientation(int width, int height) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;

Просмотреть файл

@ -743,6 +743,12 @@ void OSXWindow::setMousePosition(int x, int y)
CGWarpMouseCursorPosition(CGPointMake(screenspace.x, YCoordToFromCG(screenspace.y)));
}
bool OSXWindow::setOrientation(int width, int height)
{
UNIMPLEMENTED();
return false;
}
bool OSXWindow::setPosition(int x, int y)
{
// Given CG and NS's coordinate system, the "Y" position of a window is the Y coordinate

Просмотреть файл

@ -8,6 +8,8 @@
#include "util/ozone/OzoneWindow.h"
#include "common/debug.h"
int OzoneWindow::sLastDepth = 0;
OzoneWindow::OzoneWindow() {}
@ -47,6 +49,12 @@ void OzoneWindow::messageLoop() {}
void OzoneWindow::setMousePosition(int x, int y) {}
bool OzoneWindow::setOrientation(int width, int height)
{
UNIMPLEMENTED();
return false;
}
bool OzoneWindow::setPosition(int x, int y)
{
mNative.x = mX = x;

Просмотреть файл

@ -30,6 +30,7 @@ class OzoneWindow : public OSWindow
void messageLoop() override;
void setMousePosition(int x, int y) override;
bool setOrientation(int width, int height) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;

Просмотреть файл

@ -743,6 +743,12 @@ void Win32Window::setMousePosition(int x, int y)
SetCursorPos(topLeft.x + x, topLeft.y + y);
}
bool Win32Window::setOrientation(int width, int height)
{
UNIMPLEMENTED();
return false;
}
bool Win32Window::setPosition(int x, int y)
{
if (mX == x && mY == y)

Просмотреть файл

@ -36,6 +36,7 @@ class Win32Window : public OSWindow
void pushEvent(Event event) override;
void setMousePosition(int x, int y) override;
bool setOrientation(int width, int height) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;

Просмотреть файл

@ -417,6 +417,12 @@ void X11Window::setMousePosition(int x, int y)
XWarpPointer(mDisplay, None, mWindow, 0, 0, 0, 0, x, y);
}
bool X11Window::setOrientation(int width, int height)
{
UNIMPLEMENTED();
return false;
}
bool X11Window::setPosition(int x, int y)
{
XMoveWindow(mDisplay, mWindow, x, y);

Просмотреть файл

@ -35,6 +35,7 @@ class ANGLE_UTIL_EXPORT X11Window : public OSWindow
void messageLoop() override;
void setMousePosition(int x, int y) override;
bool setOrientation(int width, int height) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;