Flutter Engine
The Flutter Engine
SingleViewWindowManager.java
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package io.flutter.plugin.platform;
6
7import static io.flutter.Build.API_LEVELS;
8
9import android.view.Display;
10import android.view.View;
11import android.view.ViewGroup;
12import android.view.WindowManager;
13import android.view.WindowMetrics;
14import androidx.annotation.NonNull;
15import androidx.annotation.RequiresApi;
16import io.flutter.Log;
17import java.util.concurrent.Executor;
18import java.util.function.Consumer;
19
20/**
21 * A static proxy handler for a WindowManager with custom overrides.
22 *
23 * <p>The presentation's window manager delegates all calls to the default window manager.
24 * WindowManager#addView calls triggered by views that are attached to the virtual display are
25 * crashing (see: https://github.com/flutter/flutter/issues/20714). This was triggered when
26 * selecting text in an embedded WebView (as the selection handles are implemented as popup
27 * windows).
28 *
29 * <p>This static proxy overrides the addView, removeView, removeViewImmediate, and updateViewLayout
30 * methods to prevent these crashes, and forwards all other calls to the delegate.
31 *
32 * <p>This is an abstract class because some clients of Flutter compile the Android embedding with
33 * the Android System SDK, which has additional abstract methods that need to be overriden.
34 */
35abstract class SingleViewWindowManager implements WindowManager {
36 private static final String TAG = "PlatformViewsController";
37
38 final WindowManager delegate;
40
42 WindowManager delegate, SingleViewFakeWindowViewGroup fakeWindowViewGroup) {
43 this.delegate = delegate;
44 fakeWindowRootView = fakeWindowViewGroup;
45 }
46
47 @Override
48 @Deprecated
49 public Display getDefaultDisplay() {
50 return delegate.getDefaultDisplay();
51 }
52
53 @Override
54 public void removeViewImmediate(View view) {
55 if (fakeWindowRootView == null) {
56 Log.w(TAG, "Embedded view called removeViewImmediate while detached from presentation");
57 return;
58 }
59 view.clearAnimation();
60 fakeWindowRootView.removeView(view);
61 }
62
63 @Override
64 public void addView(View view, ViewGroup.LayoutParams params) {
65 if (fakeWindowRootView == null) {
66 Log.w(TAG, "Embedded view called addView while detached from presentation");
67 return;
68 }
69 fakeWindowRootView.addView(view, params);
70 }
71
72 @Override
73 public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
74 if (fakeWindowRootView == null) {
75 Log.w(TAG, "Embedded view called updateViewLayout while detached from presentation");
76 return;
77 }
78 fakeWindowRootView.updateViewLayout(view, params);
79 }
80
81 @Override
82 public void removeView(View view) {
83 if (fakeWindowRootView == null) {
84 Log.w(TAG, "Embedded view called removeView while detached from presentation");
85 return;
86 }
87 fakeWindowRootView.removeView(view);
88 }
89
90 @RequiresApi(api = API_LEVELS.API_30)
91 @NonNull
92 @Override
93 public WindowMetrics getCurrentWindowMetrics() {
94 return delegate.getCurrentWindowMetrics();
95 }
96
97 @RequiresApi(api = API_LEVELS.API_30)
98 @NonNull
99 @Override
100 public WindowMetrics getMaximumWindowMetrics() {
101 return delegate.getMaximumWindowMetrics();
102 }
103
104 @RequiresApi(api = API_LEVELS.API_31)
105 @Override
106 public boolean isCrossWindowBlurEnabled() {
107 return delegate.isCrossWindowBlurEnabled();
108 }
109
110 @RequiresApi(api = API_LEVELS.API_31)
111 @Override
112 public void addCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) {
113 delegate.addCrossWindowBlurEnabledListener(listener);
114 }
115
116 @RequiresApi(api = API_LEVELS.API_31)
117 @Override
119 @NonNull Executor executor, @NonNull Consumer<Boolean> listener) {
120 delegate.addCrossWindowBlurEnabledListener(executor, listener);
121 }
122
123 @RequiresApi(api = API_LEVELS.API_31)
124 @Override
125 public void removeCrossWindowBlurEnabledListener(@NonNull Consumer<Boolean> listener) {
126 delegate.removeCrossWindowBlurEnabledListener(listener);
127 }
128}
static final int API_31
Definition: Build.java:21
static final int API_30
Definition: Build.java:20
static void w(@NonNull String tag, @NonNull String message)
Definition: Log.java:76
void addCrossWindowBlurEnabledListener(@NonNull Consumer< Boolean > listener)
void removeCrossWindowBlurEnabledListener(@NonNull Consumer< Boolean > listener)
void updateViewLayout(View view, ViewGroup.LayoutParams params)
void addView(View view, ViewGroup.LayoutParams params)
void addCrossWindowBlurEnabledListener( @NonNull Executor executor, @NonNull Consumer< Boolean > listener)
SingleViewWindowManager(WindowManager delegate, SingleViewFakeWindowViewGroup fakeWindowViewGroup)
const EmbeddedViewParams * params
#define TAG()