mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Avoid sending a 0 DPR to framework (#21389)
* Avoid sending a 0 DPR to framework * check width and height as well
This commit is contained in:
parent
48ab5d1d14
commit
aa8d5d4b9b
@ -42,10 +42,6 @@ ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio,
|
||||
physical_system_gesture_inset_bottom(
|
||||
p_physical_system_gesture_inset_bottom),
|
||||
physical_system_gesture_inset_left(p_physical_system_gesture_inset_left) {
|
||||
// Ensure we don't have nonsensical dimensions.
|
||||
FML_DCHECK(physical_width >= 0);
|
||||
FML_DCHECK(physical_height >= 0);
|
||||
FML_DCHECK(device_pixel_ratio > 0);
|
||||
}
|
||||
|
||||
ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio,
|
||||
@ -53,11 +49,6 @@ ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio,
|
||||
double p_physical_height)
|
||||
: device_pixel_ratio(p_device_pixel_ratio),
|
||||
physical_width(p_physical_width),
|
||||
physical_height(p_physical_height) {
|
||||
// Ensure we don't have nonsensical dimensions.
|
||||
FML_DCHECK(physical_width >= 0);
|
||||
FML_DCHECK(physical_height >= 0);
|
||||
FML_DCHECK(device_pixel_ratio > 0);
|
||||
}
|
||||
physical_height(p_physical_height) {}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -47,6 +47,19 @@ void onPointerDataPacketMain() {
|
||||
@pragma('vm:entry-point')
|
||||
void emptyMain() {}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void reportMetrics() {
|
||||
window.onMetricsChanged = () {
|
||||
_reportMetrics(
|
||||
window.devicePixelRatio,
|
||||
window.physicalSize.width,
|
||||
window.physicalSize.height,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
void _reportMetrics(double devicePixelRatio, double width, double height) native 'ReportMetrics';
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void dummyReportTimingsMain() {
|
||||
window.onReportTimings = (List<FrameTiming> timings) {};
|
||||
|
||||
@ -816,6 +816,16 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) {
|
||||
FML_DCHECK(is_setup_);
|
||||
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
|
||||
|
||||
if (metrics.device_pixel_ratio <= 0 || metrics.physical_width <= 0 ||
|
||||
metrics.physical_height <= 0) {
|
||||
FML_DLOG(ERROR)
|
||||
<< "Embedding reported invalid ViewportMetrics, ignoring update."
|
||||
<< "\nphysical_width: " << metrics.physical_width
|
||||
<< "\nphysical_height: " << metrics.physical_height
|
||||
<< "\ndevice_pixel_ratio: " << metrics.device_pixel_ratio;
|
||||
return;
|
||||
}
|
||||
|
||||
// This is the formula Android uses.
|
||||
// https://android.googlesource.com/platform/frameworks/base/+/master/libs/hwui/renderthread/CacheManager.cpp#41
|
||||
size_t max_bytes = metrics.physical_width * metrics.physical_height * 12 * 4;
|
||||
|
||||
@ -2066,5 +2066,74 @@ TEST_F(ShellTest, DiscardLayerTreeOnResize) {
|
||||
DestroyShell(std::move(shell));
|
||||
}
|
||||
|
||||
TEST_F(ShellTest, IgnoresInvalidMetrics) {
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
double last_device_pixel_ratio;
|
||||
double last_width;
|
||||
double last_height;
|
||||
auto native_report_device_pixel_ratio = [&](Dart_NativeArguments args) {
|
||||
auto dpr_handle = Dart_GetNativeArgument(args, 0);
|
||||
ASSERT_TRUE(Dart_IsDouble(dpr_handle));
|
||||
Dart_DoubleValue(dpr_handle, &last_device_pixel_ratio);
|
||||
ASSERT_FALSE(last_device_pixel_ratio == 0.0);
|
||||
|
||||
auto width_handle = Dart_GetNativeArgument(args, 1);
|
||||
ASSERT_TRUE(Dart_IsDouble(width_handle));
|
||||
Dart_DoubleValue(width_handle, &last_width);
|
||||
ASSERT_FALSE(last_width == 0.0);
|
||||
|
||||
auto height_handle = Dart_GetNativeArgument(args, 2);
|
||||
ASSERT_TRUE(Dart_IsDouble(height_handle));
|
||||
Dart_DoubleValue(height_handle, &last_height);
|
||||
ASSERT_FALSE(last_height == 0.0);
|
||||
|
||||
latch.Signal();
|
||||
};
|
||||
|
||||
Settings settings = CreateSettingsForFixture();
|
||||
auto task_runner = CreateNewThread();
|
||||
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
|
||||
task_runner);
|
||||
|
||||
AddNativeCallback("ReportMetrics",
|
||||
CREATE_NATIVE_ENTRY(native_report_device_pixel_ratio));
|
||||
|
||||
std::unique_ptr<Shell> shell =
|
||||
CreateShell(std::move(settings), std::move(task_runners));
|
||||
|
||||
auto configuration = RunConfiguration::InferFromSettings(settings);
|
||||
configuration.SetEntrypoint("reportMetrics");
|
||||
|
||||
RunEngine(shell.get(), std::move(configuration));
|
||||
|
||||
task_runner->PostTask([&]() {
|
||||
shell->GetPlatformView()->SetViewportMetrics({0.0, 400, 200});
|
||||
task_runner->PostTask([&]() {
|
||||
shell->GetPlatformView()->SetViewportMetrics({0.8, 0.0, 200});
|
||||
task_runner->PostTask([&]() {
|
||||
shell->GetPlatformView()->SetViewportMetrics({0.8, 400, 0.0});
|
||||
task_runner->PostTask([&]() {
|
||||
shell->GetPlatformView()->SetViewportMetrics({0.8, 400, 200.0});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
latch.Wait();
|
||||
ASSERT_EQ(last_device_pixel_ratio, 0.8);
|
||||
ASSERT_EQ(last_width, 400.0);
|
||||
ASSERT_EQ(last_height, 200.0);
|
||||
latch.Reset();
|
||||
|
||||
task_runner->PostTask([&]() {
|
||||
shell->GetPlatformView()->SetViewportMetrics({1.2, 600, 300});
|
||||
});
|
||||
latch.Wait();
|
||||
ASSERT_EQ(last_device_pixel_ratio, 1.2);
|
||||
ASSERT_EQ(last_width, 600.0);
|
||||
ASSERT_EQ(last_height, 300.0);
|
||||
|
||||
DestroyShell(std::move(shell), std::move(task_runners));
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user