blob: bf1c7a78407ecbc1571c4c4b1bb0376416ec59a1 [file] [log] [blame]
#define FML_USED_ON_EMBEDDER
#include <memory>
#include "flutter/shell/common/thread_host.h"
#include "flutter/shell/platform/android/android_context_gl_skia.h"
#include "flutter/shell/platform/android/android_egl_surface.h"
#include "flutter/shell/platform/android/android_environment_gl.h"
#include "flutter/shell/platform/android/android_surface_gl_skia.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace flutter {
namespace testing {
namespace android {
namespace {
class MockPlatformViewAndroidJNI : public PlatformViewAndroidJNI {
public:
MOCK_METHOD2(FlutterViewHandlePlatformMessage,
void(std::unique_ptr<flutter::PlatformMessage> message,
int responseId));
MOCK_METHOD2(FlutterViewHandlePlatformMessageResponse,
void(int responseId, std::unique_ptr<fml::Mapping> data));
MOCK_METHOD3(FlutterViewUpdateSemantics,
void(std::vector<uint8_t> buffer,
std::vector<std::string> strings,
std::vector<std::vector<uint8_t>> string_attribute_args));
MOCK_METHOD2(FlutterViewUpdateCustomAccessibilityActions,
void(std::vector<uint8_t> actions_buffer,
std::vector<std::string> strings));
MOCK_METHOD0(FlutterViewOnFirstFrame, void());
MOCK_METHOD0(FlutterViewOnPreEngineRestart, void());
MOCK_METHOD2(SurfaceTextureAttachToGLContext,
void(JavaLocalRef surface_texture, int textureId));
MOCK_METHOD1(SurfaceTextureUpdateTexImage,
void(JavaLocalRef surface_texture));
MOCK_METHOD2(SurfaceTextureGetTransformMatrix,
void(JavaLocalRef surface_texture, SkMatrix& transform));
MOCK_METHOD1(SurfaceTextureDetachFromGLContext,
void(JavaLocalRef surface_texture));
MOCK_METHOD8(FlutterViewOnDisplayPlatformView,
void(int view_id,
int x,
int y,
int width,
int height,
int viewWidth,
int viewHeight,
MutatorsStack mutators_stack));
MOCK_METHOD5(FlutterViewDisplayOverlaySurface,
void(int surface_id, int x, int y, int width, int height));
MOCK_METHOD0(FlutterViewBeginFrame, void());
MOCK_METHOD0(FlutterViewEndFrame, void());
MOCK_METHOD0(FlutterViewCreateOverlaySurface,
std::unique_ptr<PlatformViewAndroidJNI::OverlayMetadata>());
MOCK_METHOD0(FlutterViewDestroyOverlaySurfaces, void());
MOCK_METHOD1(FlutterViewComputePlatformResolvedLocale,
std::unique_ptr<std::vector<std::string>>(
std::vector<std::string> supported_locales_data));
MOCK_METHOD0(GetDisplayRefreshRate, double());
MOCK_METHOD1(RequestDartDeferredLibrary, bool(int loading_unit_id));
};
TaskRunners MakeTaskRunners(const std::string& thread_label,
const ThreadHost& thread_host) {
fml::MessageLoop::EnsureInitializedForCurrentThread();
fml::RefPtr<fml::TaskRunner> platform_runner =
fml::MessageLoop::GetCurrent().GetTaskRunner();
return TaskRunners(thread_label, platform_runner,
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
}
} // namespace
TEST(AndroidContextGl, Create) {
GrMockOptions main_context_options;
sk_sp<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
std::string thread_label =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
thread_label,
ThreadHost::Type::UI | ThreadHost::Type::RASTER | ThreadHost::Type::IO));
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
auto context = std::make_unique<AndroidContextGLSkia>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);
context->SetMainSkiaContext(main_context);
EXPECT_NE(context.get(), nullptr);
context.reset();
EXPECT_TRUE(main_context->abandoned());
}
TEST(AndroidContextGl, CreateSingleThread) {
GrMockOptions main_context_options;
sk_sp<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
std::string thread_label =
::testing::UnitTest::GetInstance()->current_test_info()->name();
fml::MessageLoop::EnsureInitializedForCurrentThread();
fml::RefPtr<fml::TaskRunner> platform_runner =
fml::MessageLoop::GetCurrent().GetTaskRunner();
TaskRunners task_runners =
TaskRunners(thread_label, platform_runner, platform_runner,
platform_runner, platform_runner);
auto context = std::make_unique<AndroidContextGLSkia>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);
context->SetMainSkiaContext(main_context);
EXPECT_NE(context.get(), nullptr);
context.reset();
EXPECT_TRUE(main_context->abandoned());
}
TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNotNull) {
GrMockOptions main_context_options;
sk_sp<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
std::string thread_label =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
thread_label,
ThreadHost::Type::UI | ThreadHost::Type::RASTER | ThreadHost::Type::IO));
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
auto android_context = std::make_shared<AndroidContextGLSkia>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);
auto jni = std::make_shared<MockPlatformViewAndroidJNI>();
auto android_surface =
std::make_unique<AndroidSurfaceGLSkia>(android_context, jni);
auto window = fml::MakeRefCounted<AndroidNativeWindow>(
nullptr, /*is_fake_window=*/true);
android_surface->SetNativeWindow(window);
auto onscreen_surface = android_surface->GetOnscreenSurface();
EXPECT_NE(onscreen_surface, nullptr);
android_surface->CreateSnapshotSurface();
EXPECT_EQ(onscreen_surface, android_surface->GetOnscreenSurface());
}
TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNull) {
GrMockOptions main_context_options;
sk_sp<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
std::string thread_label =
::testing::UnitTest::GetInstance()->current_test_info()->name();
auto mask =
ThreadHost::Type::UI | ThreadHost::Type::RASTER | ThreadHost::Type::IO;
flutter::ThreadHost::ThreadHostConfig host_config(mask);
ThreadHost thread_host(host_config);
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
auto android_context = std::make_shared<AndroidContextGLSkia>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);
auto jni = std::make_shared<MockPlatformViewAndroidJNI>();
auto android_surface =
std::make_unique<AndroidSurfaceGLSkia>(android_context, jni);
EXPECT_EQ(android_surface->GetOnscreenSurface(), nullptr);
android_surface->CreateSnapshotSurface();
EXPECT_NE(android_surface->GetOnscreenSurface(), nullptr);
}
// TODO(https://github.com/flutter/flutter/issues/104463): Flaky test.
TEST(AndroidContextGl, DISABLED_MSAAx4) {
GrMockOptions main_context_options;
sk_sp<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
std::string thread_label =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
thread_label,
ThreadHost::Type::UI | ThreadHost::Type::RASTER | ThreadHost::Type::IO));
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
auto context = std::make_unique<AndroidContextGLSkia>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 4);
context->SetMainSkiaContext(main_context);
EGLint sample_count;
eglGetConfigAttrib(environment->Display(), context->Config(), EGL_SAMPLES,
&sample_count);
EXPECT_EQ(sample_count, 4);
}
TEST(AndroidContextGl, EnsureMakeCurrentChecksCurrentContextStatus) {
GrMockOptions main_context_options;
sk_sp<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
std::string thread_label =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
thread_label,
ThreadHost::Type::UI | ThreadHost::Type::RASTER | ThreadHost::Type::IO));
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
auto context = std::make_unique<AndroidContextGLSkia>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);
auto pbuffer_surface = context->CreatePbufferSurface();
auto status = pbuffer_surface->MakeCurrent();
EXPECT_EQ(AndroidEGLSurfaceMakeCurrentStatus::kSuccessMadeCurrent, status);
// context already current, so status must reflect that.
status = pbuffer_surface->MakeCurrent();
EXPECT_EQ(AndroidEGLSurfaceMakeCurrentStatus::kSuccessAlreadyCurrent, status);
}
} // namespace android
} // namespace testing
} // namespace flutter