Revert "Merging from ub-launcher3-master @ build 6294827"
Revert "Merging from ub-launcher3-master @ build 6294827"
Revert "Merging from ub-launcher3-master @ build 6294827"
Revert "Merging from ub-launcher3-master @ build 6294827"
Revert "Merging from ub-launcher3-master @ build 6294827"
Revert submission 10673936-merge_ub-launcher3-master_6294827
Reason for revert: b/151611270
Reverted Changes:
I38a587a1b:Merging from ub-launcher3-master @ build 6294827
I74ae8bea8:Merging from ub-launcher3-master @ build 6294827
I115742e03:Merging from ub-launcher3-master @ build 6294827
Iceb1e8523:Merging from ub-launcher3-master @ build 6294827
Ie242e3907:Merging from ub-launcher3-master @ build 6294827
I609b18fdd:Merging from ub-launcher3-master @ build 6294827
Change-Id: I96f08492cb92e2f670375269423d8b45a81312cf
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 814b728..217a41c 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -40,6 +40,7 @@
import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -51,10 +52,8 @@
import java.lang.annotation.Retention;
import java.util.ArrayList;
-/**
- * Launcher BaseActivity
- */
-public abstract class BaseActivity extends Activity implements LogStateProvider, ActivityContext {
+public abstract class BaseActivity extends Activity
+ implements UserEventDelegate, LogStateProvider, ActivityContext {
private static final String TAG = "BaseActivity";
@@ -156,7 +155,7 @@
public final UserEventDispatcher getUserEventDispatcher() {
if (mUserEventDispatcher == null) {
- mUserEventDispatcher = UserEventDispatcher.newInstance(this);
+ mUserEventDispatcher = UserEventDispatcher.newInstance(this, this);
}
return mUserEventDispatcher;
}
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 38e1201..864fa6e 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -22,11 +22,11 @@
import android.view.View;
import android.view.ViewGroup;
-import androidx.recyclerview.widget.RecyclerView;
-
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.views.RecyclerViewFastScroller;
+import androidx.recyclerview.widget.RecyclerView;
+
/**
* A base {@link RecyclerView}, which does the following:
@@ -138,7 +138,7 @@
if (getCurrentScrollY() == 0) {
return true;
}
- return getAdapter() == null || getAdapter().getItemCount() == 0;
+ return false;
}
/**
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 76cfe1c..b89e727 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -16,13 +16,12 @@
package com.android.launcher3;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -33,8 +32,6 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.views.Transposable;
-import java.util.ArrayList;
-
public class Hotseat extends CellLayout implements LogContainerProvider, Insettable, Transposable {
@ViewDebug.ExportedProperty(category = "launcher")
@@ -78,12 +75,10 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- child.rank = childInfo.rank;
- child.gridX = childInfo.cellX;
- child.gridY = childInfo.cellY;
- parents.add(newContainerTarget(LauncherLogProto.ContainerType.HOTSEAT));
+ public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
+ target.gridX = info.cellX;
+ target.gridY = info.cellY;
+ targetParent.containerType = LauncherLogProto.ContainerType.HOTSEAT;
}
@Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1413a5c..965b87b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -30,6 +30,7 @@
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newTarget;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
@@ -77,7 +78,6 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
@@ -110,6 +110,7 @@
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.ModelWriter;
@@ -124,8 +125,8 @@
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -182,7 +183,8 @@
* Default launcher application.
*/
public class Launcher extends BaseDraggingActivity implements LauncherExterns,
- Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {
+ Callbacks, UserEventDelegate,
+ InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {
public static final String TAG = "Launcher";
public static final ActivityTracker<Launcher> ACTIVITY_TRACKER = new ActivityTracker<>();
@@ -326,19 +328,6 @@
private boolean mDeferOverlayCallbacks;
private final Runnable mDeferredOverlayCallbacks = this::checkIfOverlayStillDeferred;
- private BackgroundBlurController mBackgroundBlurController =
- new BackgroundBlurController(this);
-
- private final ViewTreeObserver.OnDrawListener mOnDrawListener =
- new ViewTreeObserver.OnDrawListener() {
- @Override
- public void onDraw() {
- getBackgroundBlurController().setSurfaceToLauncher(mDragLayer);
- mDragLayer.post(() -> mDragLayer.getViewTreeObserver().removeOnDrawListener(
- this));
- }
- };
-
@Override
protected void onCreate(Bundle savedInstanceState) {
Object traceToken = TraceHelper.INSTANCE.beginSection(ON_CREATE_EVT,
@@ -940,8 +929,6 @@
final int origDragLayerChildCount = mDragLayer.getChildCount();
super.onStop();
- mDragLayer.getViewTreeObserver().removeOnDrawListener(mOnDrawListener);
-
if (mDeferOverlayCallbacks) {
checkIfOverlayStillDeferred();
} else {
@@ -954,7 +941,6 @@
NotificationListener.removeNotificationsChangedListener();
getStateManager().moveToRestState();
- getBackgroundBlurController().setSurfaceToLauncher(null);
// Workaround for b/78520668, explicitly trim memory once UI is hidden
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
@@ -982,7 +968,6 @@
if (!mDeferOverlayCallbacks) {
mOverlayManager.onActivityStarted(this);
}
- mDragLayer.getViewTreeObserver().addOnDrawListener(mOnDrawListener);
mAppWidgetHost.setListenIfResumed(true);
TraceHelper.INSTANCE.endSection(traceToken);
@@ -1905,6 +1890,24 @@
}
@Override
+ public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {
+ if (event.srcTarget != null && event.srcTarget.length > 0 &&
+ event.srcTarget[1].containerType == ContainerType.PREDICTION) {
+ Target[] targets = new Target[3];
+ targets[0] = event.srcTarget[0];
+ targets[1] = event.srcTarget[1];
+ targets[2] = newTarget(Target.Type.CONTAINER);
+ event.srcTarget = targets;
+ LauncherState state = mStateManager.getState();
+ if (state == LauncherState.ALL_APPS) {
+ event.srcTarget[2].containerType = ContainerType.ALLAPPS;
+ } else if (state == OVERVIEW) {
+ event.srcTarget[2].containerType = ContainerType.TASKSWITCHER;
+ }
+ }
+ }
+
+ @Override
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
@Nullable String sourceContainer) {
if (!hasBeenResumed()) {
@@ -2707,8 +2710,7 @@
}
protected StateHandler[] createStateHandlers() {
- return new StateHandler[] { getAllAppsController(), getWorkspace(),
- getBackgroundBlurController() };
+ return new StateHandler[] { getAllAppsController(), getWorkspace() };
}
public TouchController[] createTouchControllers() {
@@ -2745,12 +2747,8 @@
return Stream.of(APP_INFO, WIDGETS, INSTALL);
}
- public BackgroundBlurController getBackgroundBlurController() {
- return mBackgroundBlurController;
- }
-
public static Launcher getLauncher(Context context) {
- return fromContext(context);
+ return (Launcher) fromContext(context);
}
/**
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index d9cf7f1..32e9c14 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -18,7 +18,7 @@
import android.graphics.drawable.Drawable;
import android.util.FloatProperty;
-import android.util.IntProperty;
+import android.util.Property;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
@@ -32,15 +32,15 @@
// The progress of an animation to all apps must be at least this far along to snap to all apps.
public static final float MIN_PROGRESS_TO_ALL_APPS = 0.5f;
- public static final IntProperty<Drawable> DRAWABLE_ALPHA =
- new IntProperty<Drawable>("drawableAlpha") {
+ public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
+ new Property<Drawable, Integer>(Integer.TYPE, "drawableAlpha") {
@Override
public Integer get(Drawable drawable) {
return drawable.getAlpha();
}
@Override
- public void setValue(Drawable drawable, int alpha) {
+ public void set(Drawable drawable, Integer alpha) {
drawable.setAlpha(alpha);
}
};
@@ -64,28 +64,28 @@
return (int) Utilities.boundToRange(Math.abs(velocity) / 2, 2f, 6f);
}
- public static final IntProperty<LayoutParams> LAYOUT_WIDTH =
- new IntProperty<LayoutParams>("width") {
+ public static final Property<LayoutParams, Integer> LAYOUT_WIDTH =
+ new Property<LayoutParams, Integer>(Integer.TYPE, "width") {
@Override
public Integer get(LayoutParams lp) {
return lp.width;
}
@Override
- public void setValue(LayoutParams lp, int width) {
+ public void set(LayoutParams lp, Integer width) {
lp.width = width;
}
};
- public static final IntProperty<LayoutParams> LAYOUT_HEIGHT =
- new IntProperty<LayoutParams>("height") {
+ public static final Property<LayoutParams, Integer> LAYOUT_HEIGHT =
+ new Property<LayoutParams, Integer>(Integer.TYPE, "height") {
@Override
public Integer get(LayoutParams lp) {
return lp.height;
}
@Override
- public void setValue(LayoutParams lp, int height) {
+ public void set(LayoutParams lp, Integer height) {
lp.height = height;
}
};
@@ -117,18 +117,4 @@
return view.getTranslationY();
}
};
-
- public static final FloatProperty<View> VIEW_ALPHA =
- View.ALPHA instanceof FloatProperty ? (FloatProperty) View.ALPHA
- : new FloatProperty<View>("alpha") {
- @Override
- public void setValue(View view, float v) {
- view.setAlpha(v);
- }
-
- @Override
- public Float get(View view) {
- return view.getAlpha();
- }
- };
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 62b8927..36440c9 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -41,7 +41,6 @@
import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
-import android.content.Context;
import android.view.View;
import android.view.animation.Interpolator;
@@ -270,14 +269,6 @@
return 0;
}
- /**
- * The amount of blur to apply to the background of either the app or Launcher surface in this
- * state.
- */
- public int getBackgroundBlurRadius(Context context) {
- return 0;
- }
-
public String getDescription(Launcher launcher) {
return launcher.getWorkspace().getCurrentPageDescription();
}
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 04134f2..9f25729 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -88,22 +88,20 @@
// components may be run atomically - that is, all at once, instead of user-controlled. However,
// atomic components are not restricted to this purpose; they can be user-controlled alongside
// non atomic components as well. Note that each gesture model has exactly one atomic component,
- // PLAY_ATOMIC_OVERVIEW_SCALE *or* PLAY_ATOMIC_OVERVIEW_PEEK.
+ // ATOMIC_OVERVIEW_SCALE_COMPONENT *or* ATOMIC_OVERVIEW_PEEK_COMPONENT.
@IntDef(flag = true, value = {
- PLAY_NON_ATOMIC,
- PLAY_ATOMIC_OVERVIEW_SCALE,
- PLAY_ATOMIC_OVERVIEW_PEEK,
- SKIP_OVERVIEW,
+ NON_ATOMIC_COMPONENT,
+ ATOMIC_OVERVIEW_SCALE_COMPONENT,
+ ATOMIC_OVERVIEW_PEEK_COMPONENT,
})
@Retention(RetentionPolicy.SOURCE)
- public @interface AnimationFlags {}
- public static final int PLAY_NON_ATOMIC = 1 << 0;
- public static final int PLAY_ATOMIC_OVERVIEW_SCALE = 1 << 1;
- public static final int PLAY_ATOMIC_OVERVIEW_PEEK = 1 << 2;
- public static final int SKIP_OVERVIEW = 1 << 3;
+ public @interface AnimationComponents {}
+ public static final int NON_ATOMIC_COMPONENT = 1 << 0;
+ public static final int ATOMIC_OVERVIEW_SCALE_COMPONENT = 1 << 1;
+ public static final int ATOMIC_OVERVIEW_PEEK_COMPONENT = 1 << 2;
- public static final int ANIM_ALL_COMPONENTS = PLAY_NON_ATOMIC | PLAY_ATOMIC_OVERVIEW_SCALE
- | PLAY_ATOMIC_OVERVIEW_PEEK;
+ public static final int ANIM_ALL = NON_ATOMIC_COMPONENT | ATOMIC_OVERVIEW_SCALE_COMPONENT
+ | ATOMIC_OVERVIEW_PEEK_COMPONENT;
private final AnimationConfig mConfig = new AnimationConfig();
private final Handler mUiHandler;
@@ -246,8 +244,12 @@
} else if (!mConfig.userControlled && animated && mConfig.mTargetState == state) {
// We are running the same animation as requested
if (onCompleteRunnable != null) {
- mConfig.mCurrentAnimation.addListener(
- AnimationSuccessListener.forRunnable(onCompleteRunnable));
+ mConfig.mCurrentAnimation.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ onCompleteRunnable.run();
+ }
+ });
}
return;
}
@@ -313,10 +315,10 @@
}
public AnimatorSet createAtomicAnimation(LauncherState fromState, LauncherState toState,
- AnimatorSetBuilder builder, @AnimationFlags int animFlags, long duration) {
+ AnimatorSetBuilder builder, @AnimationComponents int atomicComponent, long duration) {
prepareForAtomicAnimation(fromState, toState, builder);
AnimationConfig config = new AnimationConfig();
- config.mAnimFlags = animFlags;
+ config.animComponents = atomicComponent;
config.duration = duration;
for (StateHandler handler : mLauncher.getStateManager().getStateHandlers()) {
handler.setStateWithAnimation(toState, builder, config);
@@ -357,25 +359,25 @@
*/
public AnimatorPlaybackController createAnimationToNewWorkspace(
LauncherState state, long duration) {
- return createAnimationToNewWorkspace(state, duration, ANIM_ALL_COMPONENTS);
+ return createAnimationToNewWorkspace(state, duration, LauncherStateManager.ANIM_ALL);
}
public AnimatorPlaybackController createAnimationToNewWorkspace(
- LauncherState state, long duration, @AnimationFlags int animComponents) {
+ LauncherState state, long duration, @AnimationComponents int animComponents) {
return createAnimationToNewWorkspace(state, new AnimatorSetBuilder(), duration, null,
animComponents);
}
public AnimatorPlaybackController createAnimationToNewWorkspace(LauncherState state,
AnimatorSetBuilder builder, long duration, Runnable onCancelRunnable,
- @AnimationFlags int animComponents) {
+ @AnimationComponents int animComponents) {
mConfig.reset();
mConfig.userControlled = true;
- mConfig.mAnimFlags = animComponents;
+ mConfig.animComponents = animComponents;
mConfig.duration = duration;
mConfig.playbackController = AnimatorPlaybackController.wrap(
- createAnimationToNewWorkspaceInternal(state, builder, null), duration)
- .setOnCancelRunnable(onCancelRunnable);
+ createAnimationToNewWorkspaceInternal(state, builder, null), duration,
+ onCancelRunnable);
return mConfig.playbackController;
}
@@ -585,7 +587,7 @@
public long duration;
public boolean userControlled;
public AnimatorPlaybackController playbackController;
- private @AnimationFlags int mAnimFlags = ANIM_ALL_COMPONENTS;
+ public @AnimationComponents int animComponents = ANIM_ALL;
private PropertySetter mPropertySetter;
private AnimatorSet mCurrentAnimation;
@@ -599,7 +601,7 @@
public void reset() {
duration = 0;
userControlled = false;
- mAnimFlags = ANIM_ALL_COMPONENTS;
+ animComponents = ANIM_ALL;
mPropertySetter = null;
mTargetState = null;
@@ -640,39 +642,16 @@
mCurrentAnimation.addListener(this);
}
- /**
- * @return Whether Overview is scaling as part of this animation. If this is the only
- * component (i.e. NON_ATOMIC_COMPONENT isn't included), then this scaling is happening
- * atomically, rather than being part of a normal state animation. StateHandlers can use
- * this to designate part of their animation that should scale with Overview.
- */
public boolean playAtomicOverviewScaleComponent() {
- return hasAnimationFlag(PLAY_ATOMIC_OVERVIEW_SCALE);
+ return (animComponents & ATOMIC_OVERVIEW_SCALE_COMPONENT) != 0;
}
- /**
- * @return Whether this animation will play atomically at the same time as a different,
- * user-controlled state transition. StateHandlers, which contribute to both animations, can
- * use this to avoid animating the same properties in both animations, since they'd conflict
- * with one another.
- */
- public boolean onlyPlayAtomicComponent() {
- return getAnimComponents() == PLAY_ATOMIC_OVERVIEW_SCALE
- || getAnimComponents() == PLAY_ATOMIC_OVERVIEW_PEEK;
+ public boolean playAtomicOverviewPeekComponent() {
+ return (animComponents & ATOMIC_OVERVIEW_PEEK_COMPONENT) != 0;
}
- /**
- * Returns true if the config and any of the provided component flags
- */
- public boolean hasAnimationFlag(@AnimationFlags int a) {
- return (mAnimFlags & a) != 0;
- }
-
- /**
- * @return Only the flags that determine which animation components to play.
- */
- public @AnimationFlags int getAnimComponents() {
- return mAnimFlags & ANIM_ALL_COMPONENTS;
+ public boolean playNonAtomicComponent() {
+ return (animComponents & NON_ATOMIC_COMPONENT) != 0;
}
}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e38631d..a6180a6 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -42,6 +42,21 @@
import android.view.animation.Interpolator;
import android.widget.ScrollView;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.PagedViewOrientedState;
+import com.android.launcher3.pageindicators.PageIndicator;
+import com.android.launcher3.states.RotationHelper;
+import com.android.launcher3.touch.PortraitPagedViewHandler;
+import com.android.launcher3.touch.OverScroll;
+import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.touch.PagedOrientationHandler.ChildBounds;
+import com.android.launcher3.util.OverScroller;
+import com.android.launcher3.util.Thunk;
+
+import java.util.ArrayList;
+
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
@@ -50,20 +65,6 @@
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_BY;
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_TO;
-import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.PagedViewOrientedState;
-import com.android.launcher3.pageindicators.PageIndicator;
-import com.android.launcher3.touch.OverScroll;
-import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.touch.PagedOrientationHandler.ChildBounds;
-import com.android.launcher3.touch.PortraitPagedViewHandler;
-import com.android.launcher3.util.OverScroller;
-import com.android.launcher3.util.Thunk;
-
-import java.util.ArrayList;
-
/**
* An abstraction of the original Workspace which supports browsing through a
* sequential list of "pages"
@@ -72,6 +73,8 @@
private static final String TAG = "PagedView";
private static final boolean DEBUG = false;
+ public static boolean sFlagForcedRotation = false;
+
public static final int INVALID_PAGE = -1;
protected static final ComputePageScrollsLogic SIMPLE_SCROLL_LOGIC = (v) -> v.getVisibility() != GONE;
@@ -197,6 +200,8 @@
if (Utilities.ATLEAST_OREO) {
setDefaultFocusHighlightEnabled(false);
}
+
+ sFlagForcedRotation = Utilities.isForcedRotation(context);
}
protected void setDefaultInterpolator(Interpolator interpolator) {
@@ -1510,7 +1515,7 @@
// interpolator at zero, ie. 5. We use 4 to make it a little slower.
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
- if (QUICKSTEP_SPRINGS.get() && mCurrentPage != whichPage) {
+ if (QUICKSTEP_SPRINGS.get()) {
return snapToPage(whichPage, delta, duration, false, null,
velocity * Math.signum(delta), true);
} else {
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 2430d5e..1841134 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -41,7 +41,6 @@
import com.android.launcher3.util.Themes;
import java.net.URISyntaxException;
-import java.util.ArrayList;
/**
* Drop target which provides a secondary option for an item.
@@ -323,9 +322,9 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- mOriginal.fillInLogContainerData(childInfo, child, parents);
+ public void fillInLogContainerData(View v, ItemInfo info, Target target,
+ Target targetParent) {
+ mOriginal.fillInLogContainerData(v, info, target, targetParent);
}
@Override
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 122b393..9780630 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -17,6 +17,7 @@
package com.android.launcher3;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED;
+import static com.android.launcher3.states.RotationHelper.FIXED_ROTATION_TRANSFORM_SETTING_NAME;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
@@ -60,7 +61,6 @@
import android.view.ViewConfiguration;
import android.view.animation.Interpolator;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.graphics.TintedDrawableSpan;
@@ -128,6 +128,11 @@
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
}
+ public static boolean isForcedRotation(Context context) {
+ return Settings.Global.getInt(context.getContentResolver(),
+ FIXED_ROTATION_TRANSFORM_SETTING_NAME, 0) != 0;
+ }
+
// An intent extra to indicate the horizontal scroll of the wallpaper.
public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET";
public static final String EXTRA_WALLPAPER_FLAVOR = "com.android.launcher3.WALLPAPER_FLAVOR";
@@ -476,15 +481,6 @@
LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
}
- /**
- * @return {@link SharedPreferences} that backs {@link FeatureFlags}
- */
- public static SharedPreferences getFeatureFlagsPrefs(Context context) {
- // Use application context for shared preferences, so that we use a single cached instance
- return context.getApplicationContext().getSharedPreferences(
- FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE);
- }
-
public static boolean areAnimationsEnabled(Context context) {
return ATLEAST_OREO
? ValueAnimator.areAnimatorsEnabled()
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index fc1a074..590c620 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -24,7 +24,6 @@
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -3310,21 +3309,17 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- if (childInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
- || childInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) {
- getHotseat().fillInLogContainerData(childInfo, child, parents);
- return;
- } else if (childInfo.container >= 0) {
- FolderIcon icon = (FolderIcon) getHomescreenIconByItemId(childInfo.container);
- icon.getFolder().fillInLogContainerData(childInfo, child, parents);
- return;
+ public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
+ target.gridX = info.cellX;
+ target.gridY = info.cellY;
+ target.pageIndex = getCurrentPage();
+ targetParent.containerType = ContainerType.WORKSPACE;
+ if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+ target.rank = info.rank;
+ targetParent.containerType = ContainerType.HOTSEAT;
+ } else if (info.container >= 0) {
+ targetParent.containerType = ContainerType.FOLDER;
}
- child.gridX = childInfo.cellX;
- child.gridY = childInfo.cellY;
- child.pageIndex = getCurrentPage();
- parents.add(newContainerTarget(ContainerType.WORKSPACE));
}
/**
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 6653426..c33392d 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -18,9 +18,6 @@
import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_SCALE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_TRANSLATE;
@@ -120,7 +117,7 @@
hotseatIconsAlpha, fadeInterpolator);
}
- if (config.onlyPlayAtomicComponent()) {
+ if (!config.playNonAtomicComponent()) {
// Only the alpha and scale, handled above, are included in the atomic animation.
return;
}
@@ -128,18 +125,18 @@
Interpolator translationInterpolator = !playAtomicComponent
? LINEAR
: builder.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT);
- propertySetter.setFloat(mWorkspace, VIEW_TRANSLATE_X,
+ propertySetter.setFloat(mWorkspace, View.TRANSLATION_X,
scaleAndTranslation.translationX, translationInterpolator);
- propertySetter.setFloat(mWorkspace, VIEW_TRANSLATE_Y,
+ propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y,
scaleAndTranslation.translationY, translationInterpolator);
Interpolator hotseatTranslationInterpolator = builder.getInterpolator(
ANIM_HOTSEAT_TRANSLATE, translationInterpolator);
- propertySetter.setFloat(hotseat, VIEW_TRANSLATE_Y,
+ propertySetter.setFloat(hotseat, View.TRANSLATION_Y,
hotseatScaleAndTranslation.translationY, hotseatTranslationInterpolator);
- propertySetter.setFloat(mWorkspace.getPageIndicator(), VIEW_TRANSLATE_Y,
+ propertySetter.setFloat(mWorkspace.getPageIndicator(), View.TRANSLATION_Y,
hotseatScaleAndTranslation.translationY, hotseatTranslationInterpolator);
- propertySetter.setFloat(qsbView, VIEW_TRANSLATE_Y,
+ propertySetter.setFloat(qsbView, View.TRANSLATION_Y,
qsbScaleAndTranslation.translationY, hotseatTranslationInterpolator);
setScrim(propertySetter, state);
@@ -175,15 +172,14 @@
float pageAlpha = pageAlphaProvider.getPageAlpha(childIndex);
int drawableAlpha = Math.round(pageAlpha * (state.hasWorkspacePageBackground ? 255 : 0));
- if (!config.onlyPlayAtomicComponent()) {
- // Don't update the scrim during the atomic animation.
+ if (config.playNonAtomicComponent()) {
propertySetter.setInt(cl.getScrimBackground(),
DRAWABLE_ALPHA, drawableAlpha, ZOOM_OUT);
}
if (config.playAtomicOverviewScaleComponent()) {
Interpolator fadeInterpolator = builder.getInterpolator(ANIM_WORKSPACE_FADE,
pageAlphaProvider.interpolator);
- propertySetter.setFloat(cl.getShortcutsAndWidgets(), VIEW_ALPHA,
+ propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA,
pageAlpha, fadeInterpolator);
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index e085ff0..afb7217 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -15,7 +15,8 @@
*/
package com.android.launcher3.allapps;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -64,8 +65,6 @@
import com.android.launcher3.views.SpringRelativeLayout;
import com.android.launcher3.views.WorkFooterContainer;
-import java.util.ArrayList;
-
/**
* The all apps view container.
*/
@@ -328,10 +327,12 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- parents.add(newContainerTarget(
- getApps().hasFilter() ? ContainerType.SEARCHRESULT : ContainerType.ALLAPPS));
+ public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
+ if (getApps().hasFilter()) {
+ targetParent.containerType = ContainerType.SEARCHRESULT;
+ } else {
+ targetParent.containerType = ContainerType.ALLAPPS;
+ }
}
@Override
@@ -392,7 +393,7 @@
rebindAdapters(showTabs, false /* force */);
}
- protected void rebindAdapters(boolean showTabs, boolean force) {
+ private void rebindAdapters(boolean showTabs, boolean force) {
if (showTabs == mUsingTabs && !force) {
return;
}
@@ -460,7 +461,6 @@
public void onTabChanged(int pos) {
mHeader.setMainActive(pos == 0);
reset(true /* animate */);
- mViewPager.getPageIndicator().updateTabTextColor(pos);
if (mAH[pos].recyclerView != null) {
mAH[pos].recyclerView.bindFastScrollbar();
@@ -606,7 +606,6 @@
public static final int MAIN = 0;
public static final int WORK = 1;
- private ItemInfoMatcher mInfoMatcher;
private final boolean mIsWork;
public final AllAppsGridAdapter adapter;
final LinearLayoutManager layoutManager;
@@ -626,7 +625,6 @@
}
void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) {
- mInfoMatcher = matcher;
appsList.updateItemFilter(matcher);
recyclerView = (AllAppsRecyclerView) rv;
recyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
@@ -647,14 +645,19 @@
void setupOverlay() {
if (!mIsWork || recyclerView == null) return;
boolean workDisabled = UserCache.INSTANCE.get(mLauncher).isAnyProfileQuietModeEnabled();
- if (mWorkDisabled == workDisabled) return;
+ recyclerView.getOverlay().clear();
if (workDisabled) {
- appsList.updateItemFilter((info, cn) -> false);
- recyclerView.addAutoSizedOverlay(
- mLauncher.getLayoutInflater().inflate(R.layout.work_apps_paused, null));
- } else if (mInfoMatcher != null) {
- appsList.updateItemFilter(mInfoMatcher);
- recyclerView.clearAutoSizedOverlays();
+ View pausedOverlay = mLauncher.getLayoutInflater().inflate(
+ R.layout.work_apps_paused, null);
+ recyclerView.post(() -> {
+ int width = recyclerView.getWidth();
+ int height = recyclerView.getHeight() - mWorkFooterContainer.getHeight();
+ pausedOverlay.measure(makeMeasureSpec(recyclerView.getWidth(), EXACTLY),
+ makeMeasureSpec(recyclerView.getHeight(), EXACTLY));
+ pausedOverlay.layout(0, 0, width, height);
+ applyPadding();
+ });
+ recyclerView.getOverlay().add(pausedOverlay);
}
mWorkDisabled = workDisabled;
}
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 8fe4633..b6744cf 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -15,11 +15,7 @@
*/
package com.android.launcher3.allapps;
-import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.UNSPECIFIED;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
-
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import android.content.Context;
import android.content.res.Resources;
@@ -44,7 +40,6 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.views.RecyclerViewFastScroller;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -64,8 +59,6 @@
private AllAppsBackgroundDrawable mEmptySearchBackground;
private int mEmptySearchBackgroundTopOffset;
- private ArrayList<View> mAutoSizedOverlays = new ArrayList<>();
-
public AllAppsRecyclerView(Context context) {
this(context, null);
}
@@ -149,37 +142,15 @@
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
updateEmptySearchBackgroundBounds();
updatePoolSize();
- for (int i = 0; i < mAutoSizedOverlays.size(); i++) {
- View overlay = mAutoSizedOverlays.get(i);
- overlay.measure(makeMeasureSpec(w, EXACTLY), makeMeasureSpec(w, EXACTLY));
- overlay.layout(0, 0, w, h);
- }
- }
-
- /**
- * Adds an overlay that automatically rescales with the recyclerview.
- */
- public void addAutoSizedOverlay(View overlay) {
- mAutoSizedOverlays.add(overlay);
- getOverlay().add(overlay);
- onSizeChanged(getWidth(), getHeight(), getWidth(), getHeight());
- }
-
- /**
- * Clears auto scaling overlay views added by #addAutoSizedOverlay
- */
- public void clearAutoSizedOverlays() {
- for (View v : mAutoSizedOverlays) {
- getOverlay().remove(v);
- }
- mAutoSizedOverlays.clear();
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- parents.add(newContainerTarget(
- getApps().hasFilter() ? ContainerType.SEARCHRESULT : ContainerType.ALLAPPS));
+ public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
+ if (mApps.hasFilter()) {
+ targetParent.containerType = ContainerType.SEARCHRESULT;
+ } else {
+ targetParent.containerType = ContainerType.ALLAPPS;
+ }
}
public void onSearchResultsChanged() {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 744f4eb..2179162 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -12,6 +12,7 @@
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
+import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
import static com.android.launcher3.util.SystemUiController.UI_STATE_ALL_APPS;
import android.animation.Animator;
@@ -30,8 +31,11 @@
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
+import com.android.launcher3.anim.SpringObjectAnimator;
+import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ScrimView;
+import com.android.systemui.plugins.ResourceProvider;
/**
* Handles AllApps view transition.
@@ -162,7 +166,7 @@
return;
}
- if (config.onlyPlayAtomicComponent()) {
+ if (!config.playNonAtomicComponent()) {
// There is no atomic component for the all apps transition, so just return early.
return;
}
@@ -181,6 +185,14 @@
}
public Animator createSpringAnimation(float... progressValues) {
+ if (UNSTABLE_SPRINGS.get()) {
+ ResourceProvider rp = DynamicResource.provider(mLauncher);
+ float damping = rp.getFloat(R.dimen.all_apps_spring_damping_ratio);
+ float stiffness = rp.getFloat(R.dimen.all_apps_spring_stiffness);
+
+ return new SpringObjectAnimator<>(this, ALL_APPS_PROGRESS, 1f / mShiftRange,
+ damping, stiffness, progressValues);
+ }
return ObjectAnimator.ofFloat(this, ALL_APPS_PROGRESS, progressValues);
}
@@ -212,7 +224,12 @@
}
public AnimatorListenerAdapter getProgressAnimatorListener() {
- return AnimationSuccessListener.forRunnable(this::onProgressAnimationEnd);
+ return new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ onProgressAnimationEnd();
+ }
+ };
}
public void setupViews(AllAppsContainerView appsView) {
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 81e1b94..cc33af9 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.allapps;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
-
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Point;
@@ -372,7 +370,7 @@
}
allowTouchForwarding(hasAllAppsContent);
- setter.setFloat(mTabLayout, VIEW_ALPHA, hasAllAppsContent ? 1 : 0, headerFade);
+ setter.setFloat(mTabLayout, ALPHA, hasAllAppsContent ? 1 : 0, headerFade);
}
protected void allowTouchForwarding(boolean allow) {
diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
index 3e40392..0e39bbe 100644
--- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
@@ -71,10 +71,12 @@
mIsRtl = Utilities.isRtl(getResources());
}
- /**
- * Highlights tab with index pos
- */
- public void updateTabTextColor(int pos) {
+ private void updateIndicatorPosition(float scrollOffset) {
+ mScrollOffset = scrollOffset;
+ updateIndicatorPosition();
+ }
+
+ private void updateTabTextColor(int pos) {
mSelectedPosition = pos;
for (int i = 0; i < getChildCount(); i++) {
Button tab = (Button) getChildAt(i);
@@ -82,11 +84,6 @@
}
}
- private void updateIndicatorPosition(float scrollOffset) {
- mScrollOffset = scrollOffset;
- updateIndicatorPosition();
- }
-
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
diff --git a/src/com/android/launcher3/allapps/PluginHeaderRow.java b/src/com/android/launcher3/allapps/PluginHeaderRow.java
index 3089b18..535ef54 100644
--- a/src/com/android/launcher3/allapps/PluginHeaderRow.java
+++ b/src/com/android/launcher3/allapps/PluginHeaderRow.java
@@ -15,11 +15,10 @@
*/
package com.android.launcher3.allapps;
+import static android.view.View.ALPHA;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
-
import android.graphics.Rect;
import android.view.View;
import android.view.animation.Interpolator;
@@ -68,7 +67,7 @@
public void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent,
PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) {
// Don't use setViewAlpha as we want to control the visibility ourselves.
- setter.setFloat(mView, VIEW_ALPHA, hasAllAppsContent ? 1 : 0, headerFade);
+ setter.setFloat(mView, ALPHA, hasAllAppsContent ? 1 : 0, headerFade);
}
@Override
diff --git a/src/com/android/launcher3/anim/AnimationSuccessListener.java b/src/com/android/launcher3/anim/AnimationSuccessListener.java
index 9905e81..9448632 100644
--- a/src/com/android/launcher3/anim/AnimationSuccessListener.java
+++ b/src/com/android/launcher3/anim/AnimationSuccessListener.java
@@ -39,25 +39,4 @@
}
public abstract void onAnimationSuccess(Animator animator);
-
- /**
- * Returns an AnimationSuccessListener which runs the provided action on success
- */
- public static AnimationSuccessListener forRunnable(Runnable r) {
- return new RunnableSuccessListener(r);
- }
-
- private static class RunnableSuccessListener extends AnimationSuccessListener {
-
- private final Runnable mRunnable;
-
- private RunnableSuccessListener(Runnable r) {
- mRunnable = r;
- }
-
- @Override
- public void onAnimationSuccess(Animator animator) {
- mRunnable.run();
- }
- }
}
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 1fc21fd..1c277ab 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -16,9 +16,7 @@
package com.android.launcher3.anim;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.clampToProgress;
-import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
@@ -26,18 +24,17 @@
import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
-import android.content.Context;
-import android.util.FloatProperty;
+import android.util.Log;
import androidx.annotation.Nullable;
-
-import com.android.launcher3.Utilities;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringAnimation;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
+import java.util.Set;
/**
* Helper class to control the playback of an {@link AnimatorSet}, with custom interpolators
@@ -46,7 +43,14 @@
* Note: The implementation does not support start delays on child animations or
* sequential playbacks.
*/
-public class AnimatorPlaybackController implements ValueAnimator.AnimatorUpdateListener {
+public abstract class AnimatorPlaybackController implements ValueAnimator.AnimatorUpdateListener {
+
+ private static final String TAG = "AnimatorPlaybackCtrler";
+ private static boolean DEBUG = false;
+
+ public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration) {
+ return wrap(anim, duration, null);
+ }
/**
* Creates an animation controller for the provided animation.
@@ -54,41 +58,20 @@
* needs to be larger than the total number of pixels so that we don't have jittering due
* to float (animation-fraction * total duration) to int conversion.
*/
- public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration) {
+ public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration,
+ Runnable onCancelRunnable) {
+
/**
* TODO: use {@link AnimatorSet#setCurrentPlayTime(long)} once b/68382377 is fixed.
*/
- ArrayList<Holder> childAnims = new ArrayList<>();
- addAnimationHoldersRecur(anim, SpringProperty.DEFAULT, childAnims);
-
- return new AnimatorPlaybackController(anim, duration, childAnims);
+ return new AnimatorPlaybackControllerVL(anim, duration, onCancelRunnable);
}
- public static AnimatorPlaybackController wrap(PendingAnimation anim, long duration) {
- /**
- * TODO: use {@link AnimatorSet#setCurrentPlayTime(long)} once b/68382377 is fixed.
- */
- return new AnimatorPlaybackController(anim.anim, duration, anim.animHolders);
- }
-
- private static final FloatProperty<ValueAnimator> CURRENT_PLAY_TIME =
- new FloatProperty<ValueAnimator>("current-play-time") {
- @Override
- public void setValue(ValueAnimator animator, float v) {
- animator.setCurrentPlayTime((long) v);
- }
-
- @Override
- public Float get(ValueAnimator animator) {
- return (float) animator.getCurrentPlayTime();
- }
- };
-
private final ValueAnimator mAnimationPlayer;
private final long mDuration;
- private final AnimatorSet mAnim;
- private final Holder[] mChildAnimations;
+ protected final AnimatorSet mAnim;
+ private Set<SpringAnimation> mSprings;
protected float mCurrentFraction;
private Runnable mEndAction;
@@ -96,14 +79,22 @@
protected boolean mTargetCancelled = false;
protected Runnable mOnCancelRunnable;
- private AnimatorPlaybackController(
- AnimatorSet anim, long duration, ArrayList<Holder> childAnims) {
+ private OnAnimationEndDispatcher mEndListener;
+ private DynamicAnimation.OnAnimationEndListener mSpringEndListener;
+ // We need this variable to ensure the end listener is called immediately, otherwise we run into
+ // issues where the callback interferes with the states of the swipe detector.
+ private boolean mSkipToEnd = false;
+
+ protected AnimatorPlaybackController(AnimatorSet anim, long duration,
+ Runnable onCancelRunnable) {
mAnim = anim;
mDuration = duration;
+ mOnCancelRunnable = onCancelRunnable;
mAnimationPlayer = ValueAnimator.ofFloat(0, 1);
mAnimationPlayer.setInterpolator(LINEAR);
- mAnimationPlayer.addListener(new OnAnimationEndDispatcher());
+ mEndListener = new OnAnimationEndDispatcher();
+ mAnimationPlayer.addListener(mEndListener);
mAnimationPlayer.addUpdateListener(this);
mAnim.addListener(new AnimatorListenerAdapter() {
@@ -128,7 +119,14 @@
}
});
- mChildAnimations = childAnims.toArray(new Holder[childAnims.size()]);
+ mSprings = new HashSet<>();
+ mSpringEndListener = (animation, canceled, value, velocity1) -> {
+ if (canceled) {
+ mEndListener.onAnimationCancel(mAnimationPlayer);
+ } else {
+ mEndListener.onAnimationEnd(mAnimationPlayer);
+ }
+ };
}
public AnimatorSet getTarget() {
@@ -162,68 +160,9 @@
}
/**
- * Starts playing the animation with the provided velocity optionally playing any
- * physics based animations
- */
- public void startWithVelocity(Context context, boolean goingToEnd,
- float velocity, float scale, long animationDuration) {
- float scaleInverse = 1 / Math.abs(scale);
- float scaledVelocity = velocity * scaleInverse;
-
- float nextFrameProgress = Utilities.boundToRange(getProgressFraction()
- + scaledVelocity * getSingleFrameMs(context), 0f, 1f);
-
- // Update setters for spring
- int springFlag = goingToEnd
- ? SpringProperty.FLAG_CAN_SPRING_ON_END
- : SpringProperty.FLAG_CAN_SPRING_ON_START;
-
- long springDuration = animationDuration;
- for (Holder h : mChildAnimations) {
- if ((h.springProperty.flags & springFlag) != 0) {
- SpringAnimationBuilder s = new SpringAnimationBuilder(h.anim, CURRENT_PLAY_TIME)
- .setStartValue(clampDuration(mCurrentFraction))
- .setEndValue(goingToEnd ? h.anim.getDuration() : 0)
- .setStartVelocity(scaledVelocity * h.anim.getDuration())
- .setMinimumVisibleChange(scaleInverse)
- .setDampingRatio(h.springProperty.mDampingRatio)
- .setStiffness(h.springProperty.mStiffness);
-
- long expectedDurationL = s.build(context).getDuration();
- springDuration = Math.max(expectedDurationL, springDuration);
-
- float expectedDuration = expectedDurationL;
- h.setter = (a, l) ->
- s.setValue(a, mAnimationPlayer.getCurrentPlayTime() / expectedDuration);
- h.anim.setInterpolator(LINEAR);
- }
- }
-
- mAnimationPlayer.setFloatValues(nextFrameProgress, goingToEnd ? 1f : 0f);
-
- if (springDuration <= animationDuration) {
- mAnimationPlayer.setDuration(animationDuration);
- mAnimationPlayer.setInterpolator(scrollInterpolatorForVelocity(velocity));
- } else {
- // Since spring requires more time to run, we let the other animations play with
- // current time and interpolation and by clamping the duration.
- mAnimationPlayer.setDuration(springDuration);
-
- float cutOff = animationDuration / (float) springDuration;
- mAnimationPlayer.setInterpolator(
- clampToProgress(scrollInterpolatorForVelocity(velocity), 0, cutOff));
- }
- mAnimationPlayer.start();
- }
-
- /**
* Pauses the currently playing animation.
*/
public void pause() {
- // Reset property setters
- for (Holder h : mChildAnimations) {
- h.reset();
- }
mAnimationPlayer.cancel();
}
@@ -237,18 +176,7 @@
/**
* Sets the current animation position and updates all the child animators accordingly.
*/
- public void setPlayFraction(float fraction) {
- mCurrentFraction = fraction;
- // Let the animator report the progress but don't apply the progress to child
- // animations if it has been cancelled.
- if (mTargetCancelled) {
- return;
- }
- long playPos = clampDuration(fraction);
- for (Holder holder : mChildAnimations) {
- holder.setter.set(holder.anim, playPos);
- }
- }
+ public abstract void setPlayFraction(float fraction);
public float getProgressFraction() {
return mCurrentFraction;
@@ -280,6 +208,49 @@
}
}
+ /**
+ * Starts playback and sets the spring.
+ */
+ public void dispatchOnStartWithVelocity(float end, float velocity) {
+ if (!QUICKSTEP_SPRINGS.get()) {
+ dispatchOnStart();
+ return;
+ }
+
+ if (DEBUG) Log.d(TAG, "dispatchOnStartWithVelocity#end=" + end + ", velocity=" + velocity);
+
+ for (Animator a : mAnim.getChildAnimations()) {
+ if (a instanceof SpringObjectAnimator) {
+ if (DEBUG) Log.d(TAG, "Found springAnimator=" + a);
+ SpringObjectAnimator springAnimator = (SpringObjectAnimator) a;
+ mSprings.add(springAnimator.getSpring());
+ springAnimator.startSpring(end, velocity, mSpringEndListener);
+ }
+ }
+
+ dispatchOnStart();
+ }
+
+ public void dispatchOnStart() {
+ dispatchOnStartRecursively(mAnim);
+ }
+
+ private void dispatchOnStartRecursively(Animator animator) {
+ List<AnimatorListener> listeners = animator instanceof SpringObjectAnimator
+ ? nonNullList(((SpringObjectAnimator) animator).getObjectAnimatorListeners())
+ : nonNullList(animator.getListeners());
+
+ for (AnimatorListener l : listeners) {
+ l.onAnimationStart(animator);
+ }
+
+ if (animator instanceof AnimatorSet) {
+ for (Animator anim : nonNullList(((AnimatorSet) animator).getChildAnimations())) {
+ dispatchOnStartRecursively(anim);
+ }
+ }
+ }
+
/** @see #dispatchOnCancelWithoutCancelRunnable(Runnable) */
public void dispatchOnCancelWithoutCancelRunnable() {
dispatchOnCancelWithoutCancelRunnable(null);
@@ -301,47 +272,115 @@
setOnCancelRunnable(onCancel);
}
-
- public AnimatorPlaybackController setOnCancelRunnable(Runnable runnable) {
- mOnCancelRunnable = runnable;
- return this;
- }
-
- public void dispatchOnStart() {
- callListenerCommandRecursively(mAnim, AnimatorListener::onAnimationStart);
- }
-
public void dispatchOnCancel() {
- callListenerCommandRecursively(mAnim, AnimatorListener::onAnimationCancel);
+ dispatchOnCancelRecursively(mAnim);
+ }
+
+ private void dispatchOnCancelRecursively(Animator animator) {
+ for (AnimatorListener l : nonNullList(animator.getListeners())) {
+ l.onAnimationCancel(animator);
+ }
+
+ if (animator instanceof AnimatorSet) {
+ for (Animator anim : nonNullList(((AnimatorSet) animator).getChildAnimations())) {
+ dispatchOnCancelRecursively(anim);
+ }
+ }
}
public void dispatchSetInterpolator(TimeInterpolator interpolator) {
- callAnimatorCommandRecursively(mAnim, a -> a.setInterpolator(interpolator));
+ dispatchSetInterpolatorRecursively(mAnim, interpolator);
}
- private static void callListenerCommandRecursively(
- Animator anim, BiConsumer<AnimatorListener, Animator> command) {
- callAnimatorCommandRecursively(anim, a-> {
- for (AnimatorListener l : nonNullList(a.getListeners())) {
- command.accept(l, a);
- }
- });
- }
-
- private static void callAnimatorCommandRecursively(Animator anim, Consumer<Animator> command) {
- command.accept(anim);
+ private void dispatchSetInterpolatorRecursively(Animator anim, TimeInterpolator interpolator) {
+ anim.setInterpolator(interpolator);
if (anim instanceof AnimatorSet) {
for (Animator child : nonNullList(((AnimatorSet) anim).getChildAnimations())) {
- callAnimatorCommandRecursively(child, command);
+ dispatchSetInterpolatorRecursively(child, interpolator);
}
}
}
+ public void setOnCancelRunnable(Runnable runnable) {
+ mOnCancelRunnable = runnable;
+ }
+
+ public void skipToEnd() {
+ mSkipToEnd = true;
+ for (SpringAnimation spring : mSprings) {
+ if (spring.canSkipToEnd()) {
+ spring.skipToEnd();
+ }
+ }
+ mAnimationPlayer.end();
+ mSkipToEnd = false;
+ }
+
+ public static class AnimatorPlaybackControllerVL extends AnimatorPlaybackController {
+
+ private final ValueAnimator[] mChildAnimations;
+
+ private AnimatorPlaybackControllerVL(AnimatorSet anim, long duration,
+ Runnable onCancelRunnable) {
+ super(anim, duration, onCancelRunnable);
+
+ // Build animation list
+ ArrayList<ValueAnimator> childAnims = new ArrayList<>();
+ getAnimationsRecur(mAnim, childAnims);
+ mChildAnimations = childAnims.toArray(new ValueAnimator[childAnims.size()]);
+ }
+
+ private void getAnimationsRecur(AnimatorSet anim, ArrayList<ValueAnimator> out) {
+ long forceDuration = anim.getDuration();
+ TimeInterpolator forceInterpolator = anim.getInterpolator();
+ for (Animator child : anim.getChildAnimations()) {
+ if (forceDuration > 0) {
+ child.setDuration(forceDuration);
+ }
+ if (forceInterpolator != null) {
+ child.setInterpolator(forceInterpolator);
+ }
+ if (child instanceof ValueAnimator) {
+ out.add((ValueAnimator) child);
+ } else if (child instanceof AnimatorSet) {
+ getAnimationsRecur((AnimatorSet) child, out);
+ } else {
+ throw new RuntimeException("Unknown animation type " + child);
+ }
+ }
+ }
+
+ @Override
+ public void setPlayFraction(float fraction) {
+ mCurrentFraction = fraction;
+ // Let the animator report the progress but don't apply the progress to child
+ // animations if it has been cancelled.
+ if (mTargetCancelled) {
+ return;
+ }
+ long playPos = clampDuration(fraction);
+ for (ValueAnimator anim : mChildAnimations) {
+ anim.setCurrentPlayTime(Math.min(playPos, anim.getDuration()));
+ }
+ }
+ }
+
+ private boolean isAnySpringRunning() {
+ for (SpringAnimation spring : mSprings) {
+ if (spring.isRunning()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Only dispatches the on end actions once the animator and all springs have completed running.
*/
private class OnAnimationEndDispatcher extends AnimationSuccessListener {
+ boolean mAnimatorDone = false;
+ boolean mSpringsDone = false;
boolean mDispatched = false;
@Override
@@ -352,76 +391,39 @@
@Override
public void onAnimationSuccess(Animator animator) {
+ if (mSprings.isEmpty()) {
+ mSpringsDone = mAnimatorDone = true;
+ }
+ if (isAnySpringRunning()) {
+ mAnimatorDone = true;
+ } else {
+ mSpringsDone = true;
+ }
+
// We wait for the spring (if any) to finish running before completing the end callback.
- if (!mDispatched) {
- callListenerCommandRecursively(mAnim, AnimatorListener::onAnimationEnd);
+ if (!mDispatched && (mSkipToEnd || (mAnimatorDone && mSpringsDone))) {
+ dispatchOnEndRecursively(mAnim);
if (mEndAction != null) {
mEndAction.run();
}
mDispatched = true;
}
}
+
+ private void dispatchOnEndRecursively(Animator animator) {
+ for (AnimatorListener l : nonNullList(animator.getListeners())) {
+ l.onAnimationEnd(animator);
+ }
+
+ if (animator instanceof AnimatorSet) {
+ for (Animator anim : nonNullList(((AnimatorSet) animator).getChildAnimations())) {
+ dispatchOnEndRecursively(anim);
+ }
+ }
+ }
}
private static <T> List<T> nonNullList(ArrayList<T> list) {
return list == null ? Collections.emptyList() : list;
}
-
- /**
- * Interface for setting position of value animator
- */
- private interface PositionSetter {
-
- PositionSetter DEFAULT = (anim, playPos) ->
- anim.setCurrentPlayTime(Math.min(playPos, anim.getDuration()));
-
- void set(ValueAnimator anim, long position);
- }
-
- /**
- * Holder class for various child animations
- */
- static class Holder {
-
- public final ValueAnimator anim;
-
- public final SpringProperty springProperty;
-
- public final TimeInterpolator interpolator;
-
- public PositionSetter setter;
-
- Holder(Animator anim, SpringProperty springProperty) {
- this.anim = (ValueAnimator) anim;
- this.springProperty = springProperty;
- this.interpolator = this.anim.getInterpolator();
- this.setter = PositionSetter.DEFAULT;
- }
-
- public void reset() {
- anim.setInterpolator(interpolator);
- setter = PositionSetter.DEFAULT;
- }
- }
-
- static void addAnimationHoldersRecur(
- Animator anim, SpringProperty springProperty, ArrayList<Holder> out) {
- long forceDuration = anim.getDuration();
- TimeInterpolator forceInterpolator = anim.getInterpolator();
- if (anim instanceof ValueAnimator) {
- out.add(new Holder(anim, springProperty));
- } else if (anim instanceof AnimatorSet) {
- for (Animator child : ((AnimatorSet) anim).getChildAnimations()) {
- if (forceDuration > 0) {
- child.setDuration(forceDuration);
- }
- if (forceInterpolator != null) {
- child.setInterpolator(forceInterpolator);
- }
- addAnimationHoldersRecur(child, springProperty, out);
- }
- } else {
- throw new RuntimeException("Unknown animation type " + anim);
- }
- }
}
diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
index d814b19..cd30dea 100644
--- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java
+++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
@@ -21,6 +21,7 @@
import android.view.animation.Interpolator;
import java.util.ArrayList;
+import java.util.List;
/**
* Utility class for building animator set
@@ -41,17 +42,36 @@
public static final int ANIM_OVERVIEW_SCRIM_FADE = 11;
public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions
+ public static final int FLAG_DONT_ANIMATE_OVERVIEW = 1 << 0;
+
protected final ArrayList<Animator> mAnims = new ArrayList<>();
private final SparseArray<Interpolator> mInterpolators = new SparseArray<>();
+ private List<Runnable> mOnFinishRunnables = new ArrayList<>();
+ private int mFlags = 0;
public void play(Animator anim) {
mAnims.add(anim);
}
+ public void addOnFinishRunnable(Runnable onFinishRunnable) {
+ mOnFinishRunnables.add(onFinishRunnable);
+ }
+
public AnimatorSet build() {
AnimatorSet anim = new AnimatorSet();
anim.playTogether(mAnims);
+ if (!mOnFinishRunnables.isEmpty()) {
+ anim.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animation) {
+ for (Runnable onFinishRunnable : mOnFinishRunnables) {
+ onFinishRunnable.run();
+ }
+ mOnFinishRunnables.clear();
+ }
+ });
+ }
return anim;
}
@@ -62,4 +82,12 @@
public void setInterpolator(int animId, Interpolator interpolator) {
mInterpolators.put(animId, interpolator);
}
+
+ public void addFlag(int flag) {
+ mFlags |= flag;
+ }
+
+ public boolean hasFlag(int flag) {
+ return (mFlags & flag) != 0;
+ }
}
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
deleted file mode 100644
index 562d160..0000000
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2018 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.anim;
-
-import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
-import android.os.Build;
-
-import com.android.launcher3.anim.AnimatorPlaybackController.Holder;
-
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-/**
- * Utility class to keep track of a running animation.
- *
- * This class allows attaching end callbacks to an animation is intended to be used with
- * {@link com.android.launcher3.anim.AnimatorPlaybackController}, since in that case
- * AnimationListeners are not properly dispatched.
- *
- * TODO: Find a better name
- */
-@TargetApi(Build.VERSION_CODES.O)
-public class PendingAnimation {
-
- private final ArrayList<Consumer<EndState>> mEndListeners = new ArrayList<>();
-
- /** package private **/
- final AnimatorSet anim = new AnimatorSet();
- final ArrayList<Holder> animHolders = new ArrayList<>();
-
- /**
- * Utility method to sent an interpolator on an animation and add it to the list
- */
- public void add(Animator anim, TimeInterpolator interpolator) {
- add(anim, interpolator, SpringProperty.DEFAULT);
- }
-
- public void add(Animator anim, TimeInterpolator interpolator, SpringProperty springProperty) {
- anim.setInterpolator(interpolator);
- add(anim, springProperty);
- }
-
- public void add(Animator anim) {
- add(anim, SpringProperty.DEFAULT);
- }
-
- public void add(Animator a, SpringProperty springProperty) {
- anim.play(a);
- addAnimationHoldersRecur(a, springProperty, animHolders);
- }
-
- public void finish(boolean isSuccess, int logAction) {
- for (Consumer<EndState> listeners : mEndListeners) {
- listeners.accept(new EndState(isSuccess, logAction));
- }
- mEndListeners.clear();
- }
-
- public void addEndListener(Consumer<EndState> listener) {
- mEndListeners.add(listener);
- }
-
- public static class EndState {
- public boolean isSuccess;
- public int logAction;
-
- public EndState(boolean isSuccess, int logAction) {
- this.isSuccess = isSuccess;
- this.logAction = logAction;
- }
- }
-}
diff --git a/src/com/android/launcher3/anim/PropertySetter.java b/src/com/android/launcher3/anim/PropertySetter.java
index 0b2eb48..757edff 100644
--- a/src/com/android/launcher3/anim/PropertySetter.java
+++ b/src/com/android/launcher3/anim/PropertySetter.java
@@ -19,8 +19,7 @@
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
-import android.util.FloatProperty;
-import android.util.IntProperty;
+import android.util.Property;
import android.view.View;
/**
@@ -37,14 +36,14 @@
}
}
- public <T> void setFloat(T target, FloatProperty<T> property, float value,
+ public <T> void setFloat(T target, Property<T, Float> property, float value,
TimeInterpolator interpolator) {
- property.setValue(target, value);
+ property.set(target, value);
}
- public <T> void setInt(T target, IntProperty<T> property, int value,
+ public <T> void setInt(T target, Property<T, Integer> property, int value,
TimeInterpolator interpolator) {
- property.setValue(target, value);
+ property.set(target, value);
}
public static class AnimatedPropertySetter extends PropertySetter {
@@ -69,7 +68,7 @@
}
@Override
- public <T> void setFloat(T target, FloatProperty<T> property, float value,
+ public <T> void setFloat(T target, Property<T, Float> property, float value,
TimeInterpolator interpolator) {
if (property.get(target) == value) {
return;
@@ -80,7 +79,7 @@
}
@Override
- public <T> void setInt(T target, IntProperty<T> property, int value,
+ public <T> void setInt(T target, Property<T, Integer> property, int value,
TimeInterpolator interpolator) {
if (property.get(target) == value) {
return;
diff --git a/src/com/android/launcher3/anim/SpringAnimationBuilder.java b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
index f22a9f0..0f34c1e 100644
--- a/src/com/android/launcher3/anim/SpringAnimationBuilder.java
+++ b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
@@ -15,15 +15,16 @@
*/
package com.android.launcher3.anim;
+import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.FloatProperty;
+import com.android.launcher3.util.DefaultDisplay;
+
import androidx.annotation.FloatRange;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.launcher3.util.DefaultDisplay;
-
/**
* Utility class to build an object animator which follows the same path as a spring animation for
* an underdamped spring.
@@ -191,8 +192,12 @@
long durationMs = (long) (1000.0 * duration);
ObjectAnimator animator = ObjectAnimator.ofFloat(mTarget, this, 0, (float) duration);
animator.setDuration(durationMs).setInterpolator(Interpolators.LINEAR);
- animator.addListener(AnimationSuccessListener.forRunnable(
- () -> mProperty.setValue(mTarget, mEndValue)));
+ animator.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ mProperty.setValue(mTarget, mEndValue);
+ }
+ });
return animator;
}
diff --git a/src/com/android/launcher3/anim/SpringObjectAnimator.java b/src/com/android/launcher3/anim/SpringObjectAnimator.java
new file mode 100644
index 0000000..27b9c18
--- /dev/null
+++ b/src/com/android/launcher3/anim/SpringObjectAnimator.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2019 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.anim;
+
+import static androidx.dynamicanimation.animation.FloatPropertyCompat.createFloatPropertyCompat;
+
+import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.FloatProperty;
+import android.util.Log;
+
+import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import java.util.ArrayList;
+
+
+/**
+ * This animator allows for an object's property to be be controlled by an {@link ObjectAnimator} or
+ * a {@link SpringAnimation}. It extends ValueAnimator so it can be used in an AnimatorSet.
+ */
+public class SpringObjectAnimator<T> extends ValueAnimator {
+
+ private static final String TAG = "SpringObjectAnimator";
+ private static boolean DEBUG = false;
+
+ private ObjectAnimator mObjectAnimator;
+ private float[] mValues;
+
+ private SpringAnimation mSpring;
+ private SpringProperty<T> mProperty;
+
+ private ArrayList<AnimatorListener> mListeners;
+ private boolean mSpringEnded = true;
+ private boolean mAnimatorEnded = true;
+ private boolean mEnded = true;
+
+ public SpringObjectAnimator(T object, FloatProperty<T> property, float minimumVisibleChange,
+ float damping, float stiffness, float... values) {
+ mSpring = new SpringAnimation(object, createFloatPropertyCompat(property));
+ mSpring.setMinimumVisibleChange(minimumVisibleChange);
+ mSpring.setSpring(new SpringForce(0)
+ .setDampingRatio(damping)
+ .setStiffness(stiffness));
+ mSpring.setStartVelocity(0.01f);
+ mProperty = new SpringProperty<>(property, mSpring);
+ mObjectAnimator = ObjectAnimator.ofFloat(object, mProperty, values);
+ mValues = values;
+ mListeners = new ArrayList<>();
+ setFloatValues(values);
+
+ // We use this listener and track mListeners so that we can sync the animator and spring
+ // listeners.
+ mObjectAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mAnimatorEnded = false;
+ mEnded = false;
+ for (AnimatorListener l : mListeners) {
+ l.onAnimationStart(animation);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimatorEnded = true;
+ tryEnding();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ for (AnimatorListener l : mListeners) {
+ l.onAnimationCancel(animation);
+ }
+ mSpring.cancel();
+ }
+ });
+
+ mSpring.addUpdateListener((animation, value, velocity) -> {
+ mSpringEnded = false;
+ mEnded = false;
+ });
+ mSpring.addEndListener((animation, canceled, value, velocity) -> {
+ mSpringEnded = true;
+ tryEnding();
+ });
+ }
+
+ private void tryEnding() {
+ if (DEBUG) {
+ Log.d(TAG, "tryEnding#mAnimatorEnded=" + mAnimatorEnded + ", mSpringEnded="
+ + mSpringEnded + ", mEnded=" + mEnded);
+ }
+
+ // If springs are disabled, ignore value of mSpringEnded
+ if (mAnimatorEnded && (mSpringEnded || !QUICKSTEP_SPRINGS.get()) && !mEnded) {
+ for (AnimatorListener l : mListeners) {
+ l.onAnimationEnd(this);
+ }
+ mEnded = true;
+ }
+ }
+
+ public SpringAnimation getSpring() {
+ return mSpring;
+ }
+
+ /**
+ * Initializes and sets up the spring to take over controlling the object.
+ */
+ public void startSpring(float end, float velocity, OnAnimationEndListener endListener) {
+ // Cancel the spring so we can set new start velocity and final position. We need to remove
+ // the listener since the spring is not actually ending.
+ mSpring.removeEndListener(endListener);
+ mSpring.cancel();
+ mSpring.addEndListener(endListener);
+
+ mProperty.switchToSpring();
+
+ float startValue = end == 0 ? mValues[1] : mValues[0];
+ float endValue = end == 0 ? mValues[0] : mValues[1];
+
+ // Ensures that the velocity matches the direction of the values.
+ velocity = Math.signum(endValue - startValue) * Math.abs(velocity);
+ mSpring.setStartVelocity(velocity);
+
+ new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ mSpring.animateToFinalPosition(endValue);
+ }, getStartDelay());
+ }
+
+ @Override
+ public void addListener(AnimatorListener listener) {
+ mListeners.add(listener);
+ }
+
+ public ArrayList<AnimatorListener> getObjectAnimatorListeners() {
+ return mObjectAnimator.getListeners();
+ }
+
+ @Override
+ public ArrayList<AnimatorListener> getListeners() {
+ return mListeners;
+ }
+
+ @Override
+ public void removeAllListeners() {
+ mListeners.clear();
+ }
+
+ @Override
+ public void removeListener(AnimatorListener listener) {
+ mListeners.remove(listener);
+ }
+
+ @Override
+ public void addPauseListener(AnimatorPauseListener listener) {
+ mObjectAnimator.addPauseListener(listener);
+ }
+
+ @Override
+ public void cancel() {
+ mObjectAnimator.cancel();
+ mSpring.cancel();
+ }
+
+ @Override
+ public void end() {
+ mObjectAnimator.end();
+ }
+
+ @Override
+ public long getDuration() {
+ return mObjectAnimator.getDuration();
+ }
+
+ @Override
+ public TimeInterpolator getInterpolator() {
+ return mObjectAnimator.getInterpolator();
+ }
+
+ @Override
+ public long getStartDelay() {
+ return mObjectAnimator.getStartDelay();
+ }
+
+ @Override
+ public long getTotalDuration() {
+ return mObjectAnimator.getTotalDuration();
+ }
+
+ @Override
+ public boolean isPaused() {
+ return mObjectAnimator.isPaused();
+ }
+
+ @Override
+ public boolean isRunning() {
+ return mObjectAnimator.isRunning();
+ }
+
+ @Override
+ public boolean isStarted() {
+ return mObjectAnimator.isStarted();
+ }
+
+ @Override
+ public void pause() {
+ mObjectAnimator.pause();
+ }
+
+ @Override
+ public void removePauseListener(AnimatorPauseListener listener) {
+ mObjectAnimator.removePauseListener(listener);
+ }
+
+ @Override
+ public void resume() {
+ mObjectAnimator.resume();
+ }
+
+ @Override
+ public ValueAnimator setDuration(long duration) {
+ return mObjectAnimator.setDuration(duration);
+ }
+
+ @Override
+ public void setInterpolator(TimeInterpolator value) {
+ mObjectAnimator.setInterpolator(value);
+ }
+
+ @Override
+ public void setStartDelay(long startDelay) {
+ mObjectAnimator.setStartDelay(startDelay);
+ }
+
+ @Override
+ public void setTarget(Object target) {
+ mObjectAnimator.setTarget(target);
+ }
+
+ @Override
+ public void start() {
+ mObjectAnimator.start();
+ }
+
+ @Override
+ public void setCurrentFraction(float fraction) {
+ mObjectAnimator.setCurrentFraction(fraction);
+ }
+
+ @Override
+ public void setCurrentPlayTime(long playTime) {
+ mObjectAnimator.setCurrentPlayTime(playTime);
+ }
+
+ public static class SpringProperty<T> extends FloatProperty<T> {
+
+ boolean useSpring = false;
+ final FloatProperty<T> mProperty;
+ final SpringAnimation mSpring;
+
+ public SpringProperty(FloatProperty<T> property, SpringAnimation spring) {
+ super(property.getName());
+ mProperty = property;
+ mSpring = spring;
+ }
+
+ public void switchToSpring() {
+ useSpring = true;
+ }
+
+ @Override
+ public Float get(T object) {
+ return mProperty.get(object);
+ }
+
+ @Override
+ public void setValue(T object, float progress) {
+ if (useSpring) {
+ mSpring.animateToFinalPosition(progress);
+ } else {
+ mProperty.setValue(object, progress);
+ }
+ }
+ }
+}
diff --git a/src/com/android/launcher3/anim/SpringProperty.java b/src/com/android/launcher3/anim/SpringProperty.java
deleted file mode 100644
index caedd6c..0000000
--- a/src/com/android/launcher3/anim/SpringProperty.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2020 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.anim;
-
-import androidx.dynamicanimation.animation.SpringForce;
-
-/**
- * Utility class to store configurations for spring animation
- */
-public class SpringProperty {
-
- public static final SpringProperty DEFAULT = new SpringProperty();
-
- // Play spring when the animation is going towards the end
- public static final int FLAG_CAN_SPRING_ON_END = 1 << 0;
- // Play spring when animation is going towards the start (in reverse direction)
- public static final int FLAG_CAN_SPRING_ON_START = 1 << 1;
-
- public final int flags;
-
- float mDampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY;
- float mStiffness = SpringForce.STIFFNESS_MEDIUM;
-
- public SpringProperty() {
- this(0);
- }
-
- public SpringProperty(int flags) {
- this.flags = flags;
- }
-
- public SpringProperty setDampingRatio(float dampingRatio) {
- mDampingRatio = dampingRatio;
- return this;
- }
-
- public SpringProperty setStiffness(float stiffness) {
- mStiffness = stiffness;
- return this;
- }
-}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 471a743..ed28df0 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -36,8 +36,6 @@
private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
public static final String FLAGS_PREF_NAME = "featureFlags";
- public static final String FLAG_ENABLE_FIXED_ROTATION_TRANSFORM =
- "ENABLE_FIXED_ROTATION_TRANSFORM";
private FeatureFlags() { }
@@ -95,9 +93,8 @@
public static final BooleanFlag FAKE_LANDSCAPE_UI = getDebugFlag(
"FAKE_LANDSCAPE_UI", false, "Rotate launcher UI instead of using transposed layout");
- public static final BooleanFlag FOLDER_NAME_SUGGEST = new DeviceFlag(
- "FOLDER_NAME_SUGGEST", true,
- "Suggests folder names instead of blank text.");
+ public static final BooleanFlag FOLDER_NAME_SUGGEST = getDebugFlag(
+ "FOLDER_NAME_SUGGEST", true, "Suggests folder names instead of blank text.");
public static final BooleanFlag APP_SEARCH_IMPROVEMENTS = new DeviceFlag(
"APP_SEARCH_IMPROVEMENTS", false,
@@ -155,10 +152,6 @@
"ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false,
"Always use hardware optimization for folder animations.");
- public static final BooleanFlag ENABLE_FIXED_ROTATION_TRANSFORM = getDebugFlag(
- FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true,
- "Launch/close apps without rotation animation. Fix Launcher to portrait");
-
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 369bf28..92f35e2 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -119,7 +119,6 @@
recreateControllers();
}
- @Override
public void recreateControllers() {
mControllers = mActivity.createTouchControllers();
}
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index 77c6306..869dd94 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -16,8 +16,6 @@
package com.android.launcher3.dragndrop;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-
import android.annotation.TargetApi;
import android.appwidget.AppWidgetManager;
import android.content.pm.LauncherApps.PinItemRequest;
@@ -40,8 +38,6 @@
import com.android.launcher3.widget.PendingItemDragHelper;
import com.android.launcher3.widget.WidgetAddFlowHandler;
-import java.util.ArrayList;
-
/**
* {@link DragSource} for handling drop from a different window. This object is initialized
* in the source window and is passed on to the Launcher activity as an Intent extra.
@@ -107,9 +103,9 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
- ArrayList<LauncherLogProto.Target> parents) {
- parents.add(newContainerTarget(LauncherLogProto.ContainerType.PINITEM));
+ public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
+ LauncherLogProto.Target targetParent) {
+ targetParent.containerType = LauncherLogProto.ContainerType.PINITEM;
}
@Override
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 2be8ff4..69f93de 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -27,7 +27,6 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_CUSTOM;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_EMPTY;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_FOLDER_LABEL_STATE_UNSPECIFIED;
@@ -90,6 +89,7 @@
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.userevent.LauncherLogProto.Action;
import com.android.launcher3.userevent.LauncherLogProto.ContainerType;
@@ -1459,24 +1459,12 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
- ArrayList<LauncherLogProto.Target> targets) {
- child.gridX = childInfo.cellX;
- child.gridY = childInfo.cellY;
- child.pageIndex = mContent.getCurrentPage();
-
- LauncherLogProto.Target target = newContainerTarget(LauncherLogProto.ContainerType.FOLDER);
- target.pageIndex = mInfo.screenId;
- target.gridX = mInfo.cellX;
- target.gridY = mInfo.cellY;
- targets.add(target);
-
- // continue to parent
- if (mInfo.container == CONTAINER_HOTSEAT) {
- mLauncher.getHotseat().fillInLogContainerData(mInfo, target, targets);
- } else {
- mLauncher.getWorkspace().fillInLogContainerData(mInfo, target, targets);
- }
+ public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
+ LauncherLogProto.Target targetParent) {
+ target.gridX = info.cellX;
+ target.gridY = info.cellY;
+ target.pageIndex = mContent.getCurrentPage();
+ targetParent.containerType = LauncherLogProto.ContainerType.FOLDER;
}
private class OnScrollHintListener implements OnAlarmListener {
@@ -1609,7 +1597,7 @@
}
} else {
mLauncher.getUserEventDispatcher().logActionTapOutside(
- newContainerTarget(LauncherLogProto.ContainerType.FOLDER));
+ LoggerUtils.newContainerTarget(LauncherLogProto.ContainerType.FOLDER));
close(true);
return true;
}
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index f72e674..1310d37 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.graphics.IconShape.getShape;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
-import static com.android.launcher3.uioverrides.BackgroundBlurController.BACKGROUND_BLUR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -47,7 +46,6 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PropertyResetListener;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
import com.android.launcher3.util.Themes;
import java.util.List;
@@ -222,13 +220,6 @@
Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0);
play(a, z, mIsOpening ? midDuration : 0, midDuration);
- BackgroundBlurController blurController = mLauncher.getBackgroundBlurController();
- int stateBackgroundBlur = mLauncher.getStateManager().getState()
- .getBackgroundBlurRadius(mLauncher);
- int folderBackgroundBlurAdjustment = blurController.getFolderBackgroundBlurAdjustment();
- play(a, ObjectAnimator.ofInt(blurController, BACKGROUND_BLUR, mIsOpening
- ? stateBackgroundBlur + folderBackgroundBlurAdjustment
- : stateBackgroundBlur));
// Store clip variables
CellLayout cellLayout = mContent.getCurrentCellLayout();
diff --git a/src/com/android/launcher3/folder/FolderNameProvider.java b/src/com/android/launcher3/folder/FolderNameProvider.java
index 07161da..184dbb9 100644
--- a/src/com/android/launcher3/folder/FolderNameProvider.java
+++ b/src/com/android/launcher3/folder/FolderNameProvider.java
@@ -15,10 +15,8 @@
*/
package com.android.launcher3.folder;
-import android.content.ComponentName;
import android.content.Context;
import android.os.Process;
-import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
@@ -36,9 +34,12 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -100,23 +101,27 @@
}
// If all the icons are from work profile,
// Then, suggest "Work" as the folder name
- Set<UserHandle> users = workspaceItemInfos.stream().map(w -> w.user)
- .collect(Collectors.toSet());
- if (users.size() == 1 && !users.contains(Process.myUserHandle())) {
+ List<WorkspaceItemInfo> distinctItemInfos = workspaceItemInfos.stream()
+ .filter(distinctByKey(p -> p.user))
+ .collect(Collectors.toList());
+
+ if (distinctItemInfos.size() == 1
+ && !distinctItemInfos.get(0).user.equals(Process.myUserHandle())) {
+ // Place it as last viable suggestion
setAsLastSuggestion(nameInfos,
context.getResources().getString(R.string.work_folder_name));
}
// If all the icons are from same package (e.g., main icon, shortcut, shortcut)
// Then, suggest the package's title as the folder name
- Set<String> packageNames = workspaceItemInfos.stream()
- .map(WorkspaceItemInfo::getTargetComponent)
- .filter(Objects::nonNull)
- .map(ComponentName::getPackageName)
- .collect(Collectors.toSet());
+ distinctItemInfos = workspaceItemInfos.stream()
+ .filter(distinctByKey(p -> p.getTargetComponent() != null
+ ? p.getTargetComponent().getPackageName() : ""))
+ .collect(Collectors.toList());
- if (packageNames.size() == 1) {
- Optional<AppInfo> info = getAppInfoByPackageName(packageNames.iterator().next());
+ if (distinctItemInfos.size() == 1) {
+ Optional<AppInfo> info = getAppInfoByPackageName(
+ distinctItemInfos.get(0).getTargetComponent().getPackageName());
// Place it as first viable suggestion and shift everything else
info.ifPresent(i -> setAsFirstSuggestion(nameInfos, i.title.toString()));
}
@@ -130,7 +135,6 @@
return Optional.empty();
}
return mAppInfos.stream()
- .filter(info -> info.componentName != null)
.filter(info -> info.componentName.getPackageName().equals(packageName))
.findAny();
}
@@ -170,6 +174,12 @@
label.toString()));
}
+ // This method can be moved to some Utility class location.
+ private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
+ Map<Object, Boolean> map = new ConcurrentHashMap<>();
+ return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
+ }
+
private class FolderNameWorker extends BaseModelUpdateTask {
@Override
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
diff --git a/src/com/android/launcher3/graphics/Scrim.java b/src/com/android/launcher3/graphics/Scrim.java
index f90962d..67b2b6d 100644
--- a/src/com/android/launcher3/graphics/Scrim.java
+++ b/src/com/android/launcher3/graphics/Scrim.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.graphics.Canvas;
-import android.util.FloatProperty;
+import android.util.Property;
import android.view.View;
import com.android.launcher3.Launcher;
@@ -31,16 +31,16 @@
public class Scrim implements View.OnAttachStateChangeListener,
WallpaperColorInfo.OnChangeListener {
- public static final FloatProperty<Scrim> SCRIM_PROGRESS =
- new FloatProperty<Scrim>("scrimProgress") {
+ public static final Property<Scrim, Float> SCRIM_PROGRESS =
+ new Property<Scrim, Float>(Float.TYPE, "scrimProgress") {
@Override
public Float get(Scrim scrim) {
return scrim.mScrimProgress;
}
@Override
- public void setValue(Scrim scrim, float v) {
- scrim.setScrimProgress(v);
+ public void set(Scrim scrim, Float value) {
+ scrim.setScrimProgress(value);
}
};
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index 83349bc..5a1dcab 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -37,7 +37,7 @@
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
-import android.util.FloatProperty;
+import android.util.Property;
import android.view.View;
import androidx.core.graphics.ColorUtils;
@@ -54,28 +54,28 @@
*/
public class WorkspaceAndHotseatScrim extends Scrim {
- public static final FloatProperty<WorkspaceAndHotseatScrim> SYSUI_PROGRESS =
- new FloatProperty<WorkspaceAndHotseatScrim>("sysUiProgress") {
+ public static final Property<WorkspaceAndHotseatScrim, Float> SYSUI_PROGRESS =
+ new Property<WorkspaceAndHotseatScrim, Float>(Float.TYPE, "sysUiProgress") {
@Override
public Float get(WorkspaceAndHotseatScrim scrim) {
return scrim.mSysUiProgress;
}
@Override
- public void setValue(WorkspaceAndHotseatScrim scrim, float value) {
+ public void set(WorkspaceAndHotseatScrim scrim, Float value) {
scrim.setSysUiProgress(value);
}
};
- private static final FloatProperty<WorkspaceAndHotseatScrim> SYSUI_ANIM_MULTIPLIER =
- new FloatProperty<WorkspaceAndHotseatScrim>("sysUiAnimMultiplier") {
+ private static final Property<WorkspaceAndHotseatScrim, Float> SYSUI_ANIM_MULTIPLIER =
+ new Property<WorkspaceAndHotseatScrim, Float>(Float.TYPE, "sysUiAnimMultiplier") {
@Override
public Float get(WorkspaceAndHotseatScrim scrim) {
return scrim.mSysUiAnimMultiplier;
}
@Override
- public void setValue(WorkspaceAndHotseatScrim scrim, float value) {
+ public void set(WorkspaceAndHotseatScrim scrim, Float value) {
scrim.mSysUiAnimMultiplier = value;
scrim.reapplySysUiAlpha();
}
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index a9d10d7..b004edf 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -37,7 +37,6 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
/**
* Helper methods for logging.
@@ -256,13 +255,4 @@
event.action = action;
return event;
}
-
- /**
- * Creates LauncherEvent using Action and ArrayList of Targets
- */
- public static LauncherEvent newLauncherEvent(Action action, ArrayList<Target> targets) {
- Target[] targetsArray = new Target[targets.size()];
- targets.toArray(targetsArray);
- return newLauncherEvent(action, targetsArray);
- }
}
diff --git a/src/com/android/launcher3/logging/StatsLogUtils.java b/src/com/android/launcher3/logging/StatsLogUtils.java
index 8449612..b02a050 100644
--- a/src/com/android/launcher3/logging/StatsLogUtils.java
+++ b/src/com/android/launcher3/logging/StatsLogUtils.java
@@ -5,13 +5,11 @@
import android.view.View;
import android.view.ViewParent;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.ItemInfo;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import java.util.ArrayList;
+import androidx.annotation.Nullable;
public class StatsLogUtils {
@@ -37,9 +35,14 @@
public interface LogContainerProvider {
/**
- * Populates parent container targets for an item
+ * Copies data from the source to the destination proto.
+ *
+ * @param v source of the data
+ * @param info source of the data
+ * @param target dest of the data
+ * @param targetParent dest of the data
*/
- void fillInLogContainerData(ItemInfo childInfo, Target child, ArrayList<Target> parents);
+ void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent);
}
/**
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 3770d17..afa3f6d 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -25,9 +25,6 @@
import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
import static com.android.launcher3.logging.LoggerUtils.newTarget;
import static com.android.launcher3.logging.LoggerUtils.newTouchAction;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.TipType;
import static java.util.Optional.ofNullable;
@@ -51,7 +48,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
-import com.android.launcher3.userevent.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -60,11 +57,7 @@
import com.android.launcher3.util.LogConfig;
import com.android.launcher3.util.ResourceBasedOverride;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-import com.google.protobuf.nano.MessageNano;
-
-import java.util.ArrayList;
+import java.util.Locale;
import java.util.UUID;
/**
@@ -79,10 +72,8 @@
private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.USEREVENT);
private static final String UUID_STORAGE = "uuid";
- /**
- * A factory method for UserEventDispatcher
- */
- public static UserEventDispatcher newInstance(Context context) {
+ public static UserEventDispatcher newInstance(Context context,
+ UserEventDelegate delegate) {
SharedPreferences sharedPrefs = Utilities.getDevicePrefs(context);
String uuidStr = sharedPrefs.getString(UUID_STORAGE, null);
if (uuidStr == null) {
@@ -91,31 +82,41 @@
}
UserEventDispatcher ued = Overrides.getObject(UserEventDispatcher.class,
context.getApplicationContext(), R.string.user_event_dispatcher_class);
+ ued.mDelegate = delegate;
ued.mUuidStr = uuidStr;
ued.mInstantAppResolver = InstantAppResolver.newInstance(context);
return ued;
}
+ public static UserEventDispatcher newInstance(Context context) {
+ return newInstance(context, null);
+ }
+
+ public interface UserEventDelegate {
+ void modifyUserEvent(LauncherEvent event);
+ }
/**
* Fills in the container data on the given event if the given view is not null.
*
* @return whether container data was added.
*/
- public boolean fillLogContainer(@Nullable View v, Target child,
- @Nullable ArrayList<Target> targets) {
- LogContainerProvider firstParent = StatsLogUtils.getLaunchProviderRecursive(v);
- if (v == null || !(v.getTag() instanceof ItemInfo) || firstParent == null) {
+ public boolean fillInLogContainerData(LauncherLogProto.LauncherEvent event, @Nullable View v) {
+ // Fill in grid(x,y), pageIndex of the child and container type of the parent
+ LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(v);
+ if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
return false;
}
final ItemInfo itemInfo = (ItemInfo) v.getTag();
- firstParent.fillInLogContainerData(itemInfo, child, targets);
+ final Target target = event.srcTarget[0];
+ final Target targetParent = event.srcTarget[1];
+ onFillInLogContainerData(itemInfo, target, targetParent);
+ provider.fillInLogContainerData(v, itemInfo, target, targetParent);
return true;
}
- protected void onFillInLogContainerData(@NonNull ItemInfo itemInfo, @NonNull Target target,
- @NonNull ArrayList<Target> targets) {
- }
+ protected void onFillInLogContainerData(
+ @NonNull ItemInfo itemInfo, @NonNull Target target, @NonNull Target targetParent) { }
private boolean mSessionStarted;
private long mElapsedContainerMillis;
@@ -124,6 +125,7 @@
private String mUuidStr;
protected InstantAppResolver mInstantAppResolver;
private boolean mAppOrTaskLaunch;
+ private UserEventDelegate mDelegate;
private boolean mPreviousHomeGesture;
// APP_ICON SHORTCUT WIDGET
@@ -134,15 +136,16 @@
// --------------------------------------------------------------
@Deprecated
- public void logAppLaunch(View v, Intent intent, @Nullable UserHandle userHandle) {
- Target itemTarget = newItemTarget(v, mInstantAppResolver);
- Action action = newTouchAction(Action.Touch.TAP);
- ArrayList<Target> targets = makeTargetsList(itemTarget);
- if (fillLogContainer(v, itemTarget, targets)) {
- onFillInLogContainerData((ItemInfo) v.getTag(), itemTarget, targets);
- fillIntentInfo(itemTarget, intent, userHandle);
+ public void logAppLaunch(View v, Intent intent, @Nullable UserHandle userHandle) {
+ LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.TAP),
+ newItemTarget(v, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
+
+ if (fillInLogContainerData(event, v)) {
+ if (mDelegate != null) {
+ mDelegate.modifyUserEvent(event);
+ }
+ fillIntentInfo(event.srcTarget[0], intent, userHandle);
}
- LauncherEvent event = newLauncherEvent(action, targets);
ItemInfo info = (ItemInfo) v.getTag();
if (info != null && Utilities.IS_DEBUG_DEVICE && FeatureFlags.ENABLE_HYBRID_HOTSEAT.get()) {
FileLog.d(TAG, "appLaunch: packageName:" + info.getTargetComponent().getPackageName()
@@ -168,7 +171,7 @@
// Direction DOWN means the task was launched, UP means it was dismissed.
event.action.dir = direction;
}
- event.srcTarget[0].itemType = ItemType.TASK;
+ event.srcTarget[0].itemType = LauncherLogProto.ItemType.TASK;
event.srcTarget[0].pageIndex = taskIndex;
fillComponentInfo(event.srcTarget[0], componentKey.componentName);
dispatchUserEvent(event, null);
@@ -191,11 +194,8 @@
public void logNotificationLaunch(View v, PendingIntent intent) {
LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.TAP),
newItemTarget(v, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
- Target itemTarget = newItemTarget(v, mInstantAppResolver);
- ArrayList<Target> targets = makeTargetsList(itemTarget);
-
- if (fillLogContainer(v, itemTarget, targets)) {
- itemTarget.packageNameHash = (mUuidStr + intent.getCreatorPackage()).hashCode();
+ if (fillInLogContainerData(event, v)) {
+ event.srcTarget[0].packageNameHash = (mUuidStr + intent.getCreatorPackage()).hashCode();
}
dispatchUserEvent(event, null);
}
@@ -241,45 +241,50 @@
LauncherEvent event = newLauncherEvent(newCommandAction(command),
newItemTarget(itemView, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
- Target itemTarget = newItemTarget(itemView, mInstantAppResolver);
- ArrayList<Target> targets = makeTargetsList(itemTarget);
-
- if (fillLogContainer(itemView, itemTarget, targets)) {
+ if (fillInLogContainerData(event, itemView)) {
// TODO: Remove the following two lines once fillInLogContainerData can take in a
// container view.
- itemTarget.type = Target.Type.CONTAINER;
- itemTarget.containerType = srcContainerType;
+ event.srcTarget[0].type = Target.Type.CONTAINER;
+ event.srcTarget[0].containerType = srcContainerType;
}
dispatchUserEvent(event, null);
}
public void logActionOnControl(int action, int controlType) {
- logActionOnControl(action, controlType, null);
+ logActionOnControl(action, controlType, null, -1);
}
public void logActionOnControl(int action, int controlType, int parentContainerType) {
logActionOnControl(action, controlType, null, parentContainerType);
}
- /**
- * Logs control action with proper parent hierarchy
- */
- public void logActionOnControl(int actionType, int controlType,
- @Nullable View controlInContainer, int... parentTypes) {
- Target control = newTarget(Target.Type.CONTROL);
- control.controlType = controlType;
- Action action = newAction(actionType);
+ public void logActionOnControl(int action, int controlType, @Nullable View controlInContainer) {
+ logActionOnControl(action, controlType, controlInContainer, -1);
+ }
- ArrayList<Target> targets = makeTargetsList(control);
+ public void logActionOnControl(int action, int controlType, int parentContainer,
+ int grandParentContainer) {
+ LauncherEvent event = newLauncherEvent(newTouchAction(action),
+ newControlTarget(controlType),
+ newContainerTarget(parentContainer),
+ newContainerTarget(grandParentContainer));
+ dispatchUserEvent(event, null);
+ }
+
+ public void logActionOnControl(int action, int controlType, @Nullable View controlInContainer,
+ int parentContainerType) {
+ final LauncherEvent event = (controlInContainer == null && parentContainerType < 0)
+ ? newLauncherEvent(newTouchAction(action), newTarget(Target.Type.CONTROL))
+ : newLauncherEvent(newTouchAction(action), newTarget(Target.Type.CONTROL),
+ newTarget(Target.Type.CONTAINER));
+ event.srcTarget[0].controlType = controlType;
if (controlInContainer != null) {
- fillLogContainer(controlInContainer, control, targets);
+ fillInLogContainerData(event, controlInContainer);
}
- for (int parentContainerType : parentTypes) {
- if (parentContainerType < 0) continue;
- targets.add(newContainerTarget(parentContainerType));
+ if (parentContainerType >= 0) {
+ event.srcTarget[1].containerType = parentContainerType;
}
- LauncherEvent event = newLauncherEvent(action, targets);
- if (actionType == Action.Touch.DRAGDROP) {
+ if (action == Action.Touch.DRAGDROP) {
event.actionDurationMillis = SystemClock.uptimeMillis() - mActionDurationMillis;
}
dispatchUserEvent(event, null);
@@ -295,7 +300,7 @@
public void logActionBounceTip(int containerType) {
LauncherEvent event = newLauncherEvent(newAction(Action.Type.TIP),
newContainerTarget(containerType));
- event.srcTarget[0].tipType = TipType.BOUNCE;
+ event.srcTarget[0].tipType = LauncherLogProto.TipType.BOUNCE;
dispatchUserEvent(event, null);
}
@@ -322,7 +327,7 @@
int srcChildTargetType, int srcParentContainerType, int dstContainerType,
int pageIndex) {
LauncherEvent event;
- if (srcChildTargetType == ItemType.TASK) {
+ if (srcChildTargetType == LauncherLogProto.ItemType.TASK) {
event = newLauncherEvent(newTouchAction(action),
newItemTarget(srcChildTargetType),
newContainerTarget(srcParentContainerType));
@@ -370,53 +375,52 @@
* Logs proto lite version of LauncherEvent object to clearcut.
*/
public void logLauncherEvent(
- com.android.launcher3.userevent.LauncherLogProto.LauncherEvent launcherEvent) {
+ com.android.launcher3.userevent.LauncherLogProto.LauncherEvent launcherEvent) {
if (mPreviousHomeGesture) {
mPreviousHomeGesture = false;
}
mAppOrTaskLaunch = false;
launcherEvent.toBuilder()
- .setElapsedContainerMillis(SystemClock.uptimeMillis() - mElapsedContainerMillis)
- .setElapsedSessionMillis(
- SystemClock.uptimeMillis() - mElapsedSessionMillis).build();
- try {
- dispatchUserEvent(LauncherEvent.parseFrom(launcherEvent.toByteArray()), null);
- } catch (InvalidProtocolBufferNanoException e) {
- throw new RuntimeException("Cannot convert LauncherEvent from Lite to Nano version.");
+ .setElapsedContainerMillis(SystemClock.uptimeMillis() - mElapsedContainerMillis)
+ .setElapsedSessionMillis(SystemClock.uptimeMillis() - mElapsedSessionMillis).build();
+ if (!IS_VERBOSE) {
+ return;
}
+ Log.d(TAG, launcherEvent.toString());
}
public void logDeepShortcutsOpen(View icon) {
+ LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(icon);
+ if (icon == null || !(icon.getTag() instanceof ItemInfo || provider == null)) {
+ return;
+ }
ItemInfo info = (ItemInfo) icon.getTag();
- Target child = newItemTarget(info, mInstantAppResolver);
- ArrayList<Target> targets = makeTargetsList(child);
- fillLogContainer(icon, child, targets);
- dispatchUserEvent(newLauncherEvent(newTouchAction(Action.Touch.TAP), targets), null);
+ LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.LONGPRESS),
+ newItemTarget(info, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
+ provider.fillInLogContainerData(icon, info, event.srcTarget[0], event.srcTarget[1]);
+ dispatchUserEvent(event, null);
+
resetElapsedContainerMillis("deep shortcut open");
}
public void logDragNDrop(DropTarget.DragObject dragObj, View dropTargetAsView) {
- Target srcChild = newItemTarget(dragObj.originalDragInfo, mInstantAppResolver);
- ArrayList<Target> srcTargets = makeTargetsList(srcChild);
+ LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.DRAGDROP),
+ newItemTarget(dragObj.originalDragInfo, mInstantAppResolver),
+ newTarget(Target.Type.CONTAINER));
+ event.destTarget = new Target[]{
+ newItemTarget(dragObj.originalDragInfo, mInstantAppResolver),
+ newDropTarget(dropTargetAsView)
+ };
+ dragObj.dragSource.fillInLogContainerData(null, dragObj.originalDragInfo,
+ event.srcTarget[0], event.srcTarget[1]);
- Target destChild = newItemTarget(dragObj.originalDragInfo, mInstantAppResolver);
- ArrayList<Target> destTargets = makeTargetsList(destChild);
-
- dragObj.dragSource.fillInLogContainerData(dragObj.originalDragInfo, srcChild, srcTargets);
if (dropTargetAsView instanceof LogContainerProvider) {
- ((LogContainerProvider) dropTargetAsView).fillInLogContainerData(dragObj.dragInfo,
- destChild, destTargets);
- }
- else {
- destTargets.add(newDropTarget(dropTargetAsView));
- }
- LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.DRAGDROP), srcTargets);
- Target[] destTargetsArray = new Target[destTargets.size()];
- destTargets.toArray(destTargetsArray);
- event.destTarget = destTargetsArray;
+ ((LogContainerProvider) dropTargetAsView).fillInLogContainerData(null,
+ dragObj.dragInfo, event.destTarget[0], event.destTarget[1]);
+ }
event.actionDurationMillis = SystemClock.uptimeMillis() - mActionDurationMillis;
dispatchUserEvent(event, null);
}
@@ -428,8 +432,8 @@
action.command = Action.Command.BACK;
action.dir = isButton ? Action.Direction.NONE :
gestureSwipeLeft ? Action.Direction.LEFT : Action.Direction.RIGHT;
- Target target = newControlTarget(isButton ? ControlType.BACK_BUTTON :
- ControlType.BACK_GESTURE);
+ Target target = newControlTarget(isButton ? LauncherLogProto.ControlType.BACK_BUTTON :
+ LauncherLogProto.ControlType.BACK_GESTURE);
target.spanX = downX;
target.spanY = downY;
target.cardinality = completed ? 1 : 0;
@@ -440,6 +444,8 @@
/**
* Currently logs following containers: workspace, allapps, widget tray.
+ *
+ * @param reason
*/
public final void resetElapsedContainerMillis(String reason) {
mElapsedContainerMillis = SystemClock.uptimeMillis();
@@ -478,23 +484,34 @@
if (!IS_VERBOSE) {
return;
}
- LauncherLogProto.LauncherEvent liteLauncherEvent;
- try {
- liteLauncherEvent =
- LauncherLogProto.LauncherEvent.parseFrom(MessageNano.toByteArray(ev));
- } catch (InvalidProtocolBufferException e) {
- throw new RuntimeException("Cannot parse LauncherEvent from Nano to Lite version");
- }
- Log.d(TAG, liteLauncherEvent.toString());
+ Log.d(TAG, generateLog(ev));
}
/**
- * Constructs an ArrayList with targets
+ * Returns a human-readable log for given user event.
*/
- public static ArrayList<Target> makeTargetsList(Target... targets) {
- ArrayList<Target> result = new ArrayList<>();
- for (Target target : targets) {
- result.add(target);
+ public static String generateLog(LauncherEvent ev) {
+ String log = "\n-----------------------------------------------------"
+ + "\naction:" + LoggerUtils.getActionStr(ev.action);
+ if (ev.srcTarget != null && ev.srcTarget.length > 0) {
+ log += "\n Source " + getTargetsStr(ev.srcTarget);
+ }
+ if (ev.destTarget != null && ev.destTarget.length > 0) {
+ log += "\n Destination " + getTargetsStr(ev.destTarget);
+ }
+ log += String.format(Locale.US,
+ "\n Elapsed container %d ms, session %d ms, action %d ms",
+ ev.elapsedContainerMillis,
+ ev.elapsedSessionMillis,
+ ev.actionDurationMillis);
+ log += "\n\n";
+ return log;
+ }
+
+ private static String getTargetsStr(Target[] targets) {
+ String result = "child:" + LoggerUtils.getTargetStr(targets[0]);
+ for (int i = 1; i < targets.length; i++) {
+ result += "\tparent:" + LoggerUtils.getTargetStr(targets[i]);
}
return result;
}
diff --git a/src/com/android/launcher3/model/PagedViewOrientedState.java b/src/com/android/launcher3/model/PagedViewOrientedState.java
index e48b8c1..1349eff 100644
--- a/src/com/android/launcher3/model/PagedViewOrientedState.java
+++ b/src/com/android/launcher3/model/PagedViewOrientedState.java
@@ -50,16 +50,7 @@
*/
private boolean mDisableMultipleOrientations;
- /**
- * Sets the appropriate {@link PagedOrientationHandler} for {@link #mOrientationHandler}
- * @param touchRotation The rotation the nav bar region that is touched is in
- * @param displayRotation Rotation of the display/device
- */
public void update(int touchRotation, int displayRotation) {
- if (mDisableMultipleOrientations) {
- return;
- }
-
mDisplayRotation = displayRotation;
mTouchRotation = touchRotation;
if (mTouchRotation == Surface.ROTATION_90) {
@@ -71,13 +62,20 @@
}
}
+ /**
+ * @return {@code true} if the area where the user touched the nav bar is the expected
+ * location for the given display rotation. Ex. bottom of phone in portrait, or left side of
+ * phone in landscape, right side in seascape, etc.
+ * False otherwise
+ */
+ public boolean isTouchRegionNaturalForDisplay() {
+ return mTouchRotation == mDisplayRotation;
+ }
+
public boolean areMultipleLayoutOrientationsDisabled() {
return mDisableMultipleOrientations;
}
- /**
- * Setting this preference will render future calls to {@link #update(int, int)} as a no-op.
- */
public void disableMultipleOrientations(boolean disable) {
mDisableMultipleOrientations = disable;
if (disable) {
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 18bc55a..1c2acfd 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -240,17 +240,6 @@
* and align above if there is enough vertical space.
*/
protected void orientAboutObject() {
- orientAboutObject(true /* allowAlignLeft */, true /* allowAlignRight */);
- }
-
- /**
- * @see #orientAboutObject()
- *
- * @param allowAlignLeft Set to false if we already tried aligning left and didn't have room.
- * @param allowAlignRight Set to false if we already tried aligning right and didn't have room.
- * TODO: Can we test this with all permutations of widths/heights and icon locations + RTL?
- */
- private void orientAboutObject(boolean allowAlignLeft, boolean allowAlignRight) {
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
int width = getMeasuredWidth();
int extraVerticalSpace = mArrow.getLayoutParams().height + mArrowOffset
@@ -264,8 +253,14 @@
// Align left (right in RTL) if there is room.
int leftAlignedX = mTempRect.left;
int rightAlignedX = mTempRect.right - width;
- mIsLeftAligned = !mIsRtl ? allowAlignLeft : !allowAlignRight;
- int x = mIsLeftAligned ? leftAlignedX : rightAlignedX;
+ int x = leftAlignedX;
+ boolean canBeLeftAligned = leftAlignedX + width + insets.left
+ < dragLayer.getRight() - insets.right;
+ boolean canBeRightAligned = rightAlignedX > dragLayer.getLeft() + insets.left;
+ if (!canBeLeftAligned || (mIsRtl && canBeRightAligned)) {
+ x = rightAlignedX;
+ }
+ mIsLeftAligned = x == leftAlignedX;
// Offset x so that the arrow and shortcut icons are center-aligned with the original icon.
int iconWidth = mTempRect.width();
@@ -287,24 +282,6 @@
}
x += mIsLeftAligned ? xOffset : -xOffset;
- // Check whether we can still align as we originally wanted, now that we've calculated x.
- if (!allowAlignLeft && !allowAlignRight) {
- // We've already tried both ways and couldn't make it fit. onLayout() will set the
- // gravity to CENTER_HORIZONTAL, but continue below to update y.
- } else {
- boolean canBeLeftAligned = x + width + insets.left
- < dragLayer.getRight() - insets.right;
- boolean canBeRightAligned = x > dragLayer.getLeft() + insets.left;
- boolean alignmentStillValid = mIsLeftAligned && canBeLeftAligned
- || !mIsLeftAligned && canBeRightAligned;
- if (!alignmentStillValid) {
- // Try again, but don't allow this alignment we already know won't work.
- orientAboutObject(allowAlignLeft && !mIsLeftAligned /* allowAlignLeft */,
- allowAlignRight && mIsLeftAligned /* allowAlignRight */);
- return;
- }
- }
-
// Open above icon if there is room.
int iconHeight = mTempRect.height();
int y = mTempRect.top - height;
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 5af5ebb..445acca 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.notification.NotificationMainView.NOTIFICATION_ITEM_INFO;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
@@ -59,6 +58,7 @@
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.notification.NotificationInfo;
import com.android.launcher3.notification.NotificationItemView;
import com.android.launcher3.notification.NotificationKeyData;
@@ -172,7 +172,7 @@
BaseDragLayer dl = getPopupContainer();
if (!dl.isEventOverView(this, ev)) {
mLauncher.getUserEventDispatcher().logActionTapOutside(
- newContainerTarget(ContainerType.DEEPSHORTCUTS));
+ LoggerUtils.newContainerTarget(ContainerType.DEEPSHORTCUTS));
close(true);
// We let touches on the original icon go through so that users can launch
@@ -485,15 +485,14 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- if (childInfo == NOTIFICATION_ITEM_INFO) {
- child.itemType = ItemType.NOTIFICATION;
+ public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
+ if (info == NOTIFICATION_ITEM_INFO) {
+ target.itemType = ItemType.NOTIFICATION;
} else {
- child.itemType = ItemType.DEEPSHORTCUT;
- child.rank = childInfo.rank;
+ target.itemType = ItemType.DEEPSHORTCUT;
+ target.rank = info.rank;
}
- parents.add(newContainerTarget(ContainerType.DEEPSHORTCUTS));
+ targetParent.containerType = ContainerType.DEEPSHORTCUTS;
}
@Override
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index 936d377..8fffee8 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -54,11 +54,6 @@
public SecondaryDragLayer(Context context, AttributeSet attrs) {
super(context, attrs, 1 /* alphaChannelCount */);
- recreateControllers();
- }
-
- @Override
- public void recreateControllers() {
mControllers = new TouchController[] {new CloseAllAppsTouchController()};
}
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index fae0fe2..43d54eb 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -21,13 +21,13 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATION_TRANSFORM;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.ContentResolver;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -72,13 +72,26 @@
return originalSmallestWidth >= 600;
}
+
+ private final ContentObserver mContentObserver =
+ new ContentObserver(MAIN_EXECUTOR.getHandler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ boolean forcedRotation = Utilities.isForcedRotation(mLauncher);
+ PagedView.sFlagForcedRotation = forcedRotation;
+ updateForcedRotation();
+ for (ForcedRotationChangedListener listener : mForcedRotationChangedListeners) {
+ listener.onForcedRotationChanged(forcedRotation);
+ }
+ }
+ };
+
public static final int REQUEST_NONE = 0;
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
private final Launcher mLauncher;
- private final SharedPreferences mSharedPrefs;
- private final SharedPreferences mFeatureFlagsPrefs;
+ private final SharedPreferences mPrefs;
private boolean mIgnoreAutoRotateSettings;
private boolean mAutoRotateEnabled;
@@ -112,42 +125,24 @@
// On large devices we do not handle auto-rotate differently.
mIgnoreAutoRotateSettings = mLauncher.getResources().getBoolean(R.bool.allow_rotation);
+ updateForcedRotation();
if (!mIgnoreAutoRotateSettings) {
- mSharedPrefs = Utilities.getPrefs(mLauncher);
- mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
- mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ mPrefs = Utilities.getPrefs(mLauncher);
+ mPrefs.registerOnSharedPreferenceChangeListener(this);
+ mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
} else {
- mSharedPrefs = null;
+ mPrefs = null;
}
+ // TODO(b/150260456) Add this in home settings as well
mContentResolver = launcher.getContentResolver();
- mFeatureFlagsPrefs = Utilities.getFeatureFlagsPrefs(mLauncher);
- mFeatureFlagsPrefs.registerOnSharedPreferenceChangeListener(this);
- updateForcedRotation(true);
+ mContentResolver.registerContentObserver(Settings.Global.getUriFor(
+ FIXED_ROTATION_TRANSFORM_SETTING_NAME), false, mContentObserver);
}
- /**
- * @param setValueFromPrefs If true, then {@link #mForcedRotation} will get set to the value
- * from the home developer settings. Otherwise it will not.
- * This is primarily to allow tests to set their own conditions.
- */
- private void updateForcedRotation(boolean setValueFromPrefs) {
- boolean isForcedRotation = mFeatureFlagsPrefs
- .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true)
- && !getAllowRotationDefaultValue();
- if (mForcedRotation == isForcedRotation) {
- return;
- }
- if (setValueFromPrefs) {
- mForcedRotation = isForcedRotation;
- }
- UI_HELPER_EXECUTOR.execute(
- () -> Settings.Global.putInt(mContentResolver, FIXED_ROTATION_TRANSFORM_SETTING_NAME,
- mForcedRotation ? 1 : 0));
- for (ForcedRotationChangedListener listener : mForcedRotationChangedListeners) {
- listener.onForcedRotationChanged(mForcedRotation);
- }
+ private void updateForcedRotation() {
+ mForcedRotation = !getAllowRotationDefaultValue() && Utilities.isForcedRotation(mLauncher);
}
/**
@@ -186,13 +181,8 @@
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
- if (FLAG_ENABLE_FIXED_ROTATION_TRANSFORM.equals(s)) {
- updateForcedRotation(true);
- return;
- }
-
boolean wasRotationEnabled = mAutoRotateEnabled;
- mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
if (mAutoRotateEnabled != wasRotationEnabled) {
@@ -228,10 +218,6 @@
public void forceAllowRotationForTesting(boolean allowRotation) {
mIgnoreAutoRotateSettings =
allowRotation || mLauncher.getResources().getBoolean(R.bool.allow_rotation);
- // TODO(b/150214193) Tests currently expect launcher to be able to be rotated
- // Modify tests for this new behavior
- mForcedRotation = !allowRotation;
- updateForcedRotation(false);
notifyChange();
}
@@ -246,11 +232,13 @@
public void destroy() {
if (!mDestroyed) {
mDestroyed = true;
- if (mSharedPrefs != null) {
- mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ if (mPrefs != null) {
+ mPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ }
+ if (mContentResolver != null) {
+ mContentResolver.unregisterContentObserver(mContentObserver);
}
mForcedRotationChangedListeners.clear();
- mFeatureFlagsPrefs.unregisterOnSharedPreferenceChangeListener(this);
}
}
@@ -305,7 +293,7 @@
return degrees;
}
- public static int getRotationFromDegrees(float degrees) {
+ public static int getRotationFromDegrees(int degrees) {
int threshold = 70;
if (degrees >= (360 - threshold) || degrees < (threshold)) {
return Surface.ROTATION_0;
@@ -330,30 +318,11 @@
}
/**
- * For landscape, since the navbar is already in a vertical position, we don't have to do any
- * rotations as the change in Y coordinate is what is read. We only flip the sign of the
- * y coordinate to make it match existing behavior of swipe to the top to go previous
- */
- public static void transformEventForNavBar(MotionEvent ev, boolean inverse) {
- // TODO(b/151269990): Use a temp matrix
- Matrix m = new Matrix();
- m.setScale(1, -1);
- if (inverse) {
- Matrix inv = new Matrix();
- m.invert(inv);
- ev.transform(inv);
- } else {
- ev.transform(m);
- }
- }
-
- /**
* Creates a matrix to transform the given motion event specified by degrees.
* If {@param inverse} is {@code true}, the inverse of that matrix will be applied
*/
public static void transformEvent(float degrees, MotionEvent ev, boolean inverse) {
Matrix transform = new Matrix();
- // TODO(b/151269990): Use a temp matrix
transform.setRotate(degrees);
if (inverse) {
Matrix inv = new Matrix();
@@ -375,7 +344,6 @@
*/
public static Matrix getRotationMatrix(int screenWidth, int screenHeight, int displayRotation) {
Matrix m = new Matrix();
- // TODO(b/151269990): Use a temp matrix
switch (displayRotation) {
case Surface.ROTATION_0:
return m;
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index c3664c3..34d69e9 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -19,9 +19,9 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.LauncherStateManager.ANIM_ALL_COMPONENTS;
-import static com.android.launcher3.LauncherStateManager.PLAY_ATOMIC_OVERVIEW_SCALE;
-import static com.android.launcher3.LauncherStateManager.PLAY_NON_ATOMIC;
+import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
+import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_SCALE_COMPONENT;
+import static com.android.launcher3.LauncherStateManager.NON_ATOMIC_COMPONENT;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
@@ -37,16 +37,16 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager.AnimationFlags;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.AnimatorSetBuilder;
-import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.FlingBlockCheck;
+import com.android.launcher3.util.PendingAnimation;
import com.android.launcher3.util.TouchController;
/**
@@ -176,7 +176,7 @@
protected abstract LauncherState getTargetState(LauncherState fromState,
boolean isDragTowardPositive);
- protected abstract float initCurrentAnimation(@AnimationFlags int animComponents);
+ protected abstract float initCurrentAnimation(@AnimationComponents int animComponents);
/**
* Returns the container that the touch started from when leaving NORMAL state.
@@ -201,10 +201,10 @@
mCurrentAnimation.setOnCancelRunnable(null);
}
int animComponents = goingBetweenNormalAndOverview(mFromState, mToState)
- ? PLAY_NON_ATOMIC : ANIM_ALL_COMPONENTS;
+ ? NON_ATOMIC_COMPONENT : ANIM_ALL;
mScheduleResumeAtomicComponent = false;
if (mAtomicAnim != null) {
- animComponents = PLAY_NON_ATOMIC;
+ animComponents = NON_ATOMIC_COMPONENT;
// Control the non-atomic components until the atomic animation finishes, then control
// the atomic components as well.
mScheduleResumeAtomicComponent = true;
@@ -215,7 +215,7 @@
}
if (mAtomicComponentsController != null) {
- animComponents &= ~PLAY_ATOMIC_OVERVIEW_SCALE;
+ animComponents &= ~ATOMIC_OVERVIEW_SCALE_COMPONENT;
}
mProgressMultiplier = initCurrentAnimation(animComponents);
mCurrentAnimation.dispatchOnStart();
@@ -360,7 +360,7 @@
long duration) {
AnimatorSetBuilder builder = getAnimatorSetBuilderForStates(fromState, targetState);
return mLauncher.getStateManager().createAtomicAnimation(fromState, targetState, builder,
- PLAY_ATOMIC_OVERVIEW_SCALE, duration);
+ ATOMIC_OVERVIEW_SCALE_COMPONENT, duration);
}
protected AnimatorSetBuilder getAnimatorSetBuilderForStates(LauncherState fromState,
@@ -434,7 +434,7 @@
maybeUpdateAtomicAnim(mFromState, targetState, targetState == mToState ? 1f : 0f);
updateSwipeCompleteAnimation(anim, Math.max(duration, getRemainingAtomicDuration()),
targetState, velocity, fling);
- mCurrentAnimation.dispatchOnStart();
+ mCurrentAnimation.dispatchOnStartWithVelocity(endProgress, progressVelocity);
if (fling && targetState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
mLauncher.getAppsView().addSpringFromFlingUpdateListener(anim, velocity);
}
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 8d5f33d..31a5d79 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -23,7 +23,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager.AnimationFlags;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
@@ -76,7 +76,7 @@
}
@Override
- protected float initCurrentAnimation(@AnimationFlags int animComponents) {
+ protected float initCurrentAnimation(@AnimationComponents int animComponents) {
float range = getShiftRange();
long maxAccuracy = (long) (2 * range);
mCurrentAnimation = mLauncher.getStateManager()
diff --git a/src/com/android/launcher3/util/PendingAnimation.java b/src/com/android/launcher3/util/PendingAnimation.java
new file mode 100644
index 0000000..617a38b
--- /dev/null
+++ b/src/com/android/launcher3/util/PendingAnimation.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 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.util;
+
+import android.animation.AnimatorSet;
+import android.annotation.TargetApi;
+import android.os.Build;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * Utility class to keep track of a running animation.
+ *
+ * This class allows attaching end callbacks to an animation is intended to be used with
+ * {@link com.android.launcher3.anim.AnimatorPlaybackController}, since in that case
+ * AnimationListeners are not properly dispatched.
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class PendingAnimation {
+
+ private final ArrayList<Consumer<OnEndListener>> mEndListeners = new ArrayList<>();
+
+ public final AnimatorSet anim;
+
+ public PendingAnimation(AnimatorSet anim) {
+ this.anim = anim;
+ }
+
+ public void finish(boolean isSuccess, int logAction) {
+ for (Consumer<OnEndListener> listeners : mEndListeners) {
+ listeners.accept(new OnEndListener(isSuccess, logAction));
+ }
+ mEndListeners.clear();
+ }
+
+ public void addEndListener(Consumer<OnEndListener> listener) {
+ mEndListeners.add(listener);
+ }
+
+ public static class OnEndListener {
+ public boolean isSuccess;
+ public int logAction;
+
+ public OnEndListener(boolean isSuccess, int logAction) {
+ this.isSuccess = isSuccess;
+ this.logAction = logAction;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 25748ae..254655c 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -40,6 +40,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
@@ -115,11 +116,6 @@
}
/**
- * Called to reinitialize touch controllers.
- */
- public abstract void recreateControllers();
-
- /**
* Same as {@link #isEventOverView(View, MotionEvent, View)} where evView == this drag layer.
*/
public boolean isEventOverView(View view, MotionEvent ev) {
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 6d204f6..8ce98f2 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -40,7 +40,7 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
-import android.util.IntProperty;
+import android.util.Property;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -80,8 +80,8 @@
public class ScrimView<T extends Launcher> extends View implements Insettable, OnChangeListener,
AccessibilityStateChangeListener, StateListener {
- public static final IntProperty<ScrimView> DRAG_HANDLE_ALPHA =
- new IntProperty<ScrimView>("dragHandleAlpha") {
+ public static final Property<ScrimView, Integer> DRAG_HANDLE_ALPHA =
+ new Property<ScrimView, Integer>(Integer.TYPE, "dragHandleAlpha") {
@Override
public Integer get(ScrimView scrimView) {
@@ -89,7 +89,7 @@
}
@Override
- public void setValue(ScrimView scrimView, int value) {
+ public void set(ScrimView scrimView, Integer value) {
scrimView.setDragHandleAlpha(value);
}
};
@@ -336,7 +336,7 @@
}
private void updateDragHandleVisibility(Drawable recycle) {
- boolean visible = shouldDragHandleBeVisible();
+ boolean visible = mLauncher.getDeviceProfile().isVerticalBarLayout() || mAM.isEnabled();
boolean wasVisible = mDragHandle != null;
if (visible != wasVisible) {
if (visible) {
@@ -352,10 +352,6 @@
}
}
- protected boolean shouldDragHandleBeVisible() {
- return mLauncher.getDeviceProfile().isVerticalBarLayout() || mAM.isEnabled();
- }
-
@Override
public boolean dispatchHoverEvent(MotionEvent event) {
return mAccessibilityHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event);
diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java
index d849138..81f8327 100644
--- a/src/com/android/launcher3/views/WorkEduView.java
+++ b/src/com/android/launcher3/views/WorkEduView.java
@@ -46,8 +46,7 @@
public class WorkEduView extends AbstractSlideInView implements Insettable {
private static final int DEFAULT_CLOSE_DURATION = 200;
- public static final String KEY_WORK_EDU_STEP = "showed_work_profile_edu";
- public static final String KEY_LEGACY_WORK_EDU_SEEN = "showed_bottom_user_education";
+ private static final String KEY_WORK_EDU_STEP = "showed_work_profile_edu";
private static final int WORK_EDU_NOT_STARTED = 0;
private static final int WORK_EDU_PERSONAL_APPS = 1;
@@ -103,8 +102,6 @@
mProceedButton = findViewById(R.id.proceed);
mContentText = findViewById(R.id.content_text);
- // make sure layout does not shrink when we change the text
- mContentText.post(() -> mContentText.setMinLines(mContentText.getLineCount()));
if (mLauncher.getAppsView().getContentView() instanceof AllAppsPagedView) {
mAllAppsPagedView = (AllAppsPagedView) mLauncher.getAppsView().getContentView();
}
@@ -182,8 +179,8 @@
if (oldListener != null) {
launcher.getStateManager().removeStateListener(oldListener);
}
- if (hasSeenLegacyEdu(launcher) || launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP,
- WORK_EDU_NOT_STARTED) != WORK_EDU_NOT_STARTED) {
+ if (launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP, WORK_EDU_NOT_STARTED)
+ != WORK_EDU_NOT_STARTED) {
return null;
}
@@ -213,8 +210,8 @@
* Shows work apps edu if user had dismissed full edu flow
*/
public static void showWorkEduIfNeeded(Launcher launcher) {
- if (hasSeenLegacyEdu(launcher) || launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP,
- WORK_EDU_NOT_STARTED) != WORK_EDU_PERSONAL_APPS) {
+ if (launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP, WORK_EDU_NOT_STARTED)
+ != WORK_EDU_PERSONAL_APPS) {
return;
}
LayoutInflater layoutInflater = LayoutInflater.from(launcher);
@@ -223,8 +220,4 @@
v.show();
v.goToWorkTab(false);
}
-
- private static boolean hasSeenLegacyEdu(Launcher launcher) {
- return launcher.getSharedPrefs().getBoolean(KEY_LEGACY_WORK_EDU_SEEN, false);
- }
}
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 73a0615..df1a469 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -41,8 +41,6 @@
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.AbstractSlideInView;
-import java.util.ArrayList;
-
/**
* Base class for various widgets popup
*/
@@ -146,11 +144,9 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- Target target = newContainerTarget(ContainerType.WIDGETS);
- target.cardinality = getElementsRowCount();
- parents.add(target);
+ public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
+ targetParent.containerType = ContainerType.WIDGETS;
+ targetParent.cardinality = getElementsRowCount();
}
@Override