Merge "Keep insets stable when taskbar is destroyed/recreated" into sc-v2-dev
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index fcbea77..c80818a 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -24,6 +24,7 @@
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
@@ -35,6 +36,7 @@
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
+import android.graphics.Insets;
import android.hardware.SensorManager;
import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
@@ -43,6 +45,7 @@
import android.os.IBinder;
import android.util.Log;
import android.view.View;
+import android.view.WindowInsets;
import android.window.SplashScreen;
import androidx.annotation.Nullable;
@@ -639,4 +642,17 @@
mDepthController.dump(prefix, writer);
}
}
+
+ @Override
+ public void updateWindowInsets(WindowInsets.Builder updatedInsetsBuilder,
+ WindowInsets oldInsets) {
+ // Override the tappable insets to be 0 on the bottom for gesture nav (otherwise taskbar
+ // would count towards it). This is used for the bottom protection in All Apps for example.
+ if (SysUINavigationMode.getMode(this) == NO_BUTTON) {
+ Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
+ Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
+ oldTappableInsets.right, 0);
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
+ }
+ }
}
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index f26cfe8..28afc57 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -4,15 +4,20 @@
import android.annotation.TargetApi;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Canvas;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.view.ViewDebug;
import android.view.WindowInsets;
+import androidx.annotation.RequiresApi;
+
import com.android.launcher3.graphics.SysUiScrim;
import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.uioverrides.ApiWrapper;
import java.util.Collections;
import java.util.List;
@@ -61,12 +66,75 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- mTempRect.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
- insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+ if (Utilities.ATLEAST_R) {
+ insets = updateInsetsDueToTaskbar(insets);
+ Insets systemWindowInsets = insets.getInsetsIgnoringVisibility(
+ WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
+ mTempRect.set(systemWindowInsets.left, systemWindowInsets.top, systemWindowInsets.right,
+ systemWindowInsets.bottom);
+ } else {
+ mTempRect.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
+ insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+ }
handleSystemWindowInsets(mTempRect);
return insets;
}
+ /**
+ * Taskbar provides nav bar and tappable insets. However, taskbar is not attached immediately,
+ * and can be destroyed and recreated. Thus, instead of relying on taskbar being present to
+ * get its insets, we calculate them ourselves so they are stable regardless of whether taskbar
+ * is currently attached.
+ *
+ * TODO(b/198798034): Currently we always calculate nav insets as taskbarSize, but then we
+ * subtract nonOverlappingTaskbarInset in handleSystemWindowInsets(). Instead, we should just
+ * calculate the normal nav bar height here, and remove nonOverlappingTaskbarInset altogether.
+ *
+ * @param oldInsets The system-provided insets, which we are modifying.
+ * @return The updated insets.
+ */
+ @RequiresApi(api = Build.VERSION_CODES.R)
+ private WindowInsets updateInsetsDueToTaskbar(WindowInsets oldInsets) {
+ if (!ApiWrapper.TASKBAR_DRAWN_IN_PROCESS) {
+ // 3P launchers based on Launcher3 should still be inset like normal.
+ return oldInsets;
+ }
+
+ WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets);
+
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ Resources resources = getResources();
+
+ Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars());
+ Rect newNavInsets = new Rect(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right,
+ oldNavInsets.bottom);
+ if (dp.isTaskbarPresent) {
+ // TODO (see javadoc): Remove this block and fall into the next one instead.
+ newNavInsets.bottom = dp.taskbarSize;
+ } else if (dp.isLandscape) {
+ if (dp.isTablet) {
+ newNavInsets.bottom = ResourceUtils.getNavbarSize(
+ "navigation_bar_height_landscape", resources);
+ } else {
+ int navWidth = ResourceUtils.getNavbarSize("navigation_bar_width", resources);
+ if (dp.isSeascape()) {
+ newNavInsets.left = navWidth;
+ } else {
+ newNavInsets.right = navWidth;
+ }
+ }
+ } else {
+ newNavInsets.bottom = ResourceUtils.getNavbarSize("navigation_bar_height", resources);
+ }
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(newNavInsets));
+ updatedInsetsBuilder.setInsetsIgnoringVisibility(WindowInsets.Type.navigationBars(),
+ Insets.of(newNavInsets));
+
+ mActivity.updateWindowInsets(updatedInsetsBuilder, oldInsets);
+
+ return updatedInsetsBuilder.build();
+ }
+
@Override
public void setInsets(Rect insets) {
// If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 63fd9a0..a701548 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -426,8 +426,7 @@
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
if (Utilities.ATLEAST_Q) {
- mNavBarScrimHeight = insets.getTappableElementInsets().bottom
- - mLauncher.getDeviceProfile().nonOverlappingTaskbarInset;
+ mNavBarScrimHeight = insets.getTappableElementInsets().bottom;
} else {
mNavBarScrimHeight = insets.getStableInsetBottom();
}
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index 8a35cb3..7a23caa 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -17,11 +17,15 @@
import static com.android.launcher3.LauncherState.FLAG_NON_INTERACTIVE;
+import android.graphics.Insets;
+import android.os.Build;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.WindowInsets;
import androidx.annotation.CallSuper;
+import androidx.annotation.RequiresApi;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.LauncherRootView;
@@ -173,4 +177,12 @@
mHandler.removeCallbacks(mHandleDeferredResume);
Utilities.postAsyncCallback(mHandler, mHandleDeferredResume);
}
+
+ /**
+ * Gives subclasses a chance to override some window insets (via
+ * {@link android.view.WindowInsets.Builder#setInsets(int, Insets)}).
+ */
+ @RequiresApi(api = Build.VERSION_CODES.R)
+ public void updateWindowInsets(WindowInsets.Builder updatedInsetsBuilder,
+ WindowInsets oldInsets) { }
}