未验证 提交 2fab00eb 编写于 作者: A Amir Hardon 提交者: GitHub

Fix AlertDialogs built by platform views (#17511)

上级 bd760768
......@@ -9,6 +9,7 @@ import static android.content.Context.WINDOW_SERVICE;
import static android.view.View.OnFocusChangeListener;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Presentation;
import android.content.Context;
import android.content.ContextWrapper;
......@@ -102,6 +103,9 @@ class SingleViewPresentation extends Presentation {
private boolean startFocused = false;
// The context for the application window that hosts FlutterView.
private final Context outerContext;
/**
* Creates a presentation that will use the view factory to create a new platform view in the
* presentation's onCreate, and attach it.
......@@ -120,6 +124,7 @@ class SingleViewPresentation extends Presentation {
this.viewId = viewId;
this.createParams = createParams;
this.focusChangeListener = focusChangeListener;
this.outerContext = outerContext;
state = new PresentationState();
getWindow()
.setFlags(
......@@ -147,6 +152,7 @@ class SingleViewPresentation extends Presentation {
viewFactory = null;
this.state = state;
this.focusChangeListener = focusChangeListener;
this.outerContext = outerContext;
getWindow()
.setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
......@@ -173,7 +179,8 @@ class SingleViewPresentation extends Presentation {
// Our base mContext has already been wrapped with an IMM cache at instantiation time, but
// we want to wrap it again here to also return state.windowManagerHandler.
Context context = new PresentationContext(getContext(), state.windowManagerHandler);
Context context =
new PresentationContext(getContext(), state.windowManagerHandler, outerContext);
if (state.platformView == null) {
state.platformView = viewFactory.create(context, viewId, createParams);
......@@ -304,15 +311,34 @@ class SingleViewPresentation extends Presentation {
private static class PresentationContext extends ContextWrapper {
private @NonNull final WindowManagerHandler windowManagerHandler;
private @Nullable WindowManager windowManager;
private final Context flutterAppWindowContext;
PresentationContext(Context base, @NonNull WindowManagerHandler windowManagerHandler) {
PresentationContext(
Context base,
@NonNull WindowManagerHandler windowManagerHandler,
Context flutterAppWindowContext) {
super(base);
this.windowManagerHandler = windowManagerHandler;
this.flutterAppWindowContext = flutterAppWindowContext;
}
@Override
public Object getSystemService(String name) {
if (WINDOW_SERVICE.equals(name)) {
if (isCalledFromAlertDialog()) {
// Alert dialogs are showing on top of the entire application and should not be limited to
// the virtual
// display. If we detect that an android.app.AlertDialog constructor is what's fetching
// the window manager
// we return the one for the application's window.
//
// Note that if we don't do this AlertDialog will throw a ClassCastException as down the
// line it tries
// to case this instance to a WindowManagerImpl which the object returned by
// getWindowManager is not
// a subclass of.
return flutterAppWindowContext.getSystemService(name);
}
return getWindowManager();
}
return super.getSystemService(name);
......@@ -324,6 +350,17 @@ class SingleViewPresentation extends Presentation {
}
return windowManager;
}
private boolean isCalledFromAlertDialog() {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (int i = 0; i < stackTraceElements.length && i < 11; i++) {
if (stackTraceElements[i].getClassName().equals(AlertDialog.class.getCanonicalName())
&& stackTraceElements[i].getMethodName().equals("<init>")) {
return true;
}
}
return false;
}
}
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册