Merge changes I96b17c78,If4b09f5b into tm-dev am: e6a860a747 am: a5128e6b60
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17943634 Change-Id: Ic9a886c6d5f657a7589daa328b15c7e6cd82a372 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -65,6 +65,9 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
|
|||||||
public void onWindowFocusGained(boolean hasViewFocus) {
|
public void onWindowFocusGained(boolean hasViewFocus) {
|
||||||
super.onWindowFocusGained(hasViewFocus);
|
super.onWindowFocusGained(hasViewFocus);
|
||||||
getImm().registerImeConsumer(this);
|
getImm().registerImeConsumer(this);
|
||||||
|
if (isRequestedVisible() && getControl() == null) {
|
||||||
|
mIsRequestedVisibleAwaitingControl = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -149,14 +152,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setControl(@Nullable InsetsSourceControl control, int[] showTypes,
|
public boolean setControl(@Nullable InsetsSourceControl control, int[] showTypes,
|
||||||
int[] hideTypes) {
|
int[] hideTypes) {
|
||||||
super.setControl(control, showTypes, hideTypes);
|
if (!super.setControl(control, showTypes, hideTypes)) {
|
||||||
// TODO(b/204524304): clean-up how to deal with the timing issues of hiding IME:
|
return false;
|
||||||
// 1) Already requested show IME, in the meantime of WM callback the control but got null
|
}
|
||||||
// control when relayout comes first
|
|
||||||
// 2) Make sure no regression on some implicit request IME visibility calls (e.g.
|
|
||||||
// toggleSoftInput)
|
|
||||||
if (control == null && !mIsRequestedVisibleAwaitingControl) {
|
if (control == null && !mIsRequestedVisibleAwaitingControl) {
|
||||||
hide();
|
hide();
|
||||||
removeSurface();
|
removeSurface();
|
||||||
@@ -164,6 +164,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
|
|||||||
if (control != null) {
|
if (control != null) {
|
||||||
mIsRequestedVisibleAwaitingControl = false;
|
mIsRequestedVisibleAwaitingControl = false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -122,8 +122,9 @@ public class InsetsSourceConsumer {
|
|||||||
* animation should be run after setting the control.
|
* animation should be run after setting the control.
|
||||||
* @param hideTypes An integer array with a single entry that determines which types a hide
|
* @param hideTypes An integer array with a single entry that determines which types a hide
|
||||||
* animation should be run after setting the control.
|
* animation should be run after setting the control.
|
||||||
|
* @return Whether the control has changed from the server
|
||||||
*/
|
*/
|
||||||
public void setControl(@Nullable InsetsSourceControl control,
|
public boolean setControl(@Nullable InsetsSourceControl control,
|
||||||
@InsetsType int[] showTypes, @InsetsType int[] hideTypes) {
|
@InsetsType int[] showTypes, @InsetsType int[] hideTypes) {
|
||||||
if (mType == ITYPE_IME) {
|
if (mType == ITYPE_IME) {
|
||||||
ImeTracing.getInstance().triggerClientDump("InsetsSourceConsumer#setControl",
|
ImeTracing.getInstance().triggerClientDump("InsetsSourceConsumer#setControl",
|
||||||
@@ -134,7 +135,7 @@ public class InsetsSourceConsumer {
|
|||||||
mSourceControl.release(SurfaceControl::release);
|
mSourceControl.release(SurfaceControl::release);
|
||||||
mSourceControl = control;
|
mSourceControl = control;
|
||||||
}
|
}
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
SurfaceControl oldLeash = mSourceControl != null ? mSourceControl.getLeash() : null;
|
SurfaceControl oldLeash = mSourceControl != null ? mSourceControl.getLeash() : null;
|
||||||
|
|
||||||
@@ -201,6 +202,7 @@ public class InsetsSourceConsumer {
|
|||||||
if (lastControl != null) {
|
if (lastControl != null) {
|
||||||
lastControl.release(SurfaceControl::release);
|
lastControl.release(SurfaceControl::release);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
package com.android.server.wm.flicker.helpers
|
package com.android.server.wm.flicker.helpers
|
||||||
|
|
||||||
|
import android.view.WindowInsets.Type.ime
|
||||||
|
import android.view.WindowInsets.Type.navigationBars
|
||||||
|
import android.view.WindowInsets.Type.statusBars
|
||||||
|
|
||||||
import android.app.Instrumentation
|
import android.app.Instrumentation
|
||||||
import androidx.test.uiautomator.By
|
import androidx.test.uiautomator.By
|
||||||
import androidx.test.uiautomator.UiDevice
|
import androidx.test.uiautomator.UiDevice
|
||||||
@@ -25,6 +29,8 @@ import com.android.server.wm.traces.common.FlickerComponentName
|
|||||||
import com.android.server.wm.traces.parser.toFlickerComponent
|
import com.android.server.wm.traces.parser.toFlickerComponent
|
||||||
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
|
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
|
||||||
|
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
class ImeAppAutoFocusHelper @JvmOverloads constructor(
|
class ImeAppAutoFocusHelper @JvmOverloads constructor(
|
||||||
instr: Instrumentation,
|
instr: Instrumentation,
|
||||||
private val rotation: Int,
|
private val rotation: Int,
|
||||||
@@ -72,6 +78,7 @@ class ImeAppAutoFocusHelper @JvmOverloads constructor(
|
|||||||
wmHelper.waitForAppTransitionIdle()
|
wmHelper.waitForAppTransitionIdle()
|
||||||
wmHelper.waitForFullScreenApp(
|
wmHelper.waitForFullScreenApp(
|
||||||
ActivityOptions.DIALOG_THEMED_ACTIVITY_COMPONENT_NAME.toFlickerComponent())
|
ActivityOptions.DIALOG_THEMED_ACTIVITY_COMPONENT_NAME.toFlickerComponent())
|
||||||
|
mInstrumentation.waitForIdleSync()
|
||||||
}
|
}
|
||||||
fun dismissDialog(wmHelper: WindowManagerStateHelper) {
|
fun dismissDialog(wmHelper: WindowManagerStateHelper) {
|
||||||
val dialog = uiDevice.wait(
|
val dialog = uiDevice.wait(
|
||||||
@@ -83,4 +90,27 @@ class ImeAppAutoFocusHelper @JvmOverloads constructor(
|
|||||||
wmHelper.waitForAppTransitionIdle()
|
wmHelper.waitForAppTransitionIdle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun getInsetsVisibleFromDialog(type: Int): Boolean {
|
||||||
|
var insetsVisibilityTextView = uiDevice.wait(
|
||||||
|
Until.findObject(By.res("android:id/text1")), FIND_TIMEOUT)
|
||||||
|
if (insetsVisibilityTextView != null) {
|
||||||
|
var visibility = insetsVisibilityTextView.text.toString()
|
||||||
|
val matcher = when (type) {
|
||||||
|
ime() -> {
|
||||||
|
Pattern.compile("IME\\: (VISIBLE|INVISIBLE)").matcher(visibility)
|
||||||
|
}
|
||||||
|
statusBars() -> {
|
||||||
|
Pattern.compile("StatusBar\\: (VISIBLE|INVISIBLE)").matcher(visibility)
|
||||||
|
}
|
||||||
|
navigationBars() -> {
|
||||||
|
Pattern.compile("NavBar\\: (VISIBLE|INVISIBLE)").matcher(visibility)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
if (matcher != null && matcher.find()) {
|
||||||
|
return matcher.group(1).equals("VISIBLE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
package com.android.server.wm.flicker.ime
|
package com.android.server.wm.flicker.ime
|
||||||
|
|
||||||
|
import android.view.WindowInsets.Type.ime
|
||||||
|
import android.view.WindowInsets.Type.navigationBars
|
||||||
|
import android.view.WindowInsets.Type.statusBars
|
||||||
|
|
||||||
import android.app.Instrumentation
|
import android.app.Instrumentation
|
||||||
import android.platform.test.annotations.Presubmit
|
import android.platform.test.annotations.Presubmit
|
||||||
import android.view.Surface
|
import android.view.Surface
|
||||||
@@ -35,6 +39,8 @@ import org.junit.Test
|
|||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.MethodSorters
|
import org.junit.runners.MethodSorters
|
||||||
import org.junit.runners.Parameterized
|
import org.junit.runners.Parameterized
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test IME snapshot mechanism won't apply when transitioning from non-IME focused dialog activity.
|
* Test IME snapshot mechanism won't apply when transitioning from non-IME focused dialog activity.
|
||||||
@@ -56,6 +62,10 @@ class LaunchAppShowImeAndDialogThemeAppTest(private val testSpec: FlickerTestPar
|
|||||||
testApp.launchViaIntent(wmHelper)
|
testApp.launchViaIntent(wmHelper)
|
||||||
wmHelper.waitImeShown()
|
wmHelper.waitImeShown()
|
||||||
testApp.startDialogThemedActivity(wmHelper)
|
testApp.startDialogThemedActivity(wmHelper)
|
||||||
|
// Verify IME insets isn't visible on dialog since it's non-IME focusable window
|
||||||
|
assertFalse(testApp.getInsetsVisibleFromDialog(ime()))
|
||||||
|
assertTrue(testApp.getInsetsVisibleFromDialog(statusBars()))
|
||||||
|
assertTrue(testApp.getInsetsVisibleFromDialog(navigationBars()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
teardown {
|
teardown {
|
||||||
|
|||||||
@@ -17,11 +17,16 @@
|
|||||||
package com.android.server.wm.flicker.testapp;
|
package com.android.server.wm.flicker.testapp;
|
||||||
|
|
||||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
import static android.view.WindowInsets.Type.ime;
|
||||||
|
import static android.view.WindowInsets.Type.navigationBars;
|
||||||
|
import static android.view.WindowInsets.Type.statusBars;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
|
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
|
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
|
||||||
|
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
@@ -33,9 +38,12 @@ public class DialogThemedActivity extends Activity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_simple);
|
setContentView(R.layout.activity_simple);
|
||||||
|
getWindow().addFlags(FLAG_NOT_FOCUSABLE);
|
||||||
getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT);
|
getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT);
|
||||||
TextView textView = new TextView(this);
|
TextView textView = new TextView(this);
|
||||||
textView.setText("This is a test dialog");
|
// Print SystemBars' insets visibility on this window for demonstrating during the test.
|
||||||
|
textView.setId(android.R.id.text1);
|
||||||
|
textView.setText("Insets visibility\n\n");
|
||||||
textView.setTextColor(Color.BLACK);
|
textView.setTextColor(Color.BLACK);
|
||||||
LinearLayout layout = new LinearLayout(this);
|
LinearLayout layout = new LinearLayout(this);
|
||||||
layout.setBackgroundColor(Color.GREEN);
|
layout.setBackgroundColor(Color.GREEN);
|
||||||
@@ -51,7 +59,17 @@ public class DialogThemedActivity extends Activity {
|
|||||||
attrs.flags = FLAG_DIM_BEHIND | FLAG_ALT_FOCUSABLE_IM;
|
attrs.flags = FLAG_DIM_BEHIND | FLAG_ALT_FOCUSABLE_IM;
|
||||||
dialog.getWindow().getDecorView().setLayoutParams(attrs);
|
dialog.getWindow().getDecorView().setLayoutParams(attrs);
|
||||||
dialog.setCanceledOnTouchOutside(true);
|
dialog.setCanceledOnTouchOutside(true);
|
||||||
|
dialog.setOnShowListener(d -> textView.setText(textView.getText()
|
||||||
|
+ "IME: " + isInsetsVisible(dialog, ime()) + "\n"
|
||||||
|
+ "StatusBar: " + isInsetsVisible(dialog, statusBars()) + "\n"
|
||||||
|
+ "NavBar: " + isInsetsVisible(dialog, navigationBars()) + "\n")
|
||||||
|
);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
dialog.setOnDismissListener((d) -> finish());
|
dialog.setOnDismissListener((d) -> finish());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String isInsetsVisible(Dialog d, int type) {
|
||||||
|
return d.getWindow().getDecorView().getRootWindowInsets().isVisible(type) ? "VISIBLE"
|
||||||
|
: "INVISIBLE";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user