Files
lawnchair/src/com/android/launcher3/LauncherRootView.java
Alex Chau 579a785144 Reapply insets normalization on configuration changes
- When going from an app to Overview after deivce is rotated, sometimes the Configuration associated with Launcher activity have old information (dimension from preious rotation), causing LauncherRootView.onApplyWindowInsets to store wrong insets from WindowManagerProxy.normalizeWindowInsets
- The fix is when LaucnehrRootView.dispatchInsets is called, reapply insets by calling onApplyWindowInsets again to get updated normalized insets.

Fix: 323105140
Test: Launch an app, rotate to landscape, tap Recents button to go to Overview
Flag: EXEMPT BUG_FIX
Change-Id: I8e641a2702670d1364ee5a0f10a1b3c8d1a2b324
2024-12-03 19:03:28 +00:00

147 lines
4.7 KiB
Java

package com.android.launcher3;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.ViewDebug;
import android.view.WindowInsets;
import com.android.launcher3.graphics.SysUiScrim;
import com.android.launcher3.statemanager.StatefulContainer;
import com.android.launcher3.util.window.WindowManagerProxy;
import java.util.Collections;
import java.util.List;
public class LauncherRootView extends InsettableFrameLayout {
private final Rect mTempRect = new Rect();
private final StatefulContainer mStatefulContainer;
@ViewDebug.ExportedProperty(category = "launcher")
private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
Collections.singletonList(new Rect());
private WindowStateListener mWindowStateListener;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mDisallowBackGesture;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mForceHideBackArrow;
private final SysUiScrim mSysUiScrim;
public LauncherRootView(Context context, AttributeSet attrs) {
super(context, attrs);
mStatefulContainer = StatefulContainer.fromContext(context);
mSysUiScrim = new SysUiScrim(this);
}
private void handleSystemWindowInsets(Rect insets) {
// Update device profile before notifying the children.
mStatefulContainer.getDeviceProfile().updateInsets(insets);
boolean resetState = !insets.equals(mInsets);
setInsets(insets);
if (resetState) {
mStatefulContainer.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
}
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
mStatefulContainer.handleConfigurationChanged(
mStatefulContainer.getContext().getResources().getConfiguration());
return updateInsets(insets);
}
private WindowInsets updateInsets(WindowInsets insets) {
insets = WindowManagerProxy.INSTANCE.get(getContext())
.normalizeWindowInsets(getContext(), insets, mTempRect);
handleSystemWindowInsets(mTempRect);
return insets;
}
@Override
public void setInsets(Rect insets) {
// If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
// modifying child layout params.
if (!insets.equals(mInsets)) {
super.setInsets(insets);
mSysUiScrim.onInsetsChanged(insets);
}
}
public void dispatchInsets() {
if (isAttachedToWindow()) {
updateInsets(getRootWindowInsets());
} else {
mStatefulContainer.getDeviceProfile().updateInsets(mInsets);
}
super.setInsets(mInsets);
}
public void setWindowStateListener(WindowStateListener listener) {
mWindowStateListener = listener;
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (mWindowStateListener != null) {
mWindowStateListener.onWindowFocusChanged(hasWindowFocus);
}
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (mWindowStateListener != null) {
mWindowStateListener.onWindowVisibilityChanged(visibility);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
mSysUiScrim.draw(canvas);
super.dispatchDraw(canvas);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(l, t, r, b);
setDisallowBackGesture(mDisallowBackGesture);
mSysUiScrim.setSize(r - l, b - t);
}
public void setForceHideBackArrow(boolean forceHideBackArrow) {
this.mForceHideBackArrow = forceHideBackArrow;
setDisallowBackGesture(mDisallowBackGesture);
}
public void setDisallowBackGesture(boolean disallowBackGesture) {
if (SEPARATE_RECENTS_ACTIVITY.get()) {
return;
}
mDisallowBackGesture = disallowBackGesture;
setSystemGestureExclusionRects((mForceHideBackArrow || mDisallowBackGesture)
? SYSTEM_GESTURE_EXCLUSION_RECT
: Collections.emptyList());
}
public SysUiScrim getSysUiScrim() {
return mSysUiScrim;
}
public interface WindowStateListener {
void onWindowFocusChanged(boolean hasFocus);
void onWindowVisibilityChanged(int visibility);
}
}