Merge "Add support for taskbar phone 3 button seascape" into udc-qpr-dev am: ea12af617e

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/23623277

Change-Id: I884e7f794448ec2f74cceb9e45be7ca12a9e718c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Vinit Nayak
2023-07-07 00:18:29 +00:00
committed by Automerger Merge Worker
13 changed files with 298 additions and 107 deletions
@@ -88,6 +88,7 @@ import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory; import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory;
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter; import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter;
import com.android.launcher3.util.DimensionUtils; import com.android.launcher3.util.DimensionUtils;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.TouchController; import com.android.launcher3.util.TouchController;
@@ -197,6 +198,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
this::onComputeInsetsForSeparateWindow; this::onComputeInsetsForSeparateWindow;
private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender(); private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender();
private ImageView mRecentsButton; private ImageView mRecentsButton;
private DisplayController mDisplayController;
public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) { public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) {
mContext = context; mContext = context;
@@ -226,6 +228,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
TaskbarManager.isPhoneMode(deviceProfile)); TaskbarManager.isPhoneMode(deviceProfile));
mNavButtonsView.getLayoutParams().height = p.y; mNavButtonsView.getLayoutParams().height = p.y;
mDisplayController = DisplayController.INSTANCE.get(mContext);
mIsImeRenderingNavButtons = mIsImeRenderingNavButtons =
InputMethodService.canImeRenderGesturalNavButtons() && mContext.imeDrawsImeNavBar(); InputMethodService.canImeRenderGesturalNavButtons() && mContext.imeDrawsImeNavBar();
if (!mIsImeRenderingNavButtons) { if (!mIsImeRenderingNavButtons) {
@@ -727,14 +731,10 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
boolean isInKidsMode = mContext.isNavBarKidsModeActive(); boolean isInKidsMode = mContext.isNavBarKidsModeActive();
if (TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) { if (TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) {
if (!isThreeButtonNav) {
return;
}
NavButtonLayoutter navButtonLayoutter = NavButtonLayoutter navButtonLayoutter =
NavButtonLayoutFactory.Companion.getUiLayoutter( NavButtonLayoutFactory.Companion.getUiLayoutter(
dp, mNavButtonsView, res, isInKidsMode, isInSetup, isThreeButtonNav, dp, mNavButtonsView, res, isInKidsMode, isInSetup, isThreeButtonNav,
TaskbarManager.isPhoneMode(dp)); TaskbarManager.isPhoneMode(dp), mDisplayController.getInfo().rotation);
navButtonLayoutter.layoutButtons(dp, isContextualButtonShowing()); navButtonLayoutter.layoutButtons(dp, isContextualButtonShowing());
return; return;
} }
@@ -55,6 +55,7 @@ import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.Gravity; import android.view.Gravity;
import android.view.RoundedCorner; import android.view.RoundedCorner;
import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@@ -295,8 +296,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
public void init(@NonNull TaskbarSharedState sharedState) { public void init(@NonNull TaskbarSharedState sharedState) {
mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight(); mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight();
mWindowLayoutParams = mWindowLayoutParams = createAllWindowParams();
createDefaultWindowLayoutParams(TYPE_NAVIGATION_BAR_PANEL, WINDOW_TITLE);
// Initialize controllers after all are constructed. // Initialize controllers after all are constructed.
mControllers.init(sharedState); mControllers.init(sharedState);
@@ -360,11 +360,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
* @param title The window title to pass to the created WindowManager.LayoutParams. * @param title The window title to pass to the created WindowManager.LayoutParams.
*/ */
public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type, String title) { public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type, String title) {
DeviceProfile deviceProfile = getDeviceProfile();
// Taskbar is on the logical bottom of the screen
boolean isVerticalBarLayout = TaskbarManager.isPhoneButtonNavMode(this) &&
deviceProfile.isLandscape;
int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SLIPPERY | WindowManager.LayoutParams.FLAG_SLIPPERY
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
@@ -373,17 +368,14 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
} }
WindowManager.LayoutParams windowLayoutParams = new WindowManager.LayoutParams( WindowManager.LayoutParams windowLayoutParams = new WindowManager.LayoutParams(
isVerticalBarLayout ? mLastRequestedNonFullscreenHeight : MATCH_PARENT, MATCH_PARENT,
isVerticalBarLayout ? MATCH_PARENT : mLastRequestedNonFullscreenHeight, mLastRequestedNonFullscreenHeight,
type, type,
windowFlags, windowFlags,
PixelFormat.TRANSLUCENT); PixelFormat.TRANSLUCENT);
windowLayoutParams.setTitle(title); windowLayoutParams.setTitle(title);
windowLayoutParams.packageName = getPackageName(); windowLayoutParams.packageName = getPackageName();
windowLayoutParams.gravity = !isVerticalBarLayout ? windowLayoutParams.gravity = Gravity.BOTTOM;
Gravity.BOTTOM :
Gravity.END; // TODO(b/230394142): seascape
windowLayoutParams.setFitInsetsTypes(0); windowLayoutParams.setFitInsetsTypes(0);
windowLayoutParams.receiveInsetsIgnoringZOrder = true; windowLayoutParams.receiveInsetsIgnoringZOrder = true;
windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
@@ -394,6 +386,64 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
TaskbarManager.isPhoneMode(mDeviceProfile) TaskbarManager.isPhoneMode(mDeviceProfile)
? R.string.taskbar_phone_a11y_title ? R.string.taskbar_phone_a11y_title
: R.string.taskbar_a11y_title); : R.string.taskbar_a11y_title);
return windowLayoutParams;
}
/**
* Creates {@link WindowManager.LayoutParams} for Taskbar, and also sets LP.paramsForRotation
* for taskbar showing as navigation bar
*/
private WindowManager.LayoutParams createAllWindowParams() {
WindowManager.LayoutParams windowLayoutParams =
createDefaultWindowLayoutParams(TYPE_NAVIGATION_BAR_PANEL,
TaskbarActivityContext.WINDOW_TITLE);
boolean isPhoneNavMode = TaskbarManager.isPhoneButtonNavMode(this);
if (!isPhoneNavMode) {
return windowLayoutParams;
}
// Provide WM layout params for all rotations to cache, see NavigationBar#getBarLayoutParams
int width = WindowManager.LayoutParams.MATCH_PARENT;
int height = WindowManager.LayoutParams.MATCH_PARENT;
int gravity = Gravity.BOTTOM;
windowLayoutParams.paramsForRotation = new WindowManager.LayoutParams[4];
for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
WindowManager.LayoutParams lp =
createDefaultWindowLayoutParams(TYPE_NAVIGATION_BAR_PANEL,
TaskbarActivityContext.WINDOW_TITLE);
switch (rot) {
case Surface.ROTATION_0, Surface.ROTATION_180 -> {
// Defaults are fine
width = WindowManager.LayoutParams.MATCH_PARENT;
height = mLastRequestedNonFullscreenHeight;
gravity = Gravity.BOTTOM;
}
case Surface.ROTATION_90 -> {
width = mLastRequestedNonFullscreenHeight;
height = WindowManager.LayoutParams.MATCH_PARENT;
gravity = Gravity.END;
}
case Surface.ROTATION_270 -> {
width = mLastRequestedNonFullscreenHeight;
height = WindowManager.LayoutParams.MATCH_PARENT;
gravity = Gravity.START;
}
}
lp.width = width;
lp.height = height;
lp.gravity = gravity;
windowLayoutParams.paramsForRotation[rot] = lp;
}
// Override current layout params
WindowManager.LayoutParams currentParams =
windowLayoutParams.paramsForRotation[getDisplay().getRotation()];
windowLayoutParams.width = currentParams.width;
windowLayoutParams.height = currentParams.height;
windowLayoutParams.gravity = currentParams.gravity;
return windowLayoutParams; return windowLayoutParams;
} }
@@ -19,6 +19,7 @@ import android.graphics.Insets
import android.graphics.Region import android.graphics.Region
import android.os.Binder import android.os.Binder
import android.os.IBinder import android.os.IBinder
import android.view.Gravity
import android.view.InsetsFrameProvider import android.view.InsetsFrameProvider
import android.view.InsetsFrameProvider.SOURCE_DISPLAY import android.view.InsetsFrameProvider.SOURCE_DISPLAY
import android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER import android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER
@@ -109,16 +110,12 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
.setSource(SOURCE_DISPLAY) .setSource(SOURCE_DISPLAY)
) )
} else { } else {
windowLayoutParams.providedInsets = windowLayoutParams.providedInsets = getButtonNavInsets(insetsRoundedCornerFlag)
arrayOf( if (windowLayoutParams.paramsForRotation != null) {
InsetsFrameProvider(insetsOwner, 0, navigationBars()) for (layoutParams in windowLayoutParams.paramsForRotation) {
.setFlags( layoutParams.providedInsets = getButtonNavInsets(insetsRoundedCornerFlag)
insetsRoundedCornerFlag, }
(FLAG_SUPPRESS_SCRIM or FLAG_INSETS_ROUNDED_CORNER) }
),
InsetsFrameProvider(insetsOwner, 0, tappableElement()),
InsetsFrameProvider(insetsOwner, 0, mandatorySystemGestures())
)
} }
val taskbarTouchableHeight = controllers.taskbarStashController.touchableHeight val taskbarTouchableHeight = controllers.taskbarStashController.touchableHeight
@@ -150,75 +147,99 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
windowLayoutParams.height windowLayoutParams.height
) )
} }
val contentHeight = controllers.taskbarStashController.contentHeightToReportToApps
val res = context.resources val gravity = windowLayoutParams.gravity
for (provider in windowLayoutParams.providedInsets) { for (provider in windowLayoutParams.providedInsets) {
if (provider.type == navigationBars() || provider.type == mandatorySystemGestures()) { setProviderInsets(provider, gravity)
provider.insetsSize = getInsetsByNavMode(contentHeight)
} else if (provider.type == tappableElement()) {
provider.insetsSize = getInsetsByNavMode(tappableHeight)
} else if (provider.type == systemGestures() && provider.index == INDEX_LEFT) {
provider.insetsSize =
Insets.of(
gestureNavSettingsObserver.getLeftSensitivityForCallingUser(res),
0,
0,
0
)
} else if (provider.type == systemGestures() && provider.index == INDEX_RIGHT) {
provider.insetsSize =
Insets.of(
0,
0,
gestureNavSettingsObserver.getRightSensitivityForCallingUser(res),
0
)
}
} }
val imeInsetsSize = getInsetsByNavMode(taskbarHeightForIme) if (windowLayoutParams.paramsForRotation != null) {
val insetsSizeOverride = // Add insets for navbar rotated params
arrayOf( for (layoutParams in windowLayoutParams.paramsForRotation) {
InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, imeInsetsSize), for (provider in layoutParams.providedInsets) {
) setProviderInsets(provider, layoutParams.gravity)
// Use 0 tappableElement insets for the VoiceInteractionWindow when gesture nav is enabled. }
val visInsetsSizeForGestureNavTappableElement = getInsetsByNavMode(0)
val insetsSizeOverrideForGestureNavTappableElement =
arrayOf(
InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, imeInsetsSize),
InsetsFrameProvider.InsetsSizeOverride(
TYPE_VOICE_INTERACTION,
visInsetsSizeForGestureNavTappableElement
),
)
for (provider in windowLayoutParams.providedInsets) {
if (context.isGestureNav && provider.type == tappableElement()) {
provider.insetsSizeOverrides = insetsSizeOverrideForGestureNavTappableElement
} else if (provider.type != systemGestures()) {
// We only override insets at the bottom of the screen
provider.insetsSizeOverrides = insetsSizeOverride
} }
} }
context.notifyUpdateLayoutParams() context.notifyUpdateLayoutParams()
} }
private fun getButtonNavInsets(insetsRoundedCornerFlag: Int): Array<InsetsFrameProvider> {
return arrayOf(
InsetsFrameProvider(insetsOwner, 0, navigationBars())
.setFlags(
insetsRoundedCornerFlag,
(FLAG_SUPPRESS_SCRIM or FLAG_INSETS_ROUNDED_CORNER)
),
InsetsFrameProvider(insetsOwner, 0, tappableElement()),
InsetsFrameProvider(insetsOwner, 0, mandatorySystemGestures()))
}
private fun setProviderInsets(provider: InsetsFrameProvider, gravity: Int) {
val contentHeight = controllers.taskbarStashController.contentHeightToReportToApps
val tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps
val res = context.resources
if (provider.type == navigationBars() || provider.type == mandatorySystemGestures()) {
provider.insetsSize = getInsetsByNavMode(contentHeight, gravity)
} else if (provider.type == tappableElement()) {
provider.insetsSize = getInsetsByNavMode(tappableHeight, gravity)
} else if (provider.type == systemGestures() && provider.index == INDEX_LEFT) {
provider.insetsSize =
Insets.of(
gestureNavSettingsObserver.getLeftSensitivityForCallingUser(res),
0,
0,
0
)
} else if (provider.type == systemGestures() && provider.index == INDEX_RIGHT) {
provider.insetsSize =
Insets.of(
0,
0,
gestureNavSettingsObserver.getRightSensitivityForCallingUser(res),
0
)
}
val imeInsetsSize = getInsetsByNavMode(taskbarHeightForIme, gravity)
val insetsSizeOverride =
arrayOf(
InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, imeInsetsSize),
)
// Use 0 tappableElement insets for the VoiceInteractionWindow when gesture nav is enabled.
val visInsetsSizeForGestureNavTappableElement = getInsetsByNavMode(0, gravity)
val insetsSizeOverrideForGestureNavTappableElement =
arrayOf(
InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, imeInsetsSize),
InsetsFrameProvider.InsetsSizeOverride(
TYPE_VOICE_INTERACTION,
visInsetsSizeForGestureNavTappableElement
),
)
if (context.isGestureNav && provider.type == tappableElement()) {
provider.insetsSizeOverrides = insetsSizeOverrideForGestureNavTappableElement
} else if (provider.type != systemGestures()) {
// We only override insets at the bottom of the screen
provider.insetsSizeOverrides = insetsSizeOverride
}
}
/** /**
* @return [Insets] where the [bottomInset] is either used as a bottom inset or * @return [Insets] where the [inset] is either used as a bottom inset or
* * right/left inset if using 3 button nav
* ```
* right/left inset if using 3 button nav
* ```
*/ */
private fun getInsetsByNavMode(bottomInset: Int): Insets { private fun getInsetsByNavMode(inset: Int, gravity: Int): Insets {
val devicePortrait = !context.deviceProfile.isLandscape if ((gravity and Gravity.BOTTOM) != 0) {
if (!TaskbarManager.isPhoneButtonNavMode(context) || devicePortrait) {
// Taskbar or portrait phone mode // Taskbar or portrait phone mode
return Insets.of(0, 0, 0, bottomInset) return Insets.of(0, 0, 0, inset)
} }
// TODO(b/230394142): seascape // TODO(b/230394142): seascape
return Insets.of(0, 0, bottomInset, 0) val isSeascape = (gravity and Gravity.START) != 0
val leftInset = if (isSeascape) inset else 0
val rightInset = if (isSeascape) 0 else inset
return Insets.of(leftInset , 0, rightInset, 0)
} }
/** /**
@@ -206,7 +206,14 @@ public class TaskbarManager {
destroyExistingTaskbar(); destroyExistingTaskbar();
} else { } else {
if (dp != null && isTaskbarPresent(dp)) { if (dp != null && isTaskbarPresent(dp)) {
mTaskbarActivityContext.updateDeviceProfile(dp); if (FLAG_HIDE_NAVBAR_WINDOW) {
// Re-initialize for screen size change? Should this be done
// by looking at screen-size change flag in configDiff in the
// block above?
recreateTaskbar();
} else {
mTaskbarActivityContext.updateDeviceProfile(dp);
}
} }
mTaskbarActivityContext.onConfigurationChanged(configDiff); mTaskbarActivityContext.onConfigurationChanged(configDiff);
} }
@@ -25,6 +25,7 @@ import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.anim.AnimatedFloat.VALUE; import static com.android.launcher3.anim.AnimatedFloat.VALUE;
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
import static com.android.launcher3.taskbar.TaskbarManager.isPhoneButtonNavMode;
import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode; import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_ALIGNMENT_ANIM; import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_ALIGNMENT_ANIM;
@@ -171,6 +172,13 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
.getTaskbarNavButtonTranslationYForInAppDisplay(); .getTaskbarNavButtonTranslationYForInAppDisplay();
mActivity.addOnDeviceProfileChangeListener(mDeviceProfileChangeListener); mActivity.addOnDeviceProfileChangeListener(mDeviceProfileChangeListener);
if (TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) {
// This gets modified in NavbarButtonsViewController, but the initial value it reads
// may be incorrect since it's state gets destroyed on taskbar recreate, so reset here
mTaskbarIconAlpha.get(ALPHA_INDEX_SMALL_SCREEN)
.animateToValue(isPhoneButtonNavMode(mActivity) ? 0 : 1).start();
}
} }
/** /**
@@ -444,8 +452,13 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
* Creates an animation for aligning the Taskbar icons with the provided Launcher device profile * Creates an animation for aligning the Taskbar icons with the provided Launcher device profile
*/ */
private AnimatorPlaybackController createIconAlignmentController(DeviceProfile launcherDp) { private AnimatorPlaybackController createIconAlignmentController(DeviceProfile launcherDp) {
mOnControllerPreCreateCallback.run();
PendingAnimation setter = new PendingAnimation(100); PendingAnimation setter = new PendingAnimation(100);
if (TaskbarManager.isPhoneButtonNavMode(mActivity)) {
// No animation for icons in small-screen
return setter.createPlaybackController();
}
mOnControllerPreCreateCallback.run();
DeviceProfile taskbarDp = mActivity.getDeviceProfile(); DeviceProfile taskbarDp = mActivity.getDeviceProfile();
Rect hotseatPadding = launcherDp.getHotseatLayoutPadding(mActivity); Rect hotseatPadding = launcherDp.getHotseatLayoutPadding(mActivity);
float scaleUp = ((float) launcherDp.iconSizePx) / taskbarDp.taskbarIconSize; float scaleUp = ((float) launcherDp.iconSizePx) / taskbarDp.taskbarIconSize;
@@ -17,10 +17,12 @@
package com.android.launcher3.taskbar.navbutton package com.android.launcher3.taskbar.navbutton
import android.content.res.Resources import android.content.res.Resources
import android.graphics.drawable.RotateDrawable
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import com.android.launcher3.R import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter
/** /**
@@ -40,7 +42,18 @@ abstract class AbstractNavButtonLayoutter(
protected val endContextualContainer: ViewGroup, protected val endContextualContainer: ViewGroup,
protected val startContextualContainer: ViewGroup protected val startContextualContainer: ViewGroup
) : NavButtonLayoutter { ) : NavButtonLayoutter {
protected val homeButton: ImageView = navButtonContainer.findViewById(R.id.home) protected val homeButton: ImageView? = navButtonContainer.findViewById(R.id.home)
protected val recentsButton: ImageView = navButtonContainer.findViewById(R.id.recent_apps) protected val recentsButton: ImageView? = navButtonContainer.findViewById(R.id.recent_apps)
protected val backButton: ImageView = navButtonContainer.findViewById(R.id.back) protected val backButton: ImageView? = navButtonContainer.findViewById(R.id.back)
init {
// setup back button drawable
if (backButton != null) {
val rotateDrawable = RotateDrawable()
rotateDrawable.drawable = backButton.context?.getDrawable(R.drawable.ic_sysbar_back)
rotateDrawable.fromDegrees = 0f
rotateDrawable.toDegrees = if (Utilities.isRtl(backButton.resources)) 90f else -90f
backButton.setImageDrawable(rotateDrawable)
}
}
} }
@@ -51,10 +51,10 @@ class KidsNavLayoutter(
val paddingTop = (buttonHeight - iconSize) / 2 val paddingTop = (buttonHeight - iconSize) / 2
// Update icons // Update icons
backButton.setImageDrawable(backButton.context.getDrawable(DRAWABLE_SYSBAR_BACK_KIDS)) backButton!!.setImageDrawable(backButton.context.getDrawable(DRAWABLE_SYSBAR_BACK_KIDS))
backButton.scaleType = ImageView.ScaleType.FIT_CENTER backButton.scaleType = ImageView.ScaleType.FIT_CENTER
backButton.setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop) backButton.setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop)
homeButton.setImageDrawable(homeButton.getContext().getDrawable(DRAWABLE_SYSBAR_HOME_KIDS)) homeButton!!.setImageDrawable(homeButton.context.getDrawable(DRAWABLE_SYSBAR_HOME_KIDS))
homeButton.scaleType = ImageView.ScaleType.FIT_CENTER homeButton.scaleType = ImageView.ScaleType.FIT_CENTER
homeButton.setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop) homeButton.setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop)
@@ -17,6 +17,8 @@
package com.android.launcher3.taskbar.navbutton package com.android.launcher3.taskbar.navbutton
import android.content.res.Resources import android.content.res.Resources
import android.view.Surface.ROTATION_90
import android.view.Surface.Rotation
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.LinearLayout import android.widget.LinearLayout
@@ -56,7 +58,8 @@ class NavButtonLayoutFactory {
isKidsMode: Boolean, isKidsMode: Boolean,
isInSetup: Boolean, isInSetup: Boolean,
isThreeButtonNav: Boolean, isThreeButtonNav: Boolean,
phoneMode: Boolean phoneMode: Boolean,
@Rotation surfaceRotation: Int
): NavButtonLayoutter { ): NavButtonLayoutter {
val navButtonContainer = navButtonsView.findViewById<LinearLayout>(ID_END_NAV_BUTTONS) val navButtonContainer = navButtonsView.findViewById<LinearLayout>(ID_END_NAV_BUTTONS)
val endContextualContainer = val endContextualContainer =
@@ -73,13 +76,20 @@ class NavButtonLayoutFactory {
endContextualContainer, endContextualContainer,
startContextualContainer startContextualContainer
) )
} else { } else if (surfaceRotation == ROTATION_90) {
PhoneLandscapeNavLayoutter( PhoneLandscapeNavLayoutter(
resources, resources,
navButtonContainer, navButtonContainer,
endContextualContainer, endContextualContainer,
startContextualContainer startContextualContainer
) )
} else {
PhoneSeascapeNavLayoutter(
resources,
navButtonContainer,
endContextualContainer,
startContextualContainer
)
} }
} }
deviceProfile.isTaskbarPresent -> { deviceProfile.isTaskbarPresent -> {
@@ -27,7 +27,7 @@ import com.android.launcher3.R
import com.android.launcher3.taskbar.TaskbarManager import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.util.DimensionUtils import com.android.launcher3.util.DimensionUtils
class PhoneLandscapeNavLayoutter( open class PhoneLandscapeNavLayoutter(
resources: Resources, resources: Resources,
navBarContainer: LinearLayout, navBarContainer: LinearLayout,
endContextualContainer: ViewGroup, endContextualContainer: ViewGroup,
@@ -44,8 +44,8 @@ class PhoneLandscapeNavLayoutter(
// TODO(b/230395757): Polish pending, this is just to make it usable // TODO(b/230395757): Polish pending, this is just to make it usable
val navContainerParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams val navContainerParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams
val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size)
val taskbarDimensions = val taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(dp, resources,
DimensionUtils.getTaskbarPhoneDimensions(dp, resources, TaskbarManager.isPhoneMode(dp)) TaskbarManager.isPhoneMode(dp))
navButtonContainer.removeAllViews() navButtonContainer.removeAllViews()
navButtonContainer.orientation = LinearLayout.VERTICAL navButtonContainer.orientation = LinearLayout.VERTICAL
@@ -43,7 +43,8 @@ class PhonePortraitNavLayoutter(
// TODO(b/230395757): Polish pending, this is just to make it usable // TODO(b/230395757): Polish pending, this is just to make it usable
val navContainerParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams val navContainerParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams
val taskbarDimensions = val taskbarDimensions =
DimensionUtils.getTaskbarPhoneDimensions(dp, resources, TaskbarManager.isPhoneMode(dp)) DimensionUtils.getTaskbarPhoneDimensions(dp, resources,
TaskbarManager.isPhoneMode(dp))
val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size)
navContainerParams.width = taskbarDimensions.x navContainerParams.width = taskbarDimensions.x
navContainerParams.height = ViewGroup.LayoutParams.MATCH_PARENT navContainerParams.height = ViewGroup.LayoutParams.MATCH_PARENT
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.launcher3.taskbar.navbutton
import android.content.res.Resources
import android.view.ViewGroup
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
class PhoneSeascapeNavLayoutter(
resources: Resources,
navBarContainer: LinearLayout,
endContextualContainer: ViewGroup,
startContextualContainer: ViewGroup
) :
PhoneLandscapeNavLayoutter(
resources,
navBarContainer,
endContextualContainer,
startContextualContainer
) {
override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
// TODO(b/230395757): Polish pending, this is just to make it usable
super.layoutButtons(dp, isContextualButtonShowing)
navButtonContainer.removeAllViews()
// Flip ordering of back and recents buttons
navButtonContainer.addView(backButton)
navButtonContainer.addView(homeButton)
navButtonContainer.addView(recentsButton)
}
}
@@ -1,6 +1,9 @@
package com.android.launcher3.taskbar.navbutton package com.android.launcher3.taskbar.navbutton
import android.content.res.Resources import android.content.res.Resources
import android.view.Surface
import android.view.Surface.ROTATION_270
import android.view.Surface.Rotation
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
@@ -32,6 +35,8 @@ class NavButtonLayoutFactoryTest {
@Mock lateinit var mockRecentsButton: ImageView @Mock lateinit var mockRecentsButton: ImageView
@Mock lateinit var mockHomeButton: ImageView @Mock lateinit var mockHomeButton: ImageView
private var surfaceRotation = Surface.ROTATION_0
@Before @Before
fun setup() { fun setup() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
@@ -60,7 +65,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode = true, isKidsMode = true,
isInSetup = false, isInSetup = false,
isThreeButtonNav = false, isThreeButtonNav = false,
phoneMode = false phoneMode = false,
surfaceRotation = surfaceRotation
) )
assert(layoutter is KidsNavLayoutter) assert(layoutter is KidsNavLayoutter)
} }
@@ -74,7 +80,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode = false, isKidsMode = false,
isInSetup = true, isInSetup = true,
isThreeButtonNav = false, isThreeButtonNav = false,
phoneMode = false phoneMode = false,
surfaceRotation = surfaceRotation
) )
assert(layoutter is SetupNavLayoutter) assert(layoutter is SetupNavLayoutter)
} }
@@ -88,7 +95,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode = false, isKidsMode = false,
isInSetup = false, isInSetup = false,
isThreeButtonNav = false, isThreeButtonNav = false,
phoneMode = false phoneMode = false,
surfaceRotation = surfaceRotation
) )
assert(layoutter is TaskbarNavLayoutter) assert(layoutter is TaskbarNavLayoutter)
} }
@@ -101,7 +109,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode = false, isKidsMode = false,
isInSetup = false, isInSetup = false,
isThreeButtonNav = false, isThreeButtonNav = false,
phoneMode = false phoneMode = false,
surfaceRotation = surfaceRotation
) )
} }
@@ -114,7 +123,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode = false, isKidsMode = false,
isInSetup = false, isInSetup = false,
isThreeButtonNav = true, isThreeButtonNav = true,
phoneMode = true phoneMode = true,
surfaceRotation = surfaceRotation
) )
assert(layoutter is PhonePortraitNavLayoutter) assert(layoutter is PhonePortraitNavLayoutter)
} }
@@ -129,11 +139,28 @@ class NavButtonLayoutFactoryTest {
isKidsMode = false, isKidsMode = false,
isInSetup = false, isInSetup = false,
isThreeButtonNav = true, isThreeButtonNav = true,
phoneMode = true phoneMode = true,
surfaceRotation = surfaceRotation
) )
assert(layoutter is PhoneLandscapeNavLayoutter) assert(layoutter is PhoneLandscapeNavLayoutter)
} }
@Test
fun getTaskbarSeascapeLayoutter() {
assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW)
mockDeviceProfile.isTaskbarPresent = false
setDeviceProfileLandscape()
val layoutter: NavButtonLayoutFactory.NavButtonLayoutter =
getLayoutter(
isKidsMode = false,
isInSetup = false,
isThreeButtonNav = true,
phoneMode = true,
surfaceRotation = ROTATION_270
)
assert(layoutter is PhoneSeascapeNavLayoutter)
}
@Test(expected = IllegalStateException::class) @Test(expected = IllegalStateException::class)
fun noValidLayoutForPhoneGestureNav() { fun noValidLayoutForPhoneGestureNav() {
assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW)
@@ -142,7 +169,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode = false, isKidsMode = false,
isInSetup = false, isInSetup = false,
isThreeButtonNav = false, isThreeButtonNav = false,
phoneMode = true phoneMode = true,
surfaceRotation = surfaceRotation
) )
} }
@@ -157,7 +185,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode: Boolean, isKidsMode: Boolean,
isInSetup: Boolean, isInSetup: Boolean,
isThreeButtonNav: Boolean, isThreeButtonNav: Boolean,
phoneMode: Boolean phoneMode: Boolean,
@Rotation surfaceRotation: Int
): NavButtonLayoutFactory.NavButtonLayoutter { ): NavButtonLayoutFactory.NavButtonLayoutter {
return NavButtonLayoutFactory.getUiLayoutter( return NavButtonLayoutFactory.getUiLayoutter(
deviceProfile = mockDeviceProfile, deviceProfile = mockDeviceProfile,
@@ -166,7 +195,8 @@ class NavButtonLayoutFactoryTest {
isKidsMode = isKidsMode, isKidsMode = isKidsMode,
isInSetup = isInSetup, isInSetup = isInSetup,
isThreeButtonNav = isThreeButtonNav, isThreeButtonNav = isThreeButtonNav,
phoneMode = phoneMode phoneMode = phoneMode,
surfaceRotation = surfaceRotation
) )
} }
} }
@@ -29,9 +29,9 @@ object DimensionUtils {
*/ */
@JvmStatic @JvmStatic
fun getTaskbarPhoneDimensions( fun getTaskbarPhoneDimensions(
deviceProfile: DeviceProfile, deviceProfile: DeviceProfile,
res: Resources, res: Resources,
isPhoneMode: Boolean isPhoneMode: Boolean
): Point { ): Point {
val p = Point() val p = Point()
// Taskbar for large screen // Taskbar for large screen