From 33d7553e39921215a45b868768be15c1b4d22452 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 21 Jan 2016 11:22:09 -0800 Subject: [PATCH] Improve handling of window insets on Android Now that we understand window insets, we don't need to hard-code the size of the status bar. Also, convert the viewport metrics to be consistently in physical pixels. --- sky/engine/core/window/window.cc | 16 ++--- .../public/platform/sky_display_metrics.h | 10 ++-- sky/services/engine/sky_engine.mojom | 10 ++-- .../platform/android/AndroidManifest.xml | 3 +- .../sky/shell/PlatformViewAndroid.java | 60 ++++++++----------- .../org/domokit/sky/shell/SkyActivity.java | 23 ++++--- sky/shell/platform/ios/sky_surface.mm | 6 +- sky/shell/ui/engine.cc | 10 ++-- 8 files changed, 60 insertions(+), 78 deletions(-) diff --git a/sky/engine/core/window/window.cc b/sky/engine/core/window/window.cc index b82d969092..80b7811f68 100644 --- a/sky/engine/core/window/window.cc +++ b/sky/engine/core/window/window.cc @@ -54,19 +54,15 @@ void Window::UpdateWindowMetrics(const SkyDisplayMetrics& metrics) { if (!dart_state) return; DartState::Scope scope(dart_state); - double device_pixel_ratio = metrics.device_pixel_ratio; - double width = metrics.physical_size.width / device_pixel_ratio; - double height = metrics.physical_size.height / device_pixel_ratio; - DartInvokeField(library_.value(), "_updateWindowMetrics", { ToDart(device_pixel_ratio), - ToDart(width), - ToDart(height), - ToDart(metrics.padding_top), - ToDart(metrics.padding_right), - ToDart(metrics.padding_bottom), - ToDart(metrics.padding_left), + ToDart(metrics.physical_size.width / device_pixel_ratio), + ToDart(metrics.physical_size.height / device_pixel_ratio), + ToDart(metrics.physical_padding_top / device_pixel_ratio), + ToDart(metrics.physical_padding_right / device_pixel_ratio), + ToDart(metrics.physical_padding_bottom / device_pixel_ratio), + ToDart(metrics.physical_padding_left / device_pixel_ratio), }); } diff --git a/sky/engine/public/platform/sky_display_metrics.h b/sky/engine/public/platform/sky_display_metrics.h index abe63b3365..c0c3c0a3da 100644 --- a/sky/engine/public/platform/sky_display_metrics.h +++ b/sky/engine/public/platform/sky_display_metrics.h @@ -10,12 +10,12 @@ namespace blink { struct SkyDisplayMetrics { - WebSize physical_size; float device_pixel_ratio = 1.0; - double padding_top = 0.0; - double padding_right = 0.0; - double padding_bottom = 0.0; - double padding_left = 0.0; + WebSize physical_size; + int physical_padding_top = 0; + int physical_padding_right = 0; + int physical_padding_bottom = 0; + int physical_padding_left = 0; }; } // namespace blink diff --git a/sky/services/engine/sky_engine.mojom b/sky/services/engine/sky_engine.mojom index 826ba92b31..3aa9c38de2 100644 --- a/sky/services/engine/sky_engine.mojom +++ b/sky/services/engine/sky_engine.mojom @@ -17,13 +17,13 @@ enum AppLifecycleState { }; struct ViewportMetrics { + float device_pixel_ratio = 1.0; int32 physical_width; int32 physical_height; - float device_pixel_ratio = 1.0; - double padding_top; - double padding_right; - double padding_bottom; - double padding_left; + int32 physical_padding_top; + int32 physical_padding_right; + int32 physical_padding_bottom; + int32 physical_padding_left; }; struct ServicesData { diff --git a/sky/shell/platform/android/AndroidManifest.xml b/sky/shell/platform/android/AndroidManifest.xml index 6bf2fa8fa5..7b87b41fff 100644 --- a/sky/shell/platform/android/AndroidManifest.xml +++ b/sky/shell/platform/android/AndroidManifest.xml @@ -15,7 +15,8 @@ android:hardwareAccelerated="true" android:launchMode="standard" android:name="SkyActivity" - android:theme="@android:style/Theme.Black.NoTitleBar"> + android:theme="@android:style/Theme.Black.NoTitleBar" + android:windowSoftInputMode="adjustResize"> diff --git a/sky/shell/platform/android/org/domokit/sky/shell/PlatformViewAndroid.java b/sky/shell/platform/android/org/domokit/sky/shell/PlatformViewAndroid.java index 555b05ae28..d26106ef51 100644 --- a/sky/shell/platform/android/org/domokit/sky/shell/PlatformViewAndroid.java +++ b/sky/shell/platform/android/org/domokit/sky/shell/PlatformViewAndroid.java @@ -6,6 +6,7 @@ package org.domokit.sky.shell; import android.content.Context; import android.os.Build; +import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.Surface; @@ -14,6 +15,7 @@ import android.view.SurfaceView; import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.view.WindowInsets; import org.chromium.base.JNINamespace; import org.chromium.mojo.bindings.InterfaceRequest; @@ -51,47 +53,24 @@ public class PlatformViewAndroid extends SurfaceView { private SkyEngine.Proxy mSkyEngine; private PlatformServiceProvider mServiceProvider; private final SurfaceHolder.Callback mSurfaceCallback; - private final EdgeDims mPadding; + private final ViewportMetrics mMetrics; private final KeyboardServiceState mKeyboardState; private final RawKeyboardServiceState mRawKeyboardState; - /** - * Dimensions in each of the four cardinal directions. - */ - public static class EdgeDims { - public double top = 0.0; - public double right = 0.0; - public double bottom = 0.0; - public double left = 0.0; - } - - public PlatformViewAndroid(Context context, EdgeDims padding) { + public PlatformViewAndroid(Context context) { super(context); - mPadding = padding; + mMetrics = new ViewportMetrics(); + mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density; setFocusable(true); setFocusableInTouchMode(true); attach(); assert mNativePlatformView != 0; - final float density = context.getResources().getDisplayMetrics().density; - mSurfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - assert mSkyEngine != null; - ViewportMetrics metrics = new ViewportMetrics(); - metrics.physicalWidth = width; - metrics.physicalHeight = height; - metrics.devicePixelRatio = density; - if (mPadding != null) { - metrics.paddingTop = mPadding.top; - metrics.paddingRight = mPadding.right; - metrics.paddingBottom = mPadding.bottom; - metrics.paddingLeft = mPadding.left; - } - mSkyEngine.onViewportMetricsChanged(metrics); } @Override @@ -137,15 +116,6 @@ public class PlatformViewAndroid extends SurfaceView { mNativePlatformView = 0; } - @Override - protected void onWindowVisibilityChanged(int visibility) { - super.onWindowVisibilityChanged(visibility); - if (visibility == View.VISIBLE) { - requestFocusFromTouch(); - requestFocus(); - } - } - @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return mKeyboardState.createInputConnection(outAttrs); @@ -257,6 +227,24 @@ public class PlatformViewAndroid extends SurfaceView { return true; } + @Override + protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { + mMetrics.physicalWidth = width; + mMetrics.physicalHeight = height; + mSkyEngine.onViewportMetricsChanged(mMetrics); + super.onSizeChanged(width, height, oldWidth, oldHeight); + } + + @Override + public final WindowInsets onApplyWindowInsets(WindowInsets insets) { + mMetrics.physicalPaddingTop = insets.getSystemWindowInsetTop(); + mMetrics.physicalPaddingRight = insets.getSystemWindowInsetRight(); + mMetrics.physicalPaddingBottom = insets.getSystemWindowInsetBottom(); + mMetrics.physicalPaddingLeft = insets.getSystemWindowInsetLeft(); + mSkyEngine.onViewportMetricsChanged(mMetrics); + return super.onApplyWindowInsets(insets); + } + private void configureLocalServices(ServiceRegistry registry) { registry.register(KeyboardService.MANAGER.getName(), new ServiceFactory() { @Override diff --git a/sky/shell/platform/android/org/domokit/sky/shell/SkyActivity.java b/sky/shell/platform/android/org/domokit/sky/shell/SkyActivity.java index 1e04230bb3..a53306dcad 100644 --- a/sky/shell/platform/android/org/domokit/sky/shell/SkyActivity.java +++ b/sky/shell/platform/android/org/domokit/sky/shell/SkyActivity.java @@ -9,7 +9,9 @@ import android.content.Intent; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; +import android.util.Log; import android.view.View; +import android.view.Window; import android.view.WindowManager; import org.chromium.base.PathUtils; @@ -57,23 +59,18 @@ public class SkyActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - PlatformViewAndroid.EdgeDims edgeDims = new PlatformViewAndroid.EdgeDims(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - getWindow().setStatusBarColor(0x40000000); + Window window = getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(0x40000000); + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } - // TODO(abarth): We should get this value from the Android framework somehow. - edgeDims.top = 25.0; - // TODO(abarth): Unclear if we want to use fullscreen if we don't have - // a transparent system bar. - getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); String[] args = getArgsFromIntent(getIntent()); SkyMain.ensureInitialized(getApplicationContext(), args); - mView = new PlatformViewAndroid(this, edgeDims); + mView = new PlatformViewAndroid(this); ActivityImpl.setCurrentActivity(this); setContentView(mView); mTracingController = new TracingController(this); @@ -175,7 +172,7 @@ public class SkyActivity extends Activity { } public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); + super.onConfigurationChanged(newConfig); Locale locale = getResources().getConfiguration().locale; mView.getEngine().onLocaleChanged(locale.getLanguage(), diff --git a/sky/shell/platform/ios/sky_surface.mm b/sky/shell/platform/ios/sky_surface.mm index faf26d8250..504fae0e57 100644 --- a/sky/shell/platform/ios/sky_surface.mm +++ b/sky/shell/platform/ios/sky_surface.mm @@ -132,11 +132,11 @@ static std::string TracesBasePath() { CGFloat scale = [UIScreen mainScreen].scale; sky::ViewportMetricsPtr metrics = sky::ViewportMetrics::New(); + metrics->device_pixel_ratio = scale; metrics->physical_width = size.width * scale; metrics->physical_height = size.height * scale; - metrics->device_pixel_ratio = scale; - metrics->padding_top = - [UIApplication sharedApplication].statusBarFrame.size.height; + metrics->physical_padding_top = + [UIApplication sharedApplication].statusBarFrame.size.height * scale; _sky_engine->OnViewportMetricsChanged(metrics.Pass()); } diff --git a/sky/shell/ui/engine.cc b/sky/shell/ui/engine.cc index 79d3c22c23..3a0eb2e137 100644 --- a/sky/shell/ui/engine.cc +++ b/sky/shell/ui/engine.cc @@ -134,12 +134,12 @@ void Engine::SetServices(ServicesDataPtr services) { void Engine::OnViewportMetricsChanged(ViewportMetricsPtr metrics) { physical_size_.SetSize(metrics->physical_width, metrics->physical_height); - display_metrics_.physical_size = physical_size_; display_metrics_.device_pixel_ratio = metrics->device_pixel_ratio; - display_metrics_.padding_top = metrics->padding_top; - display_metrics_.padding_right = metrics->padding_right; - display_metrics_.padding_bottom = metrics->padding_bottom; - display_metrics_.padding_left = metrics->padding_left; + display_metrics_.physical_size = physical_size_; + display_metrics_.physical_padding_top = metrics->physical_padding_top; + display_metrics_.physical_padding_right = metrics->physical_padding_right; + display_metrics_.physical_padding_bottom = metrics->physical_padding_bottom; + display_metrics_.physical_padding_left = metrics->physical_padding_left; if (sky_view_) sky_view_->SetDisplayMetrics(display_metrics_); -- GitLab