diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2019-07-23 11:26:38 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2019-07-24 10:12:37 -0700 |
commit | 4e6c45bcd3717af05a892a92565d55aa20728644 (patch) | |
tree | a4cd5eff6806d6962c5ca7dcfbeacfb24a31c49e /src/com/android | |
parent | b6841ac630fd4ca894e2638586511e3085c40baa (diff) | |
download | android_packages_apps_Trebuchet-4e6c45bcd3717af05a892a92565d55aa20728644.tar.gz android_packages_apps_Trebuchet-4e6c45bcd3717af05a892a92565d55aa20728644.tar.bz2 android_packages_apps_Trebuchet-4e6c45bcd3717af05a892a92565d55aa20728644.zip |
Using the first frame delay based on the display refresh rate instead of
hardcoding it to 16ms
> Creating a utility class for caching display property changes
Bug: 128940249
Change-Id: I6f9a214548de65bd1c8530508d665ee88312da4a
Diffstat (limited to 'src/com/android')
5 files changed, 190 insertions, 23 deletions
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java index c967a96e4..6c5bc40b3 100644 --- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java +++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java @@ -15,7 +15,7 @@ */ package com.android.launcher3; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; @@ -108,17 +108,20 @@ public class FirstFrameAnimatorHelper implements OnDrawListener, OnAttachStateCh // For the second frame, if the first frame took more than 16ms, // adjust the start time and pretend it took only 16ms anyway. This // prevents a large jump in the animation due to an expensive first frame - } else if (frameNum == 1 && currentTime < mStartTime + MAX_DELAY && - !mAdjustedSecondFrameTime && - currentTime > mStartTime + SINGLE_FRAME_MS && - currentPlayTime > SINGLE_FRAME_MS) { - animation.setCurrentPlayTime(SINGLE_FRAME_MS); - mAdjustedSecondFrameTime = true; } else { - if (frameNum > 1) { - mRootView.post(() -> animation.removeUpdateListener(this)); + int singleFrameMS = getSingleFrameMs(mRootView.getContext()); + if (frameNum == 1 && currentTime < mStartTime + MAX_DELAY && + !mAdjustedSecondFrameTime && + currentTime > mStartTime + singleFrameMS && + currentPlayTime > singleFrameMS) { + animation.setCurrentPlayTime(singleFrameMS); + mAdjustedSecondFrameTime = true; + } else { + if (frameNum > 1) { + mRootView.post(() -> animation.removeUpdateListener(this)); + } + if (DEBUG) print(animation); } - if (DEBUG) print(animation); } mHandlingOnAnimationUpdate = false; } else { diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index 8443231e8..c45cd85aa 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -16,8 +16,9 @@ package com.android.launcher3.anim; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; +import android.content.Context; import android.graphics.Path; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; @@ -188,13 +189,13 @@ public class Interpolators { * @param totalDistancePx The distance against which progress is calculated. */ public OvershootParams(float startProgress, float overshootPastProgress, - float endProgress, float velocityPxPerMs, int totalDistancePx) { + float endProgress, float velocityPxPerMs, int totalDistancePx, Context context) { velocityPxPerMs = Math.abs(velocityPxPerMs); start = startProgress; int startPx = (int) (start * totalDistancePx); // Overshoot by about half a frame. float overshootBy = OVERSHOOT_FACTOR * velocityPxPerMs * - SINGLE_FRAME_MS / totalDistancePx / 2; + getSingleFrameMs(context) / totalDistancePx / 2; overshootBy = Utilities.boundToRange(overshootBy, 0.02f, 0.15f); end = overshootPastProgress + overshootBy; int endPx = (int) (end * totalDistancePx); diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index ae69f3b32..49f515ad4 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -22,9 +22,9 @@ import static com.android.launcher3.LauncherState.OVERVIEW; 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.Utilities.SINGLE_FRAME_MS; import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity; import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -55,8 +55,6 @@ import com.android.launcher3.util.TouchController; public abstract class AbstractStateChangeTouchController implements TouchController, SwipeDetector.Listener { - private static final String TAG = "ASCTouchController"; - // Progress after which the transition is assumed to be a success in case user does not fling public static final float SUCCESS_TRANSITION_PROGRESS = 0.5f; @@ -396,8 +394,8 @@ public abstract class AbstractStateChangeTouchController duration = 0; startProgress = 1; } else { - startProgress = Utilities.boundToRange( - progress + velocity * SINGLE_FRAME_MS * mProgressMultiplier, 0f, 1f); + startProgress = Utilities.boundToRange(progress + + velocity * getSingleFrameMs(mLauncher) * mProgressMultiplier, 0f, 1f); duration = SwipeDetector.calculateDuration(velocity, endProgress - Math.max(progress, 0)) * durationMultiplier; } @@ -414,8 +412,8 @@ public abstract class AbstractStateChangeTouchController duration = 0; startProgress = 0; } else { - startProgress = Utilities.boundToRange( - progress + velocity * SINGLE_FRAME_MS * mProgressMultiplier, 0f, 1f); + startProgress = Utilities.boundToRange(progress + + velocity * getSingleFrameMs(mLauncher) * mProgressMultiplier, 0f, 1f); duration = SwipeDetector.calculateDuration(velocity, Math.min(progress, 1) - endProgress) * durationMultiplier; } diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java new file mode 100644 index 000000000..7719f084d --- /dev/null +++ b/src/com/android/launcher3/util/DefaultDisplay.java @@ -0,0 +1,166 @@ +/* + * 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.util; + +import android.content.Context; +import android.graphics.Point; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.Display; +import android.view.WindowManager; + +import java.util.ArrayList; + +/** + * Utility class to cache properties of default display to avoid a system RPC on every call. + */ +public class DefaultDisplay implements DisplayListener { + + public static final MainThreadInitializedObject<DefaultDisplay> INSTANCE = + new MainThreadInitializedObject<>(DefaultDisplay::new); + + private static final String TAG = "DefaultDisplay"; + + public static final int CHANGE_SIZE = 1 << 0; + public static final int CHANGE_ROTATION = 1 << 1; + public static final int CHANGE_FRAME_DELAY = 1 << 2; + + private final Context mContext; + private final int mId; + private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>(); + private final Handler mChangeHandler; + private Info mInfo; + + private DefaultDisplay(Context context) { + mContext = context; + mInfo = new Info(context); + mId = mInfo.id; + mChangeHandler = new Handler(this::onChange); + + context.getSystemService(DisplayManager.class) + .registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper())); + } + + @Override + public final void onDisplayAdded(int displayId) { } + + @Override + public final void onDisplayRemoved(int displayId) { } + + @Override + public final void onDisplayChanged(int displayId) { + if (displayId != mId) { + return; + } + + Info oldInfo = mInfo; + Info info = new Info(mContext); + + int change = 0; + if (info.hasDifferentSize(oldInfo)) { + change |= CHANGE_SIZE; + } + if (oldInfo.rotation != info.rotation) { + change |= CHANGE_ROTATION; + } + if (info.singleFrameMs != oldInfo.singleFrameMs) { + change |= CHANGE_FRAME_DELAY; + } + + if (change != 0) { + mInfo = info; + mChangeHandler.sendEmptyMessage(change); + } + } + + public static int getSingleFrameMs(Context context) { + return INSTANCE.get(context).getInfo().singleFrameMs; + } + + public Info getInfo() { + return mInfo; + } + + public void addChangeListener(DisplayInfoChangeListener listener) { + mListeners.add(listener); + } + + public void removeChangeListener(DisplayInfoChangeListener listener) { + mListeners.remove(listener); + } + + private boolean onChange(Message msg) { + for (int i = mListeners.size() - 1; i >= 0; i--) { + mListeners.get(i).onDisplayInfoChanged(mInfo, msg.what); + } + return true; + } + + public static class Info { + + public final int id; + public final int rotation; + public final int singleFrameMs; + + public final Point realSize; + public final Point smallestSize; + public final Point largestSize; + + private Info(Context context) { + Display display = context.getSystemService(WindowManager.class).getDefaultDisplay(); + + id = display.getDisplayId(); + rotation = display.getRotation(); + + float refreshRate = display.getRefreshRate(); + singleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16; + + realSize = new Point(); + smallestSize = new Point(); + largestSize = new Point(); + display.getRealSize(realSize); + display.getCurrentSizeRange(smallestSize, largestSize); + } + + private boolean hasDifferentSize(Info info) { + if (!realSize.equals(info.realSize) + && !realSize.equals(info.realSize.y, info.realSize.x)) { + Log.d(TAG, String.format("Display size changed from %s to %s", + info.realSize, realSize)); + return true; + } + + if (!smallestSize.equals(info.smallestSize) || !largestSize.equals(info.largestSize)) { + Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]", + smallestSize, largestSize, info.smallestSize, info.largestSize)); + return true; + } + + return false; + } + } + + /** + * Interface for listening for display changes + */ + public interface DisplayInfoChangeListener { + + void onDisplayInfoChanged(Info info, int flags); + } +} diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index f2f2f3b53..799762d8f 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -20,7 +20,7 @@ import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import android.annotation.TargetApi; import android.content.Context; @@ -41,7 +41,6 @@ import android.widget.FrameLayout; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.Utilities; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.TouchController; @@ -219,7 +218,7 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext> // This can happen if something goes wrong during a state change/transition. AbstractFloatingView floatingView = (AbstractFloatingView) child; if (floatingView.isOpen()) { - postDelayed(() -> floatingView.close(false), SINGLE_FRAME_MS); + postDelayed(() -> floatingView.close(false), getSingleFrameMs(getContext())); } } } |