diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 791f0c5140..fb26caab3c 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -44,7 +44,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAU import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION; import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY; import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID; -import static com.android.launcher3.statehandlers.DepthController.STATE_DEPTH; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs; import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; import static com.android.launcher3.views.FloatingIconView.getFloatingIconView; @@ -388,7 +388,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onAnimationStart(Animator animation) { mLauncher.addOnResumeCallback(() -> - ObjectAnimator.ofFloat(mLauncher.getDepthController(), STATE_DEPTH, + ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth, + MULTI_PROPERTY_VALUE, mLauncher.getStateManager().getState().getDepth( mLauncher)).start()); } @@ -412,7 +413,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onAnimationStart(Animator animation) { mLauncher.addOnResumeCallback(() -> - ObjectAnimator.ofFloat(mLauncher.getDepthController(), STATE_DEPTH, + ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth, + MULTI_PROPERTY_VALUE, mLauncher.getStateManager().getState().getDepth( mLauncher)).start()); } @@ -1050,8 +1052,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener && BlurUtils.supportsBlursOnWindows(); MyDepthController depthController = new MyDepthController(mLauncher); - ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController, STATE_DEPTH, - BACKGROUND_APP.getDepth(mLauncher)) + ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController.stateDepth, + MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher)) .setDuration(APP_LAUNCH_DURATION); if (allowBlurringLauncher) { @@ -1591,8 +1593,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener true /* animateOverviewScrim */, launcherView).getAnimators()); if (!areAllTargetsTranslucent(appTargets)) { - anim.play(ObjectAnimator.ofFloat(mLauncher.getDepthController(), - STATE_DEPTH, + anim.play(ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth, + MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher), NORMAL.getDepth(mLauncher))); } diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 2a78bdf197..867e168dd2 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -19,6 +19,7 @@ package com.android.launcher3.statehandlers; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH; import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -112,7 +113,7 @@ public class DepthController extends BaseDepthController implements StateHandler return; } - STATE_DEPTH.set(this, toState.getDepth(mLauncher)); + stateDepth.setValue(toState.getDepth(mLauncher)); if (toState == LauncherState.BACKGROUND_APP) { mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener); } @@ -127,7 +128,8 @@ public class DepthController extends BaseDepthController implements StateHandler } float toDepth = toState.getDepth(mLauncher); - animation.setFloat(this, STATE_DEPTH, toDepth, config.getInterpolator(ANIM_DEPTH, LINEAR)); + animation.setFloat(stateDepth, MULTI_PROPERTY_VALUE, toDepth, + config.getInterpolator(ANIM_DEPTH, LINEAR)); } @Override @@ -140,7 +142,7 @@ public class DepthController extends BaseDepthController implements StateHandler public void onMultiWindowModeChanged(boolean isInMultiWindowMode) { mIgnoreStateChangesDuringMultiWindowAnimation = true; - ObjectAnimator mwAnimation = ObjectAnimator.ofFloat(this, STATE_DEPTH, + ObjectAnimator mwAnimation = ObjectAnimator.ofFloat(stateDepth, MULTI_PROPERTY_VALUE, mLauncher.getStateManager().getState().getDepth(mLauncher, isInMultiWindowMode)) .setDuration(300); mwAnimation.addListener(new AnimatorListenerAdapter() { @@ -158,8 +160,8 @@ public class DepthController extends BaseDepthController implements StateHandler writer.println(prefix + "\tmMaxBlurRadius=" + mMaxBlurRadius); writer.println(prefix + "\tmCrossWindowBlursEnabled=" + mCrossWindowBlursEnabled); writer.println(prefix + "\tmSurface=" + mSurface); - writer.println(prefix + "\tmStateDepth=" + STATE_DEPTH.get(this)); - writer.println(prefix + "\tmWidgetDepth=" + WIDGET_DEPTH.get(this)); + writer.println(prefix + "\tmStateDepth=" + stateDepth.getValue()); + writer.println(prefix + "\tmWidgetDepth=" + widgetDepth.getValue()); writer.println(prefix + "\tmCurrentBlur=" + mCurrentBlur); writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp); writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation=" diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 026fa2311b..875327dc8a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -31,6 +31,7 @@ import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RE import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_KEYGUARD; import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_SMALL_SCREEN; import static com.android.launcher3.taskbar.Utilities.appendFlag; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED; @@ -84,6 +85,7 @@ import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton; import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory; import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter; import com.android.launcher3.util.DimensionUtils; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; @@ -227,13 +229,13 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mPropertyHolders.add(new StatePropertyHolder( mControllers.taskbarViewController.getTaskbarIconAlpha() - .getProperty(ALPHA_INDEX_KEYGUARD), + .get(ALPHA_INDEX_KEYGUARD), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_SCREEN_PINNING_ACTIVE) == 0)); mPropertyHolders.add(new StatePropertyHolder( mControllers.taskbarViewController.getTaskbarIconAlpha() - .getProperty(ALPHA_INDEX_SMALL_SCREEN), + .get(ALPHA_INDEX_SMALL_SCREEN), flags -> (flags & FLAG_SMALL_SCREEN) == 0)); mPropertyHolders.add(new StatePropertyHolder(mControllers.taskbarDragLayerController @@ -340,7 +342,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mBackButtonAlpha = new MultiValueAlpha(mBackButton, NUM_ALPHA_CHANNELS); mBackButtonAlpha.setUpdateVisibility(true); mPropertyHolders.add(new StatePropertyHolder( - mBackButtonAlpha.getProperty(ALPHA_INDEX_KEYGUARD_OR_DISABLE), + mBackButtonAlpha.get(ALPHA_INDEX_KEYGUARD_OR_DISABLE), flags -> { // Show only if not disabled, and if not on the keyguard or otherwise only when // the bouncer or a lockscreen app is showing above the keyguard @@ -368,7 +370,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mHomeButtonAlpha = new MultiValueAlpha(mHomeButton, NUM_ALPHA_CHANNELS); mHomeButtonAlpha.setUpdateVisibility(true); mPropertyHolders.add( - new StatePropertyHolder(mHomeButtonAlpha.getProperty( + new StatePropertyHolder(mHomeButtonAlpha.get( ALPHA_INDEX_KEYGUARD_OR_DISABLE), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_DISABLE_HOME) == 0)); @@ -720,7 +722,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT // Hide back button in SUW if keyboard is showing (IME draws its own back). mPropertyHolders.add(new StatePropertyHolder( - mBackButtonAlpha.getProperty(ALPHA_INDEX_SUW), + mBackButtonAlpha.get(ALPHA_INDEX_SUW), flags -> (flags & FLAG_IME_VISIBLE) == 0)); // TODO(b/210906568) Dark intensity is currently not propagated during setup, so set @@ -1046,9 +1048,9 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mAnimator.addListener(new AlphaUpdateListener(view)); } - StatePropertyHolder(MultiValueAlpha.AlphaProperty alphaProperty, + StatePropertyHolder(MultiProperty alphaProperty, IntPredicate enableCondition) { - this(alphaProperty, enableCondition, MultiValueAlpha.VALUE, 1, 0); + this(alphaProperty, enableCondition, MULTI_PROPERTY_VALUE, 1, 0); } StatePropertyHolder(AnimatedFloat animatedFloat, IntPredicate enableCondition) { diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java index e23e27ed0f..12dbcb3902 100644 --- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java @@ -31,6 +31,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.util.Executors; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.AnimatedFloat; import com.android.systemui.shared.navigationbar.RegionSamplingHelper; @@ -105,7 +106,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT .getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width); } - mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue( + mTaskbarStashedHandleAlpha.get(ALPHA_INDEX_STASHED).setValue( isPhoneGestureNavMode(deviceProfile) ? 1 : 0); mTaskbarStashedHandleHintScale.updateValue(1f); @@ -166,7 +167,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT return TaskbarManager.isPhoneMode(deviceProfile) && !mActivity.isThreeButtonNav(); } - public MultiValueAlpha getStashedHandleAlpha() { + public MultiPropertyFactory getStashedHandleAlpha() { return mTaskbarStashedHandleAlpha; } @@ -222,7 +223,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT * Should be called when the home button is disabled, so we can hide this handle as well. */ public void setIsHomeButtonDisabled(boolean homeDisabled) { - mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_HOME_DISABLED).setValue( + mTaskbarStashedHandleAlpha.get(ALPHA_INDEX_HOME_DISABLED).setValue( homeDisabled ? 0 : 1); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 4c5e0bea8c..237d1efbf6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -523,7 +523,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { private void onNotificationShadeExpandChanged(boolean isExpanded, boolean skipAnim) { float alpha = isExpanded ? 0 : 1; AnimatorSet anim = new AnimatorSet(); - anim.play(mControllers.taskbarViewController.getTaskbarIconAlpha().getProperty( + anim.play(mControllers.taskbarViewController.getTaskbarIconAlpha().get( TaskbarViewController.ALPHA_INDEX_NOTIFICATION_EXPANDED).animateToValue(alpha)); if (!isThreeButtonNav()) { anim.play(mControllers.taskbarDragLayerController.getNotificationShadeBgTaskbar() diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java index 6c793a6119..f7aafe0d05 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java @@ -31,13 +31,10 @@ import android.view.MotionEvent; import android.view.View; import com.android.launcher3.compat.AccessibilityManagerCompat; -import com.android.launcher3.util.MultiValueAlpha; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.TouchController; import com.android.quickstep.AnimatedFloat; -import java.util.Optional; -import java.util.function.Consumer; - /** * Controller for taskbar when force visible in immersive mode is set. */ @@ -54,8 +51,6 @@ public class TaskbarForceVisibleImmersiveController implements TouchController { private final Runnable mUndimmingRunnable = this::undimIcons; private final AnimatedFloat mIconAlphaForDimming = new AnimatedFloat( this::updateIconDimmingAlpha); - private final Consumer mImmersiveModeAlphaUpdater = alpha -> alpha.getProperty( - ALPHA_INDEX_IMMERSIVE_MODE).setValue(mIconAlphaForDimming.value); private final View.AccessibilityDelegate mKidsModeAccessibilityDelegate = new View.AccessibilityDelegate() { @Override @@ -145,22 +140,20 @@ public class TaskbarForceVisibleImmersiveController implements TouchController { } private void updateIconDimmingAlpha() { - getBackButtonAlphaOptional().ifPresent(mImmersiveModeAlphaUpdater); - getHomeButtonAlphaOptional().ifPresent(mImmersiveModeAlphaUpdater); - } - - private Optional getBackButtonAlphaOptional() { if (mControllers == null || mControllers.navbarButtonsViewController == null) { - return Optional.empty(); + return; } - return Optional.ofNullable(mControllers.navbarButtonsViewController.getBackButtonAlpha()); - } - private Optional getHomeButtonAlphaOptional() { - if (mControllers == null || mControllers.navbarButtonsViewController == null) { - return Optional.empty(); + MultiPropertyFactory ba = + mControllers.navbarButtonsViewController.getBackButtonAlpha(); + if (ba != null) { + ba.get(ALPHA_INDEX_IMMERSIVE_MODE).setValue(mIconAlphaForDimming.value); + } + MultiPropertyFactory ha = + mControllers.navbarButtonsViewController.getHomeButtonAlpha(); + if (ba != null) { + ha.get(ALPHA_INDEX_IMMERSIVE_MODE).setValue(mIconAlphaForDimming.value); } - return Optional.ofNullable(mControllers.navbarButtonsViewController.getHomeButtonAlpha()); } @Override diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index de37b70632..63f1486729 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -38,7 +38,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.uioverrides.QuickstepLauncher; -import com.android.launcher3.util.MultiValueAlpha; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.RecentsAnimationController; @@ -49,7 +49,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import java.io.PrintWriter; import java.util.HashMap; import java.util.StringJoiner; -import java.util.function.Consumer; /** * Track LauncherState, RecentsAnimation, resumed state for task bar in one place here and animate @@ -73,7 +72,7 @@ import java.util.function.Consumer; private TaskbarControllers mControllers; private AnimatedFloat mTaskbarBackgroundAlpha; - private MultiValueAlpha.AlphaProperty mIconAlphaForHome; + private MultiProperty mIconAlphaForHome; private QuickstepLauncher mLauncher; private Integer mPrevState; @@ -89,18 +88,8 @@ import java.util.function.Consumer; // We skip any view synchronizations during init/destroy. private boolean mCanSyncViews; - private final Consumer mIconAlphaForHomeConsumer = alpha -> { - /* - * Hide Launcher Hotseat icons when Taskbar icons have opacity. Both icon sets - * should not be visible at the same time. - */ - mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1); - mLauncher.getHotseat().setQsbAlpha( - mLauncher.getDeviceProfile().isQsbInline && alpha > 0 ? 0 : 1); - }; - private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener = - dp -> mIconAlphaForHomeConsumer.accept(mIconAlphaForHome.getValue()); + dp -> updateIconAlphaForHome(mIconAlphaForHome.getValue()); private final StateManager.StateListener mStateListener = new StateManager.StateListener() { @@ -139,9 +128,8 @@ import java.util.function.Consumer; mTaskbarBackgroundAlpha = mControllers.taskbarDragLayerController .getTaskbarBackgroundAlpha(); - MultiValueAlpha taskbarIconAlpha = mControllers.taskbarViewController.getTaskbarIconAlpha(); - mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME); - mIconAlphaForHome.setConsumer(mIconAlphaForHomeConsumer); + mIconAlphaForHome = mControllers.taskbarViewController + .getTaskbarIconAlpha().get(ALPHA_INDEX_HOME); mIconAlignment.finishAnimation(); onIconAlignmentRatioChanged(); @@ -162,7 +150,6 @@ import java.util.function.Consumer; mIconAlignment.finishAnimation(); - mIconAlphaForHome.setConsumer(null); mLauncher.getHotseat().setIconsAlpha(1f); mLauncher.getStateManager().removeStateListener(mStateListener); @@ -383,7 +370,7 @@ import java.util.function.Consumer; @Override public void onAnimationStart(Animator animation) { if (mLauncher.getHotseat().getIconsAlpha() > 0) { - mIconAlphaForHome.setValue(mLauncher.getHotseat().getIconsAlpha()); + updateIconAlphaForHome(mLauncher.getHotseat().getIconsAlpha()); } } }); @@ -405,7 +392,7 @@ import java.util.function.Consumer; mIconAlignment.value, mIconAlignment.getEndValue(), mLauncher.getDeviceProfile()); mControllers.navbarButtonsViewController.updateTaskbarAlignment(mIconAlignment.value); // Switch taskbar and hotseat in last frame - mIconAlphaForHome.setValue(taskbarWillBeVisible ? 1 : 0); + updateIconAlphaForHome(taskbarWillBeVisible ? 1 : 0); // Sync the first frame where we swap taskbar and hotseat. if (firstFrameVisChanged && mCanSyncViews && !Utilities.IS_RUNNING_IN_TEST_HARNESS) { @@ -415,6 +402,18 @@ import java.util.function.Consumer; } } + private void updateIconAlphaForHome(float alpha) { + mIconAlphaForHome.setValue(alpha); + + /* + * Hide Launcher Hotseat icons when Taskbar icons have opacity. Both icon sets + * should not be visible at the same time. + */ + mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1); + mLauncher.getHotseat().setQsbAlpha( + mLauncher.getDeviceProfile().isQsbInline && alpha > 0 ? 0 : 1); + } + private final class TaskBarRecentsAnimationListener implements RecentsAnimationCallbacks.RecentsAnimationListener { private final RecentsAnimationCallbacks mCallbacks; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index c5e1b8fdcd..64eb99e7d1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -44,7 +44,7 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.testing.shared.TestProtocol; -import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.SystemUiProxy; @@ -144,11 +144,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private AnimatedFloat mTaskbarBackgroundOffset; private AnimatedFloat mTaskbarImeBgAlpha; // TaskbarView icon properties. - private AlphaProperty mIconAlphaForStash; + private MultiProperty mIconAlphaForStash; private AnimatedFloat mIconScaleForStash; private AnimatedFloat mIconTranslationYForStash; // Stashed handle properties. - private AlphaProperty mTaskbarStashedHandleAlpha; + private MultiProperty mTaskbarStashedHandleAlpha; private AnimatedFloat mTaskbarStashedHandleHintScale; /** Whether we are currently visually stashed (might change based on launcher state). */ @@ -199,14 +199,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba mTaskbarImeBgAlpha = dragLayerController.getImeBgTaskbar(); TaskbarViewController taskbarViewController = controllers.taskbarViewController; - mIconAlphaForStash = taskbarViewController.getTaskbarIconAlpha().getProperty( + mIconAlphaForStash = taskbarViewController.getTaskbarIconAlpha().get( TaskbarViewController.ALPHA_INDEX_STASH); mIconScaleForStash = taskbarViewController.getTaskbarIconScaleForStash(); mIconTranslationYForStash = taskbarViewController.getTaskbarIconTranslationYForStash(); StashedHandleViewController stashedHandleController = controllers.stashedHandleViewController; - mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha().getProperty( + mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha().get( StashedHandleViewController.ALPHA_INDEX_STASHED); mTaskbarStashedHandleHintScale = stashedHandleController.getStashedHandleHintScale(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 16dd90db29..a88c05deb6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -50,6 +50,7 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.HorizontalInsettableView; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LauncherBindableItemsContainer; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.SystemUiProxy; @@ -146,7 +147,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar return mTaskbarView.areIconsVisible(); } - public MultiValueAlpha getTaskbarIconAlpha() { + public MultiPropertyFactory getTaskbarIconAlpha() { return mTaskbarIconAlpha; } @@ -161,7 +162,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * Should be called when the IME switcher visibility changes. */ public void setIsImeSwitcherVisible(boolean isImeSwitcherVisible) { - mTaskbarIconAlpha.getProperty(ALPHA_INDEX_IME_BUTTON_NAV).setValue( + mTaskbarIconAlpha.get(ALPHA_INDEX_IME_BUTTON_NAV).setValue( isImeSwitcherVisible ? 0 : 1); } @@ -170,7 +171,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar */ public void setRecentsButtonDisabled(boolean isDisabled) { // TODO: check TaskbarStashController#supportsStashing(), to stash instead of setting alpha. - mTaskbarIconAlpha.getProperty(ALPHA_INDEX_RECENTS_DISABLED).setValue(isDisabled ? 0 : 1); + mTaskbarIconAlpha.get(ALPHA_INDEX_RECENTS_DISABLED).setValue(isDisabled ? 0 : 1); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt index 076900cd39..837af589bd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt @@ -63,11 +63,11 @@ class VoiceInteractionWindowController(val context: TaskbarActivityContext) // Fade out taskbar icons and stashed handle. val taskbarIconAlpha = if (isVoiceInteractionWindowVisible) 0f else 1f val fadeTaskbarIcons = controllers.taskbarViewController.taskbarIconAlpha - .getProperty(TaskbarViewController.ALPHA_INDEX_ASSISTANT_INVOKED) + .get(TaskbarViewController.ALPHA_INDEX_ASSISTANT_INVOKED) .animateToValue(taskbarIconAlpha) .setDuration(TASKBAR_ICONS_FADE_DURATION) val fadeStashedHandle = controllers.stashedHandleViewController.stashedHandleAlpha - .getProperty(StashedHandleViewController.ALPHA_INDEX_ASSISTANT_INVOKED) + .get(StashedHandleViewController.ALPHA_INDEX_ASSISTANT_INVOKED) .animateToValue(taskbarIconAlpha) .setDuration(STASHED_HANDLE_FADE_DURATION) fadeTaskbarIcons.start() diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 23794b0e20..df391117fb 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -45,7 +45,6 @@ import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; -import static com.android.quickstep.util.BaseDepthController.WIDGET_DEPTH; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY; import android.animation.AnimatorSet; @@ -597,9 +596,8 @@ public class QuickstepLauncher extends Launcher { super.onWidgetsTransition(progress); onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX); if (mEnableWidgetDepth) { - WIDGET_DEPTH.set(getDepthController(), - Utilities.mapToRange(progress, 0f, 1f, 0f, getDeviceProfile().bottomSheetDepth, - EMPHASIZED)); + getDepthController().widgetDepth.setValue(Utilities.mapToRange( + progress, 0f, 1f, 0f, getDeviceProfile().bottomSheetDepth, EMPHASIZED)); } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 0e1120ba05..e8e83288cd 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import static com.android.quickstep.views.RecentsView.TASK_MODALNESS; @@ -43,7 +44,6 @@ import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.PagedOrientationHandler; -import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.util.AnimUtils; import com.android.quickstep.util.SplitAnimationTimings; import com.android.quickstep.views.ClearAllButton; @@ -164,7 +164,7 @@ public final class RecentsViewStateController extends clearAllButtonAlpha, LINEAR); float overviewButtonAlpha = state.areElementsVisible(mLauncher, OVERVIEW_ACTIONS) ? 1 : 0; propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(), - MultiValueAlpha.VALUE, overviewButtonAlpha, config.getInterpolator( + MULTI_PROPERTY_VALUE, overviewButtonAlpha, config.getInterpolator( ANIM_OVERVIEW_ACTIONS_FADE, LINEAR)); } diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 0a7d226da1..ecb37474e6 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -22,6 +22,7 @@ import static com.android.launcher3.LauncherState.QUICK_SWITCH; import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import android.animation.Animator; import android.animation.AnimatorSet; @@ -129,9 +130,9 @@ public final class LauncherActivityInterface extends // Animate the blur and wallpaper zoom float fromDepthRatio = BACKGROUND_APP.getDepth(activity); float toDepthRatio = OVERVIEW.getDepth(activity); - pa.addFloat(getDepthController(), + pa.addFloat(getDepthController().stateDepth, new LauncherAnimUtils.ClampedProperty<>( - DepthController.STATE_DEPTH, fromDepthRatio, toDepthRatio), + MULTI_PROPERTY_VALUE, fromDepthRatio, toDepthRatio), fromDepthRatio, toDepthRatio, LINEAR); } }; diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 7d6bbaccd1..9d5e7c362c 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -36,7 +36,7 @@ import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncest import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; import static com.android.launcher3.anim.Interpolators.clampToProgress; -import static com.android.launcher3.statehandlers.DepthController.STATE_DEPTH; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -376,8 +376,8 @@ public final class TaskViewUtils { }); if (depthController != null) { - out.setFloat(depthController, STATE_DEPTH, BACKGROUND_APP.getDepth(baseActivity), - TOUCH_RESPONSE_INTERPOLATOR); + out.setFloat(depthController.stateDepth, MULTI_PROPERTY_VALUE, + BACKGROUND_APP.getDepth(baseActivity), TOUCH_RESPONSE_INTERPOLATOR); } } diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 19a6c38901..062e50e30b 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -45,7 +45,7 @@ import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; -import com.android.launcher3.util.MultiValueAlpha; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.quickstep.RecentsActivity; import com.android.quickstep.views.ClearAllButton; @@ -95,7 +95,7 @@ public class FallbackRecentsStateController implements StateHandler DEPTH_PROPERTY_FACTORY = - new MultiPropertyFactory<>("depthProperty", DEPTH, Float::max); - - private static final int DEPTH_INDEX_STATE_TRANSITION = 1; - private static final int DEPTH_INDEX_WIDGET = 2; - - /** Property to set the depth for state transition. */ - public static final FloatProperty STATE_DEPTH = - DEPTH_PROPERTY_FACTORY.get(DEPTH_INDEX_STATE_TRANSITION); - /** Property to set the depth for widget picker. */ - public static final FloatProperty WIDGET_DEPTH = - DEPTH_PROPERTY_FACTORY.get(DEPTH_INDEX_WIDGET); + private static final int DEPTH_INDEX_STATE_TRANSITION = 0; + private static final int DEPTH_INDEX_WIDGET = 1; + private static final int DEPTH_INDEX_COUNT = 2; protected final Launcher mLauncher; + /** Property to set the depth for state transition. */ + public final MultiProperty stateDepth; + /** Property to set the depth for widget picker. */ + public final MultiProperty widgetDepth; /** * Blur radius when completely zoomed out, in pixels. @@ -92,6 +88,11 @@ public class BaseDepthController { mLauncher = activity; mMaxBlurRadius = activity.getResources().getInteger(R.integer.max_depth_blur_radius); mWallpaperManager = activity.getSystemService(WallpaperManager.class); + + MultiPropertyFactory depthProperty = + new MultiPropertyFactory<>(this, DEPTH, DEPTH_INDEX_COUNT, Float::max); + stateDepth = depthProperty.get(DEPTH_INDEX_STATE_TRANSITION); + widgetDepth = depthProperty.get(DEPTH_INDEX_WIDGET); } protected void setCrossWindowBlursEnabled(boolean isEnabled) { diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index 514d5b98bf..a16ff8fca1 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -33,8 +33,8 @@ import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.DisplayController; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiValueAlpha; -import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.NavigationMode; import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks; import com.android.quickstep.util.LayoutUtils; @@ -130,7 +130,6 @@ public class OverviewActionsView extends FrameLayo mMultiValueAlpha.setUpdateVisibility(true); findViewById(R.id.action_screenshot).setOnClickListener(this); - mSplitButton = findViewById(R.id.action_split); mSplitButton.setOnClickListener(this); } @@ -177,7 +176,7 @@ public class OverviewActionsView extends FrameLayo mHiddenFlags &= ~visibilityFlags; } boolean isHidden = mHiddenFlags != 0; - mMultiValueAlpha.getProperty(INDEX_HIDDEN_FLAGS_ALPHA).setValue(isHidden ? 0 : 1); + mMultiValueAlpha.get(INDEX_HIDDEN_FLAGS_ALPHA).setValue(isHidden ? 0 : 1); } /** @@ -232,20 +231,20 @@ public class OverviewActionsView extends FrameLayo updateSplitButtonEnabledState(); } - public AlphaProperty getContentAlpha() { - return mMultiValueAlpha.getProperty(INDEX_CONTENT_ALPHA); + public MultiProperty getContentAlpha() { + return mMultiValueAlpha.get(INDEX_CONTENT_ALPHA); } - public AlphaProperty getVisibilityAlpha() { - return mMultiValueAlpha.getProperty(INDEX_VISIBILITY_ALPHA); + public MultiProperty getVisibilityAlpha() { + return mMultiValueAlpha.get(INDEX_VISIBILITY_ALPHA); } - public AlphaProperty getFullscreenAlpha() { - return mMultiValueAlpha.getProperty(INDEX_FULLSCREEN_ALPHA); + public MultiProperty getFullscreenAlpha() { + return mMultiValueAlpha.get(INDEX_FULLSCREEN_ALPHA); } - public AlphaProperty getShareTargetAlpha() { - return mMultiValueAlpha.getProperty(INDEX_SHARE_TARGET_ALPHA); + public MultiProperty getShareTargetAlpha() { + return mMultiValueAlpha.get(INDEX_SHARE_TARGET_ALPHA); } /** diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 72467e6cd3..ce96b7168e 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -45,10 +45,10 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN; -import static com.android.launcher3.statehandlers.DepthController.STATE_DEPTH; import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK; @@ -147,7 +147,6 @@ import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; -import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.ResourceBasedOverride.Overrides; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; @@ -1897,7 +1896,7 @@ public abstract class RecentsView - mAppsViewTranslationYPropertyFactory = new MultiPropertyFactory<>( - "appsViewTranslationY", View.TRANSLATION_Y, Float::sum); private MultiValueAlpha mAppsViewAlpha; + private MultiPropertyFactory mAppsViewTranslationY; private boolean mIsTablet; @@ -184,7 +182,7 @@ public class AllAppsTransitionController */ public void setProgress(float progress) { mProgress = progress; - getAppsViewProgressTranslationY().set(mAppsView, mProgress * mShiftRange); + getAppsViewProgressTranslationY().setValue(mProgress * mShiftRange); mLauncher.onAllAppsTransition(1 - progress); } @@ -192,20 +190,20 @@ public class AllAppsTransitionController return mProgress; } - private FloatProperty getAppsViewProgressTranslationY() { - return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PROGRESS); + private MultiProperty getAppsViewProgressTranslationY() { + return mAppsViewTranslationY.get(INDEX_APPS_VIEW_PROGRESS); } - private FloatProperty getAppsViewPullbackTranslationY() { - return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PULLBACK); + private MultiProperty getAppsViewPullbackTranslationY() { + return mAppsViewTranslationY.get(INDEX_APPS_VIEW_PULLBACK); } - private MultiValueAlpha.AlphaProperty getAppsViewProgressAlpha() { - return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PROGRESS); + private MultiProperty getAppsViewProgressAlpha() { + return mAppsViewAlpha.get(INDEX_APPS_VIEW_PROGRESS); } - private MultiValueAlpha.AlphaProperty getAppsViewPullbackAlpha() { - return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PULLBACK); + private MultiProperty getAppsViewPullbackAlpha() { + return mAppsViewAlpha.get(INDEX_APPS_VIEW_PULLBACK); } /** @@ -283,7 +281,7 @@ public class AllAppsTransitionController boolean hasAllAppsContent = (visibleElements & ALL_APPS_CONTENT) != 0; Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR); - setter.setFloat(getAppsViewProgressAlpha(), MultiValueAlpha.VALUE, + setter.setFloat(getAppsViewProgressAlpha(), MultiPropertyFactory.MULTI_PROPERTY_VALUE, hasAllAppsContent ? 1 : 0, allAppsFade); boolean shouldProtectHeader = @@ -302,8 +300,11 @@ public class AllAppsTransitionController mScrimView = scrimView; mAppsView = appsView; mAppsView.setScrimView(scrimView); + mAppsViewAlpha = new MultiValueAlpha(mAppsView, APPS_VIEW_INDEX_COUNT); mAppsViewAlpha.setUpdateVisibility(true); + mAppsViewTranslationY = new MultiPropertyFactory<>( + mAppsView, VIEW_TRANSLATE_Y, APPS_VIEW_INDEX_COUNT, Float::sum); } /** diff --git a/src/com/android/launcher3/util/MultiPropertyFactory.java b/src/com/android/launcher3/util/MultiPropertyFactory.java index 43daf087ee..f34c4c2451 100644 --- a/src/com/android/launcher3/util/MultiPropertyFactory.java +++ b/src/com/android/launcher3/util/MultiPropertyFactory.java @@ -16,10 +16,13 @@ package com.android.launcher3.util; -import android.util.ArrayMap; +import android.animation.Animator; +import android.animation.ObjectAnimator; import android.util.FloatProperty; import android.util.Log; -import android.util.Property; + +import java.io.PrintWriter; +import java.util.Arrays; /** * Allows to combine multiple values set by several sources. @@ -35,15 +38,30 @@ import android.util.Property; */ public class MultiPropertyFactory { + public static final FloatProperty.MultiProperty> MULTI_PROPERTY_VALUE = + new FloatProperty.MultiProperty>("value") { + + @Override + public Float get(MultiPropertyFactory.MultiProperty property) { + return property.mValue; + } + + @Override + public void setValue(MultiPropertyFactory.MultiProperty property, float value) { + property.setValue(value); + } + }; + private static final boolean DEBUG = false; private static final String TAG = "MultiPropertyFactory"; - private final String mName; - private final ArrayMap mProperties = new ArrayMap<>(); + private final MultiPropertyFactory.MultiProperty[] mProperties; // This is an optimization for cases when set is called repeatedly with the same setterIndex. private float mAggregationOfOthers = 0f; - private Integer mLastIndexSet = -1; - private final Property mProperty; + private int mLastIndexSet = -1; + + protected final T mTarget; + private final FloatProperty mProperty; private final FloatBiFunction mAggregator; /** @@ -56,59 +74,99 @@ public class MultiPropertyFactory { float apply(float a, float b); } - public MultiPropertyFactory(String name, Property property, + public MultiPropertyFactory(T target, FloatProperty property, int size, FloatBiFunction aggregator) { - mName = name; + this(target, property, size, aggregator, 0); + } + + public MultiPropertyFactory(T target, FloatProperty property, int size, + FloatBiFunction aggregator, float defaultPropertyValue) { + mTarget = target; mProperty = property; mAggregator = aggregator; + + mProperties = new MultiPropertyFactory.MultiProperty[size]; + for (int i = 0; i < size; i++) { + mProperties[i] = new MultiProperty(i, defaultPropertyValue); + } } /** Returns the [MultiFloatProperty] associated with [inx], creating it if not present. */ - public MultiProperty get(Integer index) { - return mProperties.computeIfAbsent(index, - (k) -> new MultiProperty(index, mName + "_" + index)); + public MultiProperty get(int index) { + return (MultiProperty) mProperties[index]; + } + + @Override + public String toString() { + return Arrays.deepToString(mProperties); + } + + /** + * Dumps the alpha channel values to the given PrintWriter + * + * @param prefix String to be used before every line + * @param pw PrintWriter where the logs should be dumped + * @param label String used to help identify this object + * @param alphaIndexLabels Strings that represent each alpha channel, these should be entered + * in the order of the indexes they represent, starting from 0. + */ + public void dump(String prefix, PrintWriter pw, String label, String... alphaIndexLabels) { + pw.println(prefix + label); + + String innerPrefix = prefix + '\t'; + for (int i = 0; i < alphaIndexLabels.length; i++) { + if (i >= mProperties.length) { + pw.println(innerPrefix + alphaIndexLabels[i] + " given for alpha index " + i + + " however there are only " + mProperties.length + " alpha channels."); + continue; + } + pw.println(innerPrefix + alphaIndexLabels[i] + "=" + get(i).getValue()); + } } /** * Each [setValue] will be aggregated with the other properties values created by the * corresponding factory. */ - class MultiProperty extends FloatProperty { - private final int mInx; - private float mValue = 0f; + public class MultiProperty { - MultiProperty(int inx, String name) { - super(name); + private final int mInx; + private final float mDefaultValue; + private float mValue; + + MultiProperty(int inx, float defaultValue) { mInx = inx; + mDefaultValue = defaultValue; + mValue = defaultValue; } - @Override - public void setValue(T obj, float newValue) { + public void setValue(float newValue) { if (mLastIndexSet != mInx) { - mAggregationOfOthers = 0f; - mProperties.forEach((key, property) -> { - if (key != mInx) { + mAggregationOfOthers = mDefaultValue; + for (MultiPropertyFactory.MultiProperty other : mProperties) { + if (other.mInx != mInx) { mAggregationOfOthers = - mAggregator.apply(mAggregationOfOthers, property.mValue); + mAggregator.apply(mAggregationOfOthers, other.mValue); } - }); + } + mLastIndexSet = mInx; } float lastAggregatedValue = mAggregator.apply(mAggregationOfOthers, newValue); mValue = newValue; - apply(obj, lastAggregatedValue); + apply(lastAggregatedValue); if (DEBUG) { - Log.d(TAG, "name=" + mName - + " newValue=" + newValue + " mInx=" + mInx - + " aggregated=" + lastAggregatedValue + " others= " + mProperties); + Log.d(TAG, "name=" + mProperty.getName() + + " target=" + mTarget.getClass() + + " newValue=" + newValue + + " mInx=" + mInx + + " aggregated=" + lastAggregatedValue + + " others= " + Arrays.deepToString(mProperties)); } } - @Override - public Float get(T object) { - // Callers of MultiProperty should only care about the sub-property that it sets. If - // the overall value is needed, mProperty.get should be called directly. + public float getValue() { return mValue; } @@ -116,9 +174,19 @@ public class MultiPropertyFactory { public String toString() { return String.valueOf(mValue); } + + /** + * Creates and returns an Animator from the current value to the given value. Future + * animator on the same target automatically cancels the previous one. + */ + public Animator animateToValue(float value) { + ObjectAnimator animator = ObjectAnimator.ofFloat(this, MULTI_PROPERTY_VALUE, value); + animator.setAutoCancel(true); + return animator; + } } - protected void apply(T object, float value) { - mProperty.set(object, value); + protected void apply(float value) { + mProperty.set(mTarget, value); } } diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java index 4b46a0a04c..ac016a8595 100644 --- a/src/com/android/launcher3/util/MultiValueAlpha.java +++ b/src/com/android/launcher3/util/MultiValueAlpha.java @@ -16,62 +16,24 @@ package com.android.launcher3.util; -import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.util.FloatProperty; +import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; + import android.view.View; import com.android.launcher3.anim.AlphaUpdateListener; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.function.Consumer; - /** * Utility class to handle separating a single value as a factor of multiple values */ -public class MultiValueAlpha { +public class MultiValueAlpha extends MultiPropertyFactory { - public static final FloatProperty VALUE = - new FloatProperty("value") { + private static final FloatBiFunction ALPHA_AGGREGATOR = (a, b) -> a * b; - @Override - public Float get(AlphaProperty alphaProperty) { - return alphaProperty.mValue; - } - - @Override - public void setValue(AlphaProperty object, float value) { - object.setValue(value); - } - }; - - private final View mView; - private final AlphaProperty[] mMyProperties; - - private int mValidMask; // Whether we should change from INVISIBLE to VISIBLE and vice versa at low alpha values. private boolean mUpdateVisibility; public MultiValueAlpha(View view, int size) { - mView = view; - mMyProperties = new AlphaProperty[size]; - - mValidMask = 0; - for (int i = 0; i < size; i++) { - int myMask = 1 << i; - mValidMask |= myMask; - mMyProperties[i] = new AlphaProperty(myMask); - } - } - - @Override - public String toString() { - return Arrays.toString(mMyProperties); - } - - public AlphaProperty getProperty(int index) { - return mMyProperties[index]; + super(view, VIEW_ALPHA, size, ALPHA_AGGREGATOR, 1f); } /** Sets whether we should update between INVISIBLE and VISIBLE based on alpha. */ @@ -79,97 +41,11 @@ public class MultiValueAlpha { mUpdateVisibility = updateVisibility; } - /** - * Dumps the alpha channel values to the given PrintWriter - * - * @param prefix String to be used before every line - * @param pw PrintWriter where the logs should be dumped - * @param label String used to help identify this object - * @param alphaIndexLabels Strings that represent each alpha channel, these should be entered - * in the order of the indexes they represent, starting from 0. - */ - public void dump(String prefix, PrintWriter pw, String label, String... alphaIndexLabels) { - pw.println(prefix + label); - - String innerPrefix = prefix + '\t'; - for (int i = 0; i < alphaIndexLabels.length; i++) { - if (i >= mMyProperties.length) { - pw.println(innerPrefix + alphaIndexLabels[i] + " given for alpha index " + i - + " however there are only " + mMyProperties.length + " alpha channels."); - continue; - } - pw.println(innerPrefix + alphaIndexLabels[i] + "=" + getProperty(i).getValue()); - } - } - - public class AlphaProperty { - - private final int mMyMask; - - private float mValue = 1; - // Factor of all other alpha channels, only valid if mMyMask is present in mValidMask. - private float mOthers = 1; - - private Consumer mConsumer; - - AlphaProperty(int myMask) { - mMyMask = myMask; - } - - public void setValue(float value) { - if (mValue == value) { - return; - } - - if ((mValidMask & mMyMask) == 0) { - // Our cache value is not correct, recompute it. - mOthers = 1; - for (AlphaProperty prop : mMyProperties) { - if (prop != this) { - mOthers *= prop.mValue; - } - } - } - - // Since we have changed our value, all other caches except our own need to be - // recomputed. Change mValidMask to indicate the new valid caches (only our own). - mValidMask = mMyMask; - mValue = value; - - final float alpha = mOthers * mValue; - mView.setAlpha(alpha); - if (mUpdateVisibility) { - AlphaUpdateListener.updateVisibility(mView); - } - if (mConsumer != null) { - mConsumer.accept(mValue); - } - } - - public float getValue() { - return mValue; - } - - public void setConsumer(Consumer consumer) { - mConsumer = consumer; - if (mConsumer != null) { - mConsumer.accept(mValue); - } - } - - @Override - public String toString() { - return Float.toString(mValue); - } - - /** - * Creates and returns an Animator from the current value to the given value. Future - * animator on the same target automatically cancels the previous one. - */ - public Animator animateToValue(float value) { - ObjectAnimator animator = ObjectAnimator.ofFloat(this, VALUE, value); - animator.setAutoCancel(true); - return animator; + @Override + protected void apply(float value) { + super.apply(value); + if (mUpdateVisibility) { + AlphaUpdateListener.updateVisibility(mTarget); } } } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 1e154a2dfb..77992a2e89 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -22,7 +22,6 @@ import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs; -import android.app.WallpaperManager; import android.content.Context; import android.graphics.Insets; import android.graphics.Rect; @@ -41,8 +40,8 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.Utilities; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiValueAlpha; -import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.TouchController; import java.io.PrintWriter; @@ -108,7 +107,6 @@ public abstract class BaseDragLayer protected final T mActivity; private final MultiValueAlpha mMultiValueAlpha; - private final WallpaperManager mWallpaperManager; // All the touch controllers for the view protected TouchController[] mControllers; @@ -121,9 +119,8 @@ public abstract class BaseDragLayer public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) { super(context, attrs); - mActivity = (T) ActivityContext.lookupContext(context); + mActivity = ActivityContext.lookupContext(context); mMultiValueAlpha = new MultiValueAlpha(this, alphaChannelCount); - mWallpaperManager = context.getSystemService(WallpaperManager.class); } /** @@ -508,8 +505,8 @@ public abstract class BaseDragLayer return new LayoutParams(p); } - public AlphaProperty getAlphaProperty(int index) { - return mMultiValueAlpha.getProperty(index); + public MultiProperty getAlphaProperty(int index) { + return mMultiValueAlpha.get(index); } public void dump(String prefix, PrintWriter writer) { diff --git a/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt b/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt index a4f189c6b3..bf3a092adb 100644 --- a/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt +++ b/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt @@ -39,21 +39,21 @@ class MultiPropertyFactoryTest { } } - private val factory = MultiPropertyFactory("depth_property", receiveProperty) { + private val factory = MultiPropertyFactory(null, receiveProperty, 3) { x: Float, y: Float -> x + y } - private val p1 = factory.get(1) - private val p2 = factory.get(2) - private val p3 = factory.get(3) + private val p1 = factory.get(0) + private val p2 = factory.get(1) + private val p3 = factory.get(2) @Test fun set_sameIndexes_allApplied() { val v1 = 50f val v2 = 100f - p1.set(null, v1) - p1.set(null, v1) - p1.set(null, v2) + p1.value = v1 + p1.value = v1 + p1.value = v2 assertThat(received).containsExactly(v1, v1, v2) } @@ -63,9 +63,9 @@ class MultiPropertyFactoryTest { val v1 = 50f val v2 = 100f val v3 = 150f - p1.set(null, v1) - p2.set(null, v2) - p3.set(null, v3) + p1.value = v1 + p2.value = v2 + p3.value = v3 assertThat(received).containsExactly(v1, v1 + v2, v1 + v2 + v3) }