Revert "Reland "[Insets] Attach InsetObserver directly to ActivityWindowAndroid""
This reverts commit e1180f7d09784ccd680d8d02c64f0236bf208a08.
Reason for revert: Suspected cause for test failure, crbug.com/345372444
Original change's description:
> Reland "[Insets] Attach InsetObserver directly to ActivityWindowAndroid"
>
> This is a reland of commit 384890b3adf44d85a0dbedfc45b542c7bdca95eb
>
> PS1 is the original change.
>
> The main issue with the patchset is it introduced b/344959459. The root
> cause of the bug was holding RootView caused GC to fail for WebView. A
> fix was proposed here and has been folded into this CL.
> https://chromium-review.googlesource.com/c/chromium/src/+/5598361
>
> However, there is still the issue that we probably shouldn't create the
> InsetObserver for WebView in the first place so this CL also addresses
> that by lazily instantiating it only when needed.
>
> I'll land this and then reland the follow-up change after a day so we
> don't need to chain the reverts again.
>
> Original change's description:
> > [Insets] Attach InsetObserver directly to ActivityWindowAndroid
> >
> > Rework the lifecycle of InsetObserver to be tied to
> > ActivityWindowAndroid.
> >
> > Precursor to landing:
> > https://chromium-review.googlesource.com/c/chromium/src/+/5580959
> >
> > Bug: 343224210
> > Change-Id: I15fabd91e614fd690c31ddba8641da9720d073ed
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5589447
> > Reviewed-by: Theresa Sullivan <twellington@chromium.org>
> > Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
> > Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
> > Reviewed-by: Ted Choc <tedchoc@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#1309960}
>
> Include-Ci-Only-Tests: true
> Bug: 343224210
> Change-Id: I439e5d41187b50e75c014232c581597042108946
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5597547
> Reviewed-by: Theresa Sullivan <twellington@chromium.org>
> Reviewed-by: Bo Liu <boliu@chromium.org>
> Reviewed-by: Ted Choc <tedchoc@chromium.org>
> Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
> Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
> Cr-Commit-Position: refs/heads/main@{#1310765}
Bug: 343224210, 345372444
Change-Id: I747b94bd4b537d4c28f3936ccff2c4e6dbea133c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5602672
Auto-Submit: Benoit Lize <lizeb@chromium.org>
Owners-Override: Benoit Lize <lizeb@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Benoit Lize <lizeb@chromium.org>
Reviewed-by: Benoit Lize <lizeb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1311116}
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
index caf2f1b..a105a38 100644
--- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
+++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
@@ -95,6 +95,7 @@
import org.chromium.components.embedder_support.view.ContentView;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.ApplicationViewportInsetSupplier;
import org.chromium.ui.display.DisplayAndroid;
import org.chromium.ui.modelutil.PropertyModel;
@@ -330,7 +331,7 @@
mJniMocker.mock(ProfileJni.TEST_HOOKS, mProfileJniMock);
when(mProfileJniMock.fromWebContents(any())).thenReturn(mMockProfile);
- when(mMockWindow.getInsetObserver()).thenReturn(mInsetObserver);
+ InsetObserverSupplier.setInstanceForTesting(mInsetObserver);
simulateLayoutSizeChange(
2.f, 80, 128, /* keyboardShown= */ false, VirtualKeyboardMode.RESIZES_VISUAL);
Configuration config = new Configuration();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index f162544a..5a5e53ef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -2253,7 +2253,7 @@
new ObservableSupplierImpl<>(),
getIntentRequestTracker(),
getControlContainerHeightResource(),
- getWindowAndroid().getInsetObserver(),
+ mInsetObserverViewSupplier,
this::backShouldCloseTab,
getTabReparentingControllerSupplier(),
// TODO(sinansahin): This currently only checks for incognito extras in the intent.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 48aa8334..af4abc8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -231,6 +231,7 @@
import org.chromium.printing.PrintingController;
import org.chromium.printing.PrintingControllerImpl;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.UiUtils;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.ApplicationViewportInsetSupplier;
@@ -338,6 +339,8 @@
new ObservableSupplierImpl<>();
private ObservableSupplierImpl<LayoutManagerImpl> mLayoutManagerSupplier =
new ObservableSupplierImpl<>();
+ protected final UnownedUserDataSupplier<InsetObserver> mInsetObserverViewSupplier =
+ new InsetObserverSupplier();
private final ObservableSupplierImpl<ContextualSearchManager> mContextualSearchManagerSupplier =
new ObservableSupplierImpl<>();
@@ -489,6 +492,11 @@
// insets.
rootView.setFitsSystemWindows(false);
+ // Add an inset observer that stores the insets to access later.
+ // WebContents needs the insets to determine the portion of the screen obscured by
+ // non-content displaying things such as the OSK.
+ mInsetObserverViewSupplier.set(new InsetObserver(rootView));
+
if (BuildInfo.getInstance().isAutomotive
&& ChromeFeatureList.sVerticalAutomotiveBackButtonToolbar.isEnabled()) {
mBaseChromeLayout = new FrameLayout(this);
@@ -566,6 +574,7 @@
mTabModelSelectorSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
mTabCreatorManagerSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
mManualFillingComponentSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
+ mInsetObserverViewSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
mBrowserControlsManagerSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
// BrowserControlsManager is ready immediately.
mBrowserControlsManagerSupplier.set(
@@ -692,7 +701,7 @@
mBottomContainer = (BottomContainer) findViewById(R.id.bottom_container);
mSnackbarManager = new SnackbarManager(this, mBottomContainer, getWindowAndroid());
- getWindowAndroid().getInsetObserver().addObserver(mSnackbarManager);
+ mInsetObserverViewSupplier.get().addObserver(mSnackbarManager);
SnackbarManagerProvider.attach(getWindowAndroid(), mSnackbarManager);
// Make the activity listen to policy change events
@@ -1703,17 +1712,9 @@
mBottomContainer = null;
}
- WindowAndroid windowAndroid = getWindowAndroid();
- if (windowAndroid != null) {
- if (mDisplayAndroidObserver != null) {
- windowAndroid.getDisplay().removeObserver(mDisplayAndroidObserver);
- mDisplayAndroidObserver = null;
- }
-
- InsetObserver insetObserver = windowAndroid.getInsetObserver();
- if (insetObserver != null) {
- insetObserver.removeObserver(mSnackbarManager);
- }
+ if (mDisplayAndroidObserver != null) {
+ getWindowAndroid().getDisplay().removeObserver(mDisplayAndroidObserver);
+ mDisplayAndroidObserver = null;
}
if (mTextBubbleBackPressHandler != null) {
@@ -1736,6 +1737,10 @@
mStylusWritingCoordinator = null;
}
+ if (mInsetObserverViewSupplier.get() != null) {
+ mInsetObserverViewSupplier.get().removeObserver(mSnackbarManager);
+ }
+
// Destroy spare tab on activity destruction.
WarmupManager warmupManager = WarmupManager.getInstance();
warmupManager.destroySpareTab();
@@ -2167,7 +2172,7 @@
ApplicationViewportInsetSupplier insetSupplier =
getWindowAndroid().getApplicationBottomInsetSupplier();
insetSupplier.setKeyboardInsetSupplier(
- getWindowAndroid().getInsetObserver().getSupplierForKeyboardInset());
+ mInsetObserverViewSupplier.get().getSupplierForKeyboardInset());
insetSupplier.setKeyboardAccessoryInsetSupplier(
mManualFillingComponentSupplier.get().getBottomInsetSupplier());
compositorViewHolder.setApplicationViewportInsetSupplier(insetSupplier);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java
index 6e1c3cb..fa8db11 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java
@@ -23,6 +23,7 @@
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
/**
@@ -91,7 +92,7 @@
@Override
public InsetObserver getInsetObserverView() {
- return mTab.getWindowAndroid().getInsetObserver();
+ return InsetObserverSupplier.getValueOrNullFrom(mTab.getWindowAndroid());
}
@Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
index a7265f3c..f74ae0c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
@@ -34,6 +34,7 @@
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.supplier.OneShotCallback;
import org.chromium.base.supplier.OneshotSupplier;
+import org.chromium.base.supplier.UnownedUserDataSupplier;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton;
@@ -78,6 +79,8 @@
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.common.ContentUrlConstants;
+import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.ActivityKeyboardVisibilityDelegate;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.WindowDelegate;
@@ -233,6 +236,8 @@
private SnackbarManager mSnackbarManager;
private Tab mTab;
private final ObservableSupplierImpl<Profile> mProfileSupplier = new ObservableSupplierImpl<>();
+ protected final UnownedUserDataSupplier<InsetObserver> mInsetObserverViewSupplier =
+ new InsetObserverSupplier();
// SearchBoxDataProvider and LocationBarEmbedderUiOverrides are passed to several child
// components upon construction. Ensure we don't accidentally introduce disconnection by
@@ -282,6 +287,11 @@
// Setting fitsSystemWindows to false ensures that the root view doesn't consume the
// insets.
rootView.setFitsSystemWindows(false);
+ // Add an inset observer that stores the insets to access later.
+ // WebContents needs the insets to determine the portion of the screen obscured by
+ // non-content displaying things such as the OSK.
+ mInsetObserverViewSupplier.attach(getWindowAndroid().getUnownedUserDataHost());
+ mInsetObserverViewSupplier.set(new InsetObserver(rootView));
var contentView = createContentView();
setContentView(contentView);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
index 964fea7..fcc379f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -185,7 +185,7 @@
private CommerceSubscriptionsService mCommerceSubscriptionsService;
private UndoGroupSnackbarController mUndoGroupSnackbarController;
private final int mControlContainerHeightResource;
- private final InsetObserver mInsetObserver;
+ private final Supplier<InsetObserver> mInsetObserverViewSupplier;
private final Function<Tab, Boolean> mBackButtonShouldCloseTabFn;
private LayoutStateProvider.LayoutStateObserver mGestureNavLayoutObserver;
private final ObservableSupplierImpl<EphemeralTabCoordinator> mEphemeralTabCoordinatorSupplier;
@@ -275,7 +275,7 @@
* @param ephemeralTabCoordinatorSupplier Supplies the {@link EphemeralTabCoordinator}.
* @param intentRequestTracker Tracks intent requests.
* @param controlContainerHeightResource The resource for the control container.
- * @param insetObserver The {@link InsetObserver}.
+ * @param insetObserverViewSupplier Supplier for the {@link InsetObserver}.
* @param backButtonShouldCloseTabFn Function which supplies whether or not the back button
* should close the tab.
* @param tabReparentingControllerSupplier Supplier for the {@link TabReparentingController}.
@@ -330,7 +330,7 @@
ObservableSupplierImpl<EphemeralTabCoordinator> ephemeralTabCoordinatorSupplier,
@NonNull IntentRequestTracker intentRequestTracker,
int controlContainerHeightResource,
- @NonNull InsetObserver insetObserver,
+ @NonNull Supplier<InsetObserver> insetObserverViewSupplier,
@NonNull Function<Tab, Boolean> backButtonShouldCloseTabFn,
OneshotSupplier<TabReparentingController> tabReparentingControllerSupplier,
boolean initializeUiWithIncognitoColors,
@@ -385,7 +385,7 @@
overviewColorSupplier,
baseChromeLayout);
mControlContainerHeightResource = controlContainerHeightResource;
- mInsetObserver = insetObserver;
+ mInsetObserverViewSupplier = insetObserverViewSupplier;
mBackButtonShouldCloseTabFn = backButtonShouldCloseTabFn;
mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier;
mCanAnimateBrowserControls =
@@ -533,7 +533,7 @@
mContextualSearchManagerSupplier,
getBottomSheetController(),
mToolbarManager.getLocationBar().getOmniboxSuggestionsVisualState(),
- mInsetObserver);
+ mInsetObserverViewSupplier.get());
}
@Override
@@ -603,7 +603,7 @@
mCallbackController.makeCancelable(
() -> mLayoutManager.getActiveLayout().requestUpdate()),
mActivityTabProvider,
- mInsetObserver,
+ mInsetObserverViewSupplier.get(),
mStartSurfaceSupplier,
new BackActionDelegate() {
@Override
@@ -1232,7 +1232,7 @@
mActivity,
mActivity.getWindow().getDecorView().getRootView(),
mBrowserControlsManager.getBrowserVisibilityDelegate(),
- mInsetObserver,
+ mInsetObserverViewSupplier.get(),
mActivityLifecycleDispatcher,
savedInstanceState);
}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java
index 56be3e9..4417a3b 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java
@@ -39,6 +39,7 @@
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
import java.lang.ref.WeakReference;
@@ -81,8 +82,8 @@
when(mTab.getUserDataHost()).thenReturn(mTabDataHost);
when(mWebContents.isFullscreenForCurrentTab()).thenReturn(true);
when(mWindowAndroid.getActivity()).thenReturn(mActivityRef);
- when(mWindowAndroid.getInsetObserver()).thenReturn(mInsetObserver);
+ InsetObserverSupplier.setInstanceForTesting(mInsetObserver);
ActivityDisplayCutoutModeSupplier.setInstanceForTesting(0);
mDisplayCutoutTabHelper = spy(new DisplayCutoutTabHelper(mTab));
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
index 364f437f..cceb631a 100644
--- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
+++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
@@ -60,6 +60,7 @@
import org.chromium.content_public.browser.GlobalRenderFrameHostId;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.url.GURL;
@@ -628,7 +629,8 @@
}
};
- InsetObserver insetObserver = mActivityWindowAndroid.getInsetObserver();
+ InsetObserver insetObserver =
+ InsetObserverSupplier.getValueOrNullFrom(mActivityWindowAndroid);
if (insetObserver != null) {
insetObserver.addObserver(this);
}
@@ -967,7 +969,8 @@
resetCurrentPlayback();
mStateToRestoreOnBringingToForeground = null;
ReadAloudFeatures.shutdown();
- InsetObserver insetObserver = mActivityWindowAndroid.getInsetObserver();
+ InsetObserver insetObserver =
+ InsetObserverSupplier.getValueOrNullFrom(mActivityWindowAndroid);
if (insetObserver != null) {
insetObserver.removeObserver(this);
}
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
index 112f1e0..f706349 100644
--- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
+++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
@@ -31,6 +31,7 @@
import org.chromium.content_public.browser.WebContentsObserver.ViewportFitType;
import org.chromium.ui.InsetObserver;
import org.chromium.ui.InsetObserver.WindowInsetsConsumer;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
/**
@@ -120,7 +121,7 @@
TotallyEdgeToEdge.isEnabled()
? new TotallyEdgeToEdge(browserControlsStateProvider, this::maybeDrawToEdge)
: null;
- mInsetObserver = mWindowAndroid.getInsetObserver();
+ mInsetObserver = InsetObserverSupplier.getValueOrNullFrom(mWindowAndroid);
mBrowserControlsStateProvider = browserControlsStateProvider;
mBrowserControlsStateProvider.addObserver(this);
}
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java
index 10a1de8..9133b3e9 100644
--- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java
+++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java
@@ -64,6 +64,7 @@
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.ui.InsetObserver;
import org.chromium.ui.InsetObserver.WindowInsetsConsumer;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
/**
@@ -125,7 +126,7 @@
ChromeFeatureList.sDrawWebEdgeToEdge.setForTesting(false);
MockitoAnnotations.openMocks(this);
- when(mWindowAndroid.getInsetObserver()).thenReturn(mInsetObserver);
+ InsetObserverSupplier.setInstanceForTesting(mInsetObserver);
mActivity = Robolectric.buildActivity(AppCompatActivity.class).setup().get();
mTabProvider = new ObservableSupplierImpl<>();
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java
index 895aace..6ed6c0a 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java
@@ -15,6 +15,7 @@
import org.chromium.ui.InsetObserver;
import org.chromium.ui.InsetObserver.WindowInsetsAnimationListener;
import org.chromium.ui.InsetObserver.WindowInsetsConsumer;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
import java.util.List;
@@ -50,7 +51,7 @@
* window insets and listening for IME animation updates.
*/
public void attach(WindowAndroid windowAndroid) {
- InsetObserver insetObserver = windowAndroid.getInsetObserver();
+ InsetObserver insetObserver = InsetObserverSupplier.getValueOrNullFrom(windowAndroid);
assert insetObserver != null
: "DeferredIMEWindowInsetApplicationCallback can only be used in activities with an"
+ " InsetObserverView";
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java
index e97ace19..e8b30164 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java
@@ -8,7 +8,6 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.view.View;
@@ -26,6 +25,7 @@
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
/** Unit tests for {@link DeferredIMEWindowInsetApplicationCallback}. */
@@ -44,11 +44,11 @@
@Mock private Runnable mUpdateRunnable;
@Mock private WindowAndroid mWindowAndroid;
@Mock private View mView;
- @Mock private InsetObserver mInsetObserver;
+ @Mock InsetObserver mInsetObserver;
@Before
public void setUp() {
- when(mWindowAndroid.getInsetObserver()).thenReturn(mInsetObserver);
+ InsetObserverSupplier.setInstanceForTesting(mInsetObserver);
mAnimation = new WindowInsetsAnimationCompat(WindowInsetsCompat.Type.ime(), null, 160);
mAnimation2 = new WindowInsetsAnimationCompat(WindowInsetsCompat.Type.ime(), null, 160);
mCallback = new DeferredIMEWindowInsetApplicationCallback(mUpdateRunnable);
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestionsDropdownEmbedderImplTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestionsDropdownEmbedderImplTest.java
index 04bc53f7..486be240 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestionsDropdownEmbedderImplTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestionsDropdownEmbedderImplTest.java
@@ -33,6 +33,7 @@
import org.chromium.chrome.browser.omnibox.styles.OmniboxResourceProvider;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionsDropdownEmbedder.OmniboxAlignment;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.display.DisplayAndroid;
@@ -78,7 +79,7 @@
@Before
public void setUp() {
mContextWeakRef = new WeakReference<>(ContextUtils.getApplicationContext());
- doReturn(mInsetObserver).when(mWindowAndroid).getInsetObserver();
+ InsetObserverSupplier.setInstanceForTesting(mInsetObserver);
doReturn(mContextWeakRef).when(mWindowAndroid).getContext();
doReturn(mContextWeakRef.get()).when(mAnchorView).getContext();
doReturn(mViewTreeObserver).when(mAnchorView).getViewTreeObserver();
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java
index c7ae299..26abcc3 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java
@@ -90,6 +90,7 @@
import org.chromium.components.omnibox.suggestions.OmniboxSuggestionUiType;
import org.chromium.content_public.browser.NavigationHandle;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.modaldialog.ModalDialogManager;
import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
@@ -195,7 +196,7 @@
mListModel.set(SuggestionListProperties.SUGGESTION_MODELS, mSuggestionModels);
mTabWindowManagerSupplier = new ObservableSupplierImpl<>();
- doReturn(mInsetObserver).when(mWindowAndroid).getInsetObserver();
+ InsetObserverSupplier.setInstanceForTesting(mInsetObserver);
mMediator =
new AutocompleteMediator(
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriver.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriver.java
index 8a2d511..2d9e5c1 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriver.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriver.java
@@ -11,6 +11,7 @@
import org.chromium.base.supplier.Supplier;
import org.chromium.ui.InsetObserver;
import org.chromium.ui.InsetObserver.WindowInsetsAnimationListener;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.modelutil.PropertyModel;
@@ -56,7 +57,7 @@
void onOmniboxSessionStateChange(boolean active) {
if (active) {
- InsetObserver insetObserver = mWindowAndroid.getInsetObserver();
+ InsetObserver insetObserver = InsetObserverSupplier.getValueOrNullFrom(mWindowAndroid);
insetObserver.addWindowInsetsAnimationListener(this);
} else {
removeInsetListener();
@@ -64,7 +65,7 @@
}
private void removeInsetListener() {
- InsetObserver insetObserver = mWindowAndroid.getInsetObserver();
+ InsetObserver insetObserver = InsetObserverSupplier.getValueOrNullFrom(mWindowAndroid);
insetObserver.removeWindowInsetsAnimationListener(this);
}
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriverTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriverTest.java
index 2d011e6..2a7169d 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriverTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionsListAnimationDriverTest.java
@@ -7,7 +7,6 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import androidx.core.view.WindowInsetsAnimationCompat;
import androidx.core.view.WindowInsetsCompat;
@@ -23,6 +22,7 @@
import org.chromium.base.MathUtils;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.ui.InsetObserver;
+import org.chromium.ui.InsetObserverSupplier;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.modelutil.PropertyModel;
@@ -47,7 +47,7 @@
@Before
public void setUp() {
mTranslation = 0.0f;
- when(mWindowAndroid.getInsetObserver()).thenReturn(mInsetObserver);
+ InsetObserverSupplier.setInstanceForTesting(mInsetObserver);
mImeAnimation = new WindowInsetsAnimationCompat(WindowInsetsCompat.Type.ime(), null, 160);
mNonImeAnimation =
new WindowInsetsAnimationCompat(WindowInsetsCompat.Type.statusBars(), null, 160);
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index af718c1..e287512 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -282,6 +282,7 @@
"java/src/org/chromium/ui/ElidedUrlTextView.java",
"java/src/org/chromium/ui/HorizontalListDividerDrawable.java",
"java/src/org/chromium/ui/InsetObserver.java",
+ "java/src/org/chromium/ui/InsetObserverSupplier.java",
"java/src/org/chromium/ui/InsetsRectProvider.java",
"java/src/org/chromium/ui/LayoutInflaterUtils.java",
"java/src/org/chromium/ui/OverscrollRefreshHandler.java",
diff --git a/ui/android/java/src/org/chromium/ui/InsetObserver.java b/ui/android/java/src/org/chromium/ui/InsetObserver.java
index e1bad0e8..baed1ca 100644
--- a/ui/android/java/src/org/chromium/ui/InsetObserver.java
+++ b/ui/android/java/src/org/chromium/ui/InsetObserver.java
@@ -21,7 +21,6 @@
import org.chromium.base.ResettersForTesting;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.supplier.ObservableSupplierImpl;
-import org.chromium.ui.base.ImmutableWeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -40,7 +39,7 @@
private final ObserverList<WindowInsetsAnimationListener> mWindowInsetsAnimationListeners =
new ObserverList<>();
private final List<WindowInsetsConsumer> mInsetsConsumers = new ArrayList<>();
- private final ImmutableWeakReference<View> mRootViewReference;
+ private final View mRootView;
// Insets to be added to the current safe area.
private int mBottomInsetsForEdgeToEdge;
private final Rect mDisplayCutoutRect;
@@ -111,10 +110,10 @@
/**
* Creates an instance of {@link InsetObserver}.
*
- * @param rootViewWeakRef A weak reference to the root view of the app.
+ * @param rootView The root view of the app.
*/
- public InsetObserver(ImmutableWeakReference<View> rootViewWeakRef) {
- mRootViewReference = rootViewWeakRef;
+ public InsetObserver(View rootView) {
+ mRootView = rootView;
mWindowInsets = new Rect();
mCurrentSafeArea = new Rect();
mDisplayCutoutRect = new Rect();
@@ -168,13 +167,10 @@
}
};
- View rootView = getRootView();
- if (rootView == null) return;
-
// Populate the root window insets if available.
- if (rootView.getRootWindowInsets() != null) {
+ if (mRootView.getRootWindowInsets() != null) {
mLastSeenRawWindowInset =
- WindowInsetsCompat.toWindowInsetsCompat(rootView.getRootWindowInsets());
+ WindowInsetsCompat.toWindowInsetsCompat(mRootView.getRootWindowInsets());
} else if (sInitialRawWindowInsetsForTesting != null) {
mLastSeenRawWindowInset = sInitialRawWindowInsetsForTesting;
}
@@ -283,11 +279,7 @@
}
private void updateKeyboardInset() {
- View rootView = mRootViewReference.get();
- if (rootView == null) return;
-
- int keyboardInset = KeyboardUtils.calculateKeyboardHeightFromWindowInsets(rootView);
-
+ int keyboardInset = KeyboardUtils.calculateKeyboardHeightFromWindowInsets(mRootView);
if (mKeyboardInset == keyboardInset) {
return;
}
@@ -300,11 +292,8 @@
}
private WindowInsetsCompat forwardToInsetConsumers(WindowInsetsCompat insets) {
- View rootView = mRootViewReference.get();
- if (rootView == null) return insets;
-
for (WindowInsetsConsumer consumer : mInsetsConsumers) {
- insets = consumer.onApplyWindowInsets(rootView, insets);
+ insets = consumer.onApplyWindowInsets(mRootView, insets);
}
return insets;
}
@@ -363,8 +352,4 @@
sInitialRawWindowInsetsForTesting = windowInsets;
ResettersForTesting.register(() -> sInitialRawWindowInsetsForTesting = null);
}
-
- private View getRootView() {
- return mRootViewReference.get();
- }
}
diff --git a/ui/android/java/src/org/chromium/ui/InsetObserverSupplier.java b/ui/android/java/src/org/chromium/ui/InsetObserverSupplier.java
new file mode 100644
index 0000000..c928b19
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/InsetObserverSupplier.java
@@ -0,0 +1,50 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.ui;
+
+import androidx.annotation.Nullable;
+
+import org.chromium.base.UnownedUserDataKey;
+import org.chromium.base.supplier.ObservableSupplier;
+import org.chromium.base.supplier.ObservableSupplierImpl;
+import org.chromium.base.supplier.UnownedUserDataSupplier;
+import org.chromium.ui.base.WindowAndroid;
+
+/**
+ * A {@link UnownedUserDataSupplier} which manages the supplier and UnownedUserData for a {@link
+ * InsetObserver}.
+ */
+public class InsetObserverSupplier extends UnownedUserDataSupplier<InsetObserver> {
+ private static final UnownedUserDataKey<InsetObserverSupplier> KEY =
+ new UnownedUserDataKey<>(InsetObserverSupplier.class);
+ private static ObservableSupplierImpl<InsetObserver> sInstanceForTesting;
+
+ /** Returns {@link InsetObserver} supplier associated with the given {@link WindowAndroid}. */
+ public static ObservableSupplier<InsetObserver> from(@Nullable WindowAndroid windowAndroid) {
+ if (windowAndroid == null) return null;
+ if (sInstanceForTesting != null) return sInstanceForTesting;
+ return KEY.retrieveDataFromHost(windowAndroid.getUnownedUserDataHost());
+ }
+
+ /** Retrieves a {@link InsetObserver} from {@link WindowAndroid}. */
+ public static @Nullable InsetObserver getValueOrNullFrom(
+ @Nullable WindowAndroid windowAndroid) {
+ ObservableSupplier<InsetObserver> supplier = from(windowAndroid);
+ return supplier == null ? null : supplier.get();
+ }
+
+ /** Sets an instance for testing. */
+ public static void setInstanceForTesting(InsetObserver insetObserver) {
+ if (sInstanceForTesting == null) {
+ sInstanceForTesting = new ObservableSupplierImpl<>();
+ }
+ sInstanceForTesting.set(insetObserver);
+ }
+
+ /** Constructor. */
+ public InsetObserverSupplier() {
+ super(KEY);
+ }
+}
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index e9770ab..6226216 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -45,7 +45,6 @@
import org.chromium.base.UnownedUserDataHost;
import org.chromium.base.compat.ApiHelperForO;
import org.chromium.base.compat.ApiHelperForOMR1;
-import org.chromium.ui.InsetObserver;
import org.chromium.ui.KeyboardVisibilityDelegate;
import org.chromium.ui.display.DisplayAndroid;
import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver;
@@ -77,8 +76,6 @@
private KeyboardVisibilityDelegate mKeyboardVisibilityDelegate =
KeyboardVisibilityDelegate.getInstance();
- private InsetObserver mInsetObserver;
-
// Native pointer to the c++ WindowAndroid object.
private long mNativeWindowAndroid;
private final DisplayAndroid mDisplayAndroid;
@@ -702,41 +699,25 @@
mAnimationPlaceholderView = view;
}
- protected void setKeyboardDelegate(KeyboardVisibilityDelegate keyboardDelegate) {
- mKeyboardVisibilityDelegate = keyboardDelegate;
- // TODO(crbug.com/343936788): Remove - callers should use the window to get the delegate.
- KeyboardVisibilityDelegate.setInstance(keyboardDelegate);
- }
-
/**
* The returned {@link KeyboardVisibilityDelegate} can read and influence the soft keyboard.
- *
* @return a {@link KeyboardVisibilityDelegate} specific for this window.
*/
public KeyboardVisibilityDelegate getKeyboardDelegate() {
return mKeyboardVisibilityDelegate;
}
- /** Returns the {@link InsetObserver} for the root view of the activity or null. */
- public InsetObserver getInsetObserver() {
- if (mInsetObserver == null) {
- Window window = getWindow();
- if (window == null) return null;
-
- mInsetObserver =
- new InsetObserver(
- new ImmutableWeakReference<>(window.getDecorView().getRootView()));
- }
- return mInsetObserver;
- }
-
- /**
- * @return A mechanism for updating and observing the bottom inset of the browser window.
- */
+ /** @return A mechanism for updating and observing the bottom inset of the browser window. */
public ApplicationViewportInsetSupplier getApplicationBottomInsetSupplier() {
return mApplicationBottomInsetSupplier;
}
+ public void setKeyboardDelegate(KeyboardVisibilityDelegate keyboardDelegate) {
+ mKeyboardVisibilityDelegate = keyboardDelegate;
+ // TODO(crbug.com/343936788): Remove - callers should use the window to get the delegate.
+ KeyboardVisibilityDelegate.setInstance(keyboardDelegate);
+ }
+
/** Adds a listener that will be notified whenever a ContextMenu is closed. */
public void addContextMenuCloseListener(OnCloseContextMenuListener listener) {
mContextMenuCloseListeners.addObserver(listener);
diff --git a/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java b/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java
index f94d904..052f5d843 100644
--- a/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java
+++ b/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java
@@ -16,7 +16,6 @@
import android.graphics.Rect;
import android.os.Build;
import android.os.Build.VERSION_CODES;
-import android.view.View;
import android.view.WindowInsets;
import android.widget.LinearLayout;
@@ -38,7 +37,6 @@
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.ui.InsetObserver.WindowInsetsAnimationListener;
import org.chromium.ui.InsetObserver.WindowInsetsConsumer;
-import org.chromium.ui.base.ImmutableWeakReference;
import java.util.Collections;
@@ -100,7 +98,7 @@
.when(mModifiedInsets)
.getInsets(WindowInsetsCompat.Type.systemBars());
- mInsetObserver = new InsetObserver(new ImmutableWeakReference<View>(mContentView));
+ mInsetObserver = new InsetObserver(mContentView);
mInsetObserver.addObserver(mObserver);
}
@@ -267,7 +265,7 @@
@Config(sdk = VERSION_CODES.R)
public void initializeWithLastSeenRawWindowInsets() {
doReturn(mNonCompatInsets).when(mContentView).getRootWindowInsets();
- mInsetObserver = new InsetObserver(new ImmutableWeakReference<View>(mContentView));
+ mInsetObserver = new InsetObserver(mContentView);
assertEquals(
"WindowInsets is different.",
WindowInsetsCompat.toWindowInsetsCompat(mNonCompatInsets),