Snap for 9032824 from 2ae4420a12 to tm-qpr1-release
Change-Id: I96f55323cd7279874f8a95e63918880df6086317
This commit is contained in:
@@ -35,6 +35,7 @@ import androidx.core.content.ContextCompat;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.FloatingHeaderRow;
|
||||
import com.android.launcher3.allapps.FloatingHeaderView;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
|
||||
@@ -92,8 +93,10 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
|
||||
? R.color.all_apps_label_text_dark
|
||||
: R.color.all_apps_label_text);
|
||||
|
||||
mShowAllAppsLabel = !ActivityContext.lookupContext(
|
||||
getContext()).getOnboardingPrefs().hasReachedMaxCount(ALL_APPS_VISITED_COUNT);
|
||||
OnboardingPrefs<?> onboardingPrefs = ActivityContext.lookupContext(
|
||||
getContext()).getOnboardingPrefs();
|
||||
mShowAllAppsLabel = onboardingPrefs == null || !onboardingPrefs.hasReachedMaxCount(
|
||||
ALL_APPS_VISITED_COUNT);
|
||||
}
|
||||
|
||||
public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) {
|
||||
@@ -216,8 +219,8 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
|
||||
|
||||
CharSequence allAppsLabelText = getResources().getText(R.string.all_apps_label);
|
||||
mAllAppsLabelLayout = StaticLayout.Builder.obtain(
|
||||
allAppsLabelText, 0, allAppsLabelText.length(), mPaint,
|
||||
Math.round(mPaint.measureText(allAppsLabelText.toString())))
|
||||
allAppsLabelText, 0, allAppsLabelText.length(), mPaint,
|
||||
Math.round(mPaint.measureText(allAppsLabelText.toString())))
|
||||
.setAlignment(Layout.Alignment.ALIGN_CENTER)
|
||||
.setMaxLines(1)
|
||||
.setIncludePad(true)
|
||||
|
||||
@@ -334,6 +334,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_GESTURE_COMPLETED;
|
||||
} else if (stateFlag == STATE_GESTURE_CANCELLED) {
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_GESTURE_CANCELLED;
|
||||
} else if (stateFlag == STATE_SCREENSHOT_CAPTURED) {
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_SCREENSHOT_CAPTURED;
|
||||
} else if (stateFlag == STATE_CAPTURE_SCREENSHOT) {
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_CAPTURE_SCREENSHOT;
|
||||
} else if (stateFlag == STATE_HANDLER_INVALIDATED) {
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_HANDLER_INVALIDATED;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1222,6 +1228,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
|
||||
// or resumeLastTask().
|
||||
if (mRecentsView != null) {
|
||||
ActiveGestureLog.INSTANCE.trackEvent(ActiveGestureErrorDetector.GestureEvent
|
||||
.SET_ON_PAGE_TRANSITION_END_CALLBACK);
|
||||
mRecentsView.setOnPageTransitionEndCallback(
|
||||
() -> mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED));
|
||||
} else {
|
||||
@@ -1535,7 +1543,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
Rect keepClearArea;
|
||||
if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
|
||||
// make the height equal to hotseatBarSizePx only
|
||||
keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, 0);
|
||||
keepClearArea = new Rect(0, 0, 0, mDp.hotseatBarSizePx);
|
||||
return keepClearArea;
|
||||
}
|
||||
// the keep clear area in global screen coordinates, in pixels
|
||||
@@ -1699,6 +1707,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
* handler (in case of quick switch).
|
||||
*/
|
||||
private void cancelCurrentAnimation() {
|
||||
ActiveGestureLog.INSTANCE.addLog(
|
||||
"AbsSwipeUpHandler.cancelCurrentAnimation",
|
||||
ActiveGestureErrorDetector.GestureEvent.CANCEL_CURRENT_ANIMATION);
|
||||
mCanceled = true;
|
||||
mCurrentShift.cancelAnimation();
|
||||
|
||||
|
||||
@@ -189,6 +189,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_END_TARGET_ANIMATION_FINISHED;
|
||||
} else if (stateFlag == STATE_RECENTS_SCROLLING_FINISHED) {
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_RECENTS_SCROLLING_FINISHED;
|
||||
} else if (stateFlag == STATE_RECENTS_ANIMATION_CANCELED) {
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_RECENTS_ANIMATION_CANCELED;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.quickstep.util.ActiveGestureErrorDetector;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
|
||||
@@ -172,7 +174,12 @@ public class RecentsAnimationController {
|
||||
*/
|
||||
@UiThread
|
||||
public void cleanupScreenshot() {
|
||||
UI_HELPER_EXECUTOR.execute(() -> mController.cleanupScreenshot());
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
ActiveGestureLog.INSTANCE.addLog(
|
||||
"cleanupScreenshot",
|
||||
ActiveGestureErrorDetector.GestureEvent.CLEANUP_SCREENSHOT);
|
||||
mController.cleanupScreenshot();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,8 @@ import androidx.annotation.UiThread;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
|
||||
import com.android.quickstep.util.ActiveGestureErrorDetector;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -136,6 +138,8 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
// handling this call entirely
|
||||
return;
|
||||
}
|
||||
ActiveGestureLog.INSTANCE.addLog("TaskAnimationManager.startRecentsAnimation",
|
||||
ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION);
|
||||
mController = controller;
|
||||
mTargets = targets;
|
||||
mLastAppearedTaskTarget = mTargets.findTask(mLastGestureState.getRunningTaskId());
|
||||
|
||||
@@ -43,7 +43,6 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MOD
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.PendingIntent;
|
||||
@@ -198,8 +197,7 @@ public final class TaskViewUtils {
|
||||
BaseActivity baseActivity = BaseActivity.fromContext(context);
|
||||
DeviceProfile dp = baseActivity.getDeviceProfile();
|
||||
boolean showAsGrid = dp.isTablet;
|
||||
boolean parallaxCenterAndAdjacentTask =
|
||||
taskIndex != recentsView.getCurrentPage() && !showAsGrid;
|
||||
boolean parallaxCenterAndAdjacentTask = taskIndex != recentsView.getCurrentPage();
|
||||
int taskRectTranslationPrimary = recentsView.getScrollOffset(taskIndex);
|
||||
int taskRectTranslationSecondary = showAsGrid ? (int) v.getGridTranslationY() : 0;
|
||||
|
||||
@@ -603,11 +601,7 @@ public final class TaskViewUtils {
|
||||
if (raController != null) {
|
||||
raController.setWillFinishToHome(false);
|
||||
}
|
||||
Context context = v.getContext();
|
||||
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
|
||||
launcherAnim = dp.isTablet
|
||||
? ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, 0)
|
||||
: recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
|
||||
launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
|
||||
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
|
||||
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
|
||||
|
||||
|
||||
@@ -721,8 +721,10 @@ public class TouchInteractionService extends Service
|
||||
gestureState.updateRunningTask(taskInfo);
|
||||
}
|
||||
// Log initial state for the gesture.
|
||||
ActiveGestureLog.INSTANCE.addLog(
|
||||
"Current SystemUi state flags= " + mDeviceState.getSystemUiStateString());
|
||||
ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current running task package name=")
|
||||
.append(taskInfo == null ? "no running task" : taskInfo.getPackageName()));
|
||||
ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current SystemUi state flags=")
|
||||
.append(mDeviceState.getSystemUiStateString()));
|
||||
return gestureState;
|
||||
}
|
||||
|
||||
@@ -1024,12 +1026,27 @@ public class TouchInteractionService extends Service
|
||||
.append("activity == null, trying to use default input consumer"));
|
||||
}
|
||||
|
||||
if (activity.getRootView().hasWindowFocus()
|
||||
|| previousGestureState.isRunningAnimationToLauncher()
|
||||
|| (ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
|
||||
&& forceOverviewInputConsumer)
|
||||
|| (ENABLE_QUICKSTEP_LIVE_TILE.get()
|
||||
&& gestureState.getActivityInterface().isInLiveTileMode())) {
|
||||
boolean hasWindowFocus = activity.getRootView().hasWindowFocus();
|
||||
boolean isPreviousGestureAnimatingToLauncher =
|
||||
previousGestureState.isRunningAnimationToLauncher();
|
||||
boolean forcingOverviewInputConsumer =
|
||||
ASSISTANT_GIVES_LAUNCHER_FOCUS.get() && forceOverviewInputConsumer;
|
||||
boolean isInLiveTileMode = ENABLE_QUICKSTEP_LIVE_TILE.get()
|
||||
&& gestureState.getActivityInterface().isInLiveTileMode();
|
||||
reasonString.append(SUBSTRING_PREFIX)
|
||||
.append(hasWindowFocus
|
||||
? "activity has window focus"
|
||||
: (isPreviousGestureAnimatingToLauncher
|
||||
? "previous gesture is still animating to launcher"
|
||||
: (forcingOverviewInputConsumer
|
||||
? "assistant gives launcher focus and forcing focus"
|
||||
: (isInLiveTileMode
|
||||
? "device is in live mode"
|
||||
: "all overview focus conditions failed"))));
|
||||
if (hasWindowFocus
|
||||
|| isPreviousGestureAnimatingToLauncher
|
||||
|| forcingOverviewInputConsumer
|
||||
|| isInLiveTileMode) {
|
||||
reasonString.append(SUBSTRING_PREFIX)
|
||||
.append("overview should have focus, using OverviewInputConsumer");
|
||||
return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
|
||||
|
||||
+13
-1
@@ -28,6 +28,8 @@ import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
@@ -41,6 +43,7 @@ import com.android.quickstep.RecentsAnimationCallbacks;
|
||||
import com.android.quickstep.RecentsAnimationController;
|
||||
import com.android.quickstep.RecentsAnimationTargets;
|
||||
import com.android.quickstep.TaskAnimationManager;
|
||||
import com.android.quickstep.util.ActiveGestureErrorDetector;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
@@ -99,7 +102,8 @@ public class ProgressDelegateInputConsumer implements InputConsumer,
|
||||
mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().currentSize;
|
||||
|
||||
// Init states
|
||||
mStateCallback = new MultiStateCallback(STATE_NAMES);
|
||||
mStateCallback = new MultiStateCallback(
|
||||
STATE_NAMES, ProgressDelegateInputConsumer::getTrackedEventForState);
|
||||
mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_HANDLER_INVALIDATED,
|
||||
this::endRemoteAnimation);
|
||||
mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_FLING_FINISHED,
|
||||
@@ -109,6 +113,14 @@ public class ProgressDelegateInputConsumer implements InputConsumer,
|
||||
mSwipeDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ActiveGestureErrorDetector.GestureEvent getTrackedEventForState(int stateFlag) {
|
||||
if (stateFlag == STATE_HANDLER_INVALIDATED) {
|
||||
return ActiveGestureErrorDetector.GestureEvent.STATE_HANDLER_INVALIDATED;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return TYPE_PROGRESS_DELEGATE;
|
||||
|
||||
@@ -29,11 +29,24 @@ import java.util.Set;
|
||||
*/
|
||||
public class ActiveGestureErrorDetector {
|
||||
|
||||
/**
|
||||
* Enums associated to gesture navigation events.
|
||||
*/
|
||||
public enum GestureEvent {
|
||||
MOTION_DOWN, MOTION_UP, SET_END_TARGET, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
|
||||
FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, STATE_GESTURE_STARTED,
|
||||
STATE_GESTURE_COMPLETED, STATE_GESTURE_CANCELLED, STATE_END_TARGET_ANIMATION_FINISHED,
|
||||
STATE_RECENTS_SCROLLING_FINISHED
|
||||
FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
|
||||
CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
|
||||
|
||||
/**
|
||||
* These GestureEvents are specifically associated to state flags that get set in
|
||||
* {@link com.android.quickstep.MultiStateCallback}. If a state flag needs to be tracked
|
||||
* for error detection, an enum should be added here and that state flag-enum pair should
|
||||
* be added to the state flag's container class' {@code getTrackedEventForState} method.
|
||||
*/
|
||||
STATE_GESTURE_STARTED, STATE_GESTURE_COMPLETED, STATE_GESTURE_CANCELLED,
|
||||
STATE_END_TARGET_ANIMATION_FINISHED, STATE_RECENTS_SCROLLING_FINISHED,
|
||||
STATE_CAPTURE_SCREENSHOT, STATE_SCREENSHOT_CAPTURED, STATE_HANDLER_INVALIDATED,
|
||||
STATE_RECENTS_ANIMATION_CANCELED
|
||||
}
|
||||
|
||||
private ActiveGestureErrorDetector() {}
|
||||
@@ -90,6 +103,14 @@ public class ActiveGestureErrorDetector {
|
||||
+ "before/without startRecentsAnimation.",
|
||||
writer);
|
||||
break;
|
||||
case CLEANUP_SCREENSHOT:
|
||||
errorDetected |= printErrorIfTrue(
|
||||
!encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
|
||||
/* errorMessage= */ prefix + "\t\trecents activity screenshot was "
|
||||
+ "cleaned up before/without STATE_SCREENSHOT_CAPTURED "
|
||||
+ "being set.",
|
||||
writer);
|
||||
break;
|
||||
case STATE_GESTURE_COMPLETED:
|
||||
errorDetected |= printErrorIfTrue(
|
||||
!encounteredEvents.contains(GestureEvent.MOTION_UP),
|
||||
@@ -114,12 +135,39 @@ public class ActiveGestureErrorDetector {
|
||||
+ "before/without STATE_GESTURE_STARTED.",
|
||||
writer);
|
||||
break;
|
||||
case STATE_SCREENSHOT_CAPTURED:
|
||||
errorDetected |= printErrorIfTrue(
|
||||
!encounteredEvents.contains(GestureEvent.STATE_CAPTURE_SCREENSHOT),
|
||||
/* errorMessage= */ prefix + "\t\tSTATE_SCREENSHOT_CAPTURED set "
|
||||
+ "before/without STATE_CAPTURE_SCREENSHOT.",
|
||||
writer);
|
||||
break;
|
||||
case STATE_RECENTS_SCROLLING_FINISHED:
|
||||
errorDetected |= printErrorIfTrue(
|
||||
!encounteredEvents.contains(
|
||||
GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK),
|
||||
/* errorMessage= */ prefix + "\t\tSTATE_RECENTS_SCROLLING_FINISHED "
|
||||
+ "set before/without calling "
|
||||
+ "setOnPageTransitionEndCallback.",
|
||||
writer);
|
||||
break;
|
||||
case STATE_RECENTS_ANIMATION_CANCELED:
|
||||
errorDetected |= printErrorIfTrue(
|
||||
!encounteredEvents.contains(
|
||||
GestureEvent.START_RECENTS_ANIMATION),
|
||||
/* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED "
|
||||
+ "set before/without startRecentsAnimation.",
|
||||
writer);
|
||||
break;
|
||||
case MOTION_DOWN:
|
||||
case SET_END_TARGET:
|
||||
case START_RECENTS_ANIMATION:
|
||||
case SET_ON_PAGE_TRANSITION_END_CALLBACK:
|
||||
case CANCEL_CURRENT_ANIMATION:
|
||||
case STATE_GESTURE_STARTED:
|
||||
case STATE_END_TARGET_ANIMATION_FINISHED:
|
||||
case STATE_RECENTS_SCROLLING_FINISHED:
|
||||
case STATE_CAPTURE_SCREENSHOT:
|
||||
case STATE_HANDLER_INVALIDATED:
|
||||
default:
|
||||
// No-Op
|
||||
}
|
||||
@@ -183,6 +231,39 @@ public class ActiveGestureErrorDetector {
|
||||
+ "STATE_GESTURE_COMPLETED and STATE_GESTURE_CANCELLED weren't.",
|
||||
writer);
|
||||
|
||||
errorDetected |= printErrorIfTrue(
|
||||
/* condition= */ encounteredEvents.contains(
|
||||
GestureEvent.STATE_CAPTURE_SCREENSHOT)
|
||||
&& !encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
|
||||
/* errorMessage= */ prefix + "\t\tSTATE_CAPTURE_SCREENSHOT was set, but "
|
||||
+ "STATE_SCREENSHOT_CAPTURED wasn't.",
|
||||
writer);
|
||||
|
||||
errorDetected |= printErrorIfTrue(
|
||||
/* condition= */ encounteredEvents.contains(
|
||||
GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK)
|
||||
&& !encounteredEvents.contains(
|
||||
GestureEvent.STATE_RECENTS_SCROLLING_FINISHED),
|
||||
/* errorMessage= */ prefix + "\t\tsetOnPageTransitionEndCallback called, but "
|
||||
+ "STATE_RECENTS_SCROLLING_FINISHED wasn't set.",
|
||||
writer);
|
||||
|
||||
errorDetected |= printErrorIfTrue(
|
||||
/* condition= */ !encounteredEvents.contains(
|
||||
GestureEvent.CANCEL_CURRENT_ANIMATION)
|
||||
&& !encounteredEvents.contains(GestureEvent.STATE_HANDLER_INVALIDATED),
|
||||
/* errorMessage= */ prefix + "\t\tAbsSwipeUpHandler.cancelCurrentAnimation "
|
||||
+ "wasn't called and STATE_HANDLER_INVALIDATED wasn't set.",
|
||||
writer);
|
||||
|
||||
errorDetected |= printErrorIfTrue(
|
||||
/* condition= */ encounteredEvents.contains(
|
||||
GestureEvent.STATE_RECENTS_ANIMATION_CANCELED)
|
||||
&& !encounteredEvents.contains(GestureEvent.CLEANUP_SCREENSHOT),
|
||||
/* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED was set but "
|
||||
+ "the task screenshot wasn't cleaned up.",
|
||||
writer);
|
||||
|
||||
if (!errorDetected) {
|
||||
writer.println(prefix + "\t\tNo errors detected.");
|
||||
}
|
||||
|
||||
@@ -138,14 +138,10 @@ public class ActiveGestureLog {
|
||||
List<EventEntry> lastEventEntries = lastEventLog.eventEntries;
|
||||
EventEntry lastEntry = lastEventEntries.size() > 0
|
||||
? lastEventEntries.get(lastEventEntries.size() - 1) : null;
|
||||
EventEntry secondLastEntry = lastEventEntries.size() > 1
|
||||
? lastEventEntries.get(lastEventEntries.size() - 2) : null;
|
||||
|
||||
// Update the last EventEntry if it's a duplicate
|
||||
if (isEntrySame(lastEntry, type, event, compoundString, gestureEvent)
|
||||
&& isEntrySame(secondLastEntry, type, event, compoundString, gestureEvent)) {
|
||||
lastEntry.update(type, event, extras, compoundString, gestureEvent);
|
||||
secondLastEntry.duplicateCount++;
|
||||
if (isEntrySame(lastEntry, type, event, extras, compoundString, gestureEvent)) {
|
||||
lastEntry.duplicateCount++;
|
||||
return;
|
||||
}
|
||||
EventEntry eventEntry = new EventEntry();
|
||||
@@ -223,11 +219,13 @@ public class ActiveGestureLog {
|
||||
EventEntry entry,
|
||||
int type,
|
||||
String event,
|
||||
float extras,
|
||||
CompoundString compoundString,
|
||||
ActiveGestureErrorDetector.GestureEvent gestureEvent) {
|
||||
return entry != null
|
||||
&& entry.type == type
|
||||
&& entry.event.equals(event)
|
||||
&& Float.compare(entry.extras, extras) == 0
|
||||
&& entry.mCompoundString.equals(compoundString)
|
||||
&& entry.gestureEvent == gestureEvent;
|
||||
}
|
||||
@@ -342,7 +340,7 @@ public class ActiveGestureLog {
|
||||
return false;
|
||||
}
|
||||
CompoundString other = (CompoundString) obj;
|
||||
return mIsNoOp && other.mIsNoOp && Objects.equals(mSubstrings, other.mSubstrings);
|
||||
return (mIsNoOp == other.mIsNoOp) && Objects.equals(mSubstrings, other.mSubstrings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4317,25 +4317,27 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
int taskIndex = indexOfChild(tv);
|
||||
int centerTaskIndex = getCurrentPage();
|
||||
boolean launchingCenterTask = taskIndex == centerTaskIndex;
|
||||
|
||||
float toScale = getMaxScaleForFullScreen();
|
||||
RecentsView recentsView = tv.getRecentsView();
|
||||
boolean showAsGrid = showAsGrid();
|
||||
boolean launchingCenterTask = showAsGrid
|
||||
? tv.isFocusedTask() && isTaskViewFullyVisible(tv)
|
||||
: taskIndex == centerTaskIndex;
|
||||
if (launchingCenterTask) {
|
||||
anim.play(ObjectAnimator.ofFloat(recentsView, RECENTS_SCALE_PROPERTY, toScale));
|
||||
anim.play(ObjectAnimator.ofFloat(recentsView, FULLSCREEN_PROGRESS, 1));
|
||||
} else {
|
||||
anim.play(ObjectAnimator.ofFloat(this, RECENTS_SCALE_PROPERTY, toScale));
|
||||
anim.play(ObjectAnimator.ofFloat(this, FULLSCREEN_PROGRESS, 1));
|
||||
} else if (!showAsGrid) {
|
||||
// We are launching an adjacent task, so parallax the center and other adjacent task.
|
||||
float displacementX = tv.getWidth() * (toScale - 1f);
|
||||
float primaryTranslation = mIsRtl ? -displacementX : displacementX;
|
||||
anim.play(ObjectAnimator.ofFloat(getPageAt(centerTaskIndex),
|
||||
mOrientationHandler.getPrimaryViewTranslate(), primaryTranslation));
|
||||
int runningTaskIndex = recentsView.getRunningTaskIndex();
|
||||
int runningTaskIndex = getRunningTaskIndex();
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()
|
||||
&& runningTaskIndex != -1
|
||||
&& runningTaskIndex != taskIndex
|
||||
&& recentsView.getRemoteTargetHandles() != null) {
|
||||
for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
|
||||
&& getRemoteTargetHandles() != null) {
|
||||
for (RemoteTargetHandle remoteHandle : getRemoteTargetHandles()) {
|
||||
anim.play(ObjectAnimator.ofFloat(
|
||||
remoteHandle.getTaskViewSimulator().taskPrimaryTranslation,
|
||||
AnimatedFloat.VALUE,
|
||||
@@ -4355,7 +4357,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
properties));
|
||||
}
|
||||
}
|
||||
anim.play(ObjectAnimator.ofFloat(recentsView, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
|
||||
anim.play(ObjectAnimator.ofFloat(this, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
|
||||
return anim;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
<dimen name="drop_target_text_size">16sp</dimen>
|
||||
<dimen name="drop_target_shadow_elevation">2dp</dimen>
|
||||
<dimen name="drop_target_bar_margin_horizontal">4dp</dimen>
|
||||
<dimen name="drop_target_button_drawable_size">20dp</dimen>
|
||||
<dimen name="drop_target_button_drawable_padding">8dp</dimen>
|
||||
<dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
|
||||
<dimen name="drop_target_button_drawable_vertical_padding">8dp</dimen>
|
||||
|
||||
@@ -91,7 +91,7 @@ public abstract class ButtonDropTarget extends TextView
|
||||
|
||||
Resources resources = getResources();
|
||||
mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
|
||||
mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_text_size);
|
||||
mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_button_drawable_size);
|
||||
mDrawablePadding = resources.getDimensionPixelSize(
|
||||
R.dimen.drop_target_button_drawable_padding);
|
||||
}
|
||||
@@ -374,11 +374,63 @@ public abstract class ButtonDropTarget extends TextView
|
||||
hideTooltip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the text will be truncated within the provided availableWidth.
|
||||
*/
|
||||
public boolean isTextTruncated(int availableWidth) {
|
||||
availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth()
|
||||
+ getCompoundDrawablePadding());
|
||||
CharSequence displayedText = TextUtils.ellipsize(mText, getPaint(), availableWidth,
|
||||
availableWidth -= getPaddingLeft() + getPaddingRight();
|
||||
if (mIconVisible) {
|
||||
availableWidth -= mDrawable.getIntrinsicWidth() + getCompoundDrawablePadding();
|
||||
}
|
||||
if (availableWidth <= 0) {
|
||||
return true;
|
||||
}
|
||||
CharSequence firstLine = TextUtils.ellipsize(mText, getPaint(), availableWidth,
|
||||
TextUtils.TruncateAt.END);
|
||||
return !mText.equals(displayedText);
|
||||
if (!mTextMultiLine) {
|
||||
return !TextUtils.equals(mText, firstLine);
|
||||
}
|
||||
if (TextUtils.equals(mText, firstLine)) {
|
||||
// When multi-line is active, if it can display as one line, then text is not truncated.
|
||||
return false;
|
||||
}
|
||||
CharSequence secondLine =
|
||||
TextUtils.ellipsize(mText.subSequence(firstLine.length(), mText.length()),
|
||||
getPaint(), availableWidth, TextUtils.TruncateAt.END);
|
||||
return !(TextUtils.equals(mText.subSequence(0, firstLine.length()), firstLine)
|
||||
&& TextUtils.equals(mText.subSequence(firstLine.length(), secondLine.length()),
|
||||
secondLine));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the size of the text until it fits the measured width or reaches a minimum.
|
||||
*
|
||||
* The minimum size is defined by {@code R.dimen.button_drop_target_min_text_size} and
|
||||
* it diminishes by intervals defined by
|
||||
* {@code R.dimen.button_drop_target_resize_text_increment}
|
||||
* This functionality is very similar to the option
|
||||
* {@link TextView#setAutoSizeTextTypeWithDefaults(int)} but can't be used in this view because
|
||||
* the layout width is {@code WRAP_CONTENT}.
|
||||
*
|
||||
* @return The biggest text size in SP that makes the text fit or if the text can't fit returns
|
||||
* the min available value
|
||||
*/
|
||||
public float resizeTextToFit() {
|
||||
float minSize = Utilities.pxToSp(getResources()
|
||||
.getDimensionPixelSize(R.dimen.button_drop_target_min_text_size));
|
||||
float step = Utilities.pxToSp(getResources()
|
||||
.getDimensionPixelSize(R.dimen.button_drop_target_resize_text_increment));
|
||||
float textSize = Utilities.pxToSp(getTextSize());
|
||||
|
||||
int availableWidth = getMeasuredWidth();
|
||||
while (textSize > minSize) {
|
||||
if (isTextTruncated(availableWidth)) {
|
||||
textSize -= step;
|
||||
setTextSize(textSize);
|
||||
} else {
|
||||
return textSize;
|
||||
}
|
||||
}
|
||||
return minSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1037,7 +1037,7 @@ public class DeviceProfile {
|
||||
/ getCellLayoutHeight();
|
||||
scale = Math.min(scale, 1f);
|
||||
|
||||
// Reduce scale if next pages would not be visible after scaling the workspace
|
||||
// Reduce scale if next pages would not be visible after scaling the workspace.
|
||||
int workspaceWidth = availableWidthPx;
|
||||
float scaledWorkspaceWidth = workspaceWidth * scale;
|
||||
float maxAvailableWidth = workspaceWidth - (2 * workspaceSpringLoadedMinNextPageVisiblePx);
|
||||
|
||||
@@ -151,6 +151,8 @@ public class DropTargetBar extends FrameLayout
|
||||
int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
|
||||
|
||||
ButtonDropTarget firstButton = mTempTargets[0];
|
||||
firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX,
|
||||
mLauncher.getDeviceProfile().dropTargetTextSizePx);
|
||||
firstButton.setTextVisible(true);
|
||||
firstButton.setIconVisible(true);
|
||||
firstButton.measure(widthSpec, heightSpec);
|
||||
@@ -160,14 +162,16 @@ public class DropTargetBar extends FrameLayout
|
||||
int horizontalPadding = dp.dropTargetHorizontalPaddingPx;
|
||||
|
||||
ButtonDropTarget firstButton = mTempTargets[0];
|
||||
firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
|
||||
firstButton.setTextVisible(true);
|
||||
firstButton.setIconVisible(true);
|
||||
firstButton.setTextMultiLine(false);
|
||||
// Reset second button padding in case it was previously changed to multi-line text.
|
||||
// Reset first button padding in case it was previously changed to multi-line text.
|
||||
firstButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
|
||||
verticalPadding);
|
||||
|
||||
ButtonDropTarget secondButton = mTempTargets[1];
|
||||
secondButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
|
||||
secondButton.setTextVisible(true);
|
||||
secondButton.setIconVisible(true);
|
||||
secondButton.setTextMultiLine(false);
|
||||
@@ -175,20 +179,14 @@ public class DropTargetBar extends FrameLayout
|
||||
secondButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
|
||||
verticalPadding);
|
||||
|
||||
float scale = dp.getWorkspaceSpringLoadScale(mLauncher);
|
||||
int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale);
|
||||
|
||||
int availableWidth;
|
||||
if (dp.isTwoPanels) {
|
||||
// Both buttons for two panel fit to the width of one Cell Layout (less
|
||||
// half of the center gap between the buttons).
|
||||
int halfButtonGap = dp.dropTargetGapPx / 2;
|
||||
availableWidth = scaledPanelWidth - halfButtonGap / 2;
|
||||
// Each button for two panel fits to half the width of the screen excluding the
|
||||
// center gap between the buttons.
|
||||
availableWidth = (dp.availableWidthPx - dp.dropTargetGapPx) / 2;
|
||||
} else {
|
||||
// Both buttons plus the button gap do not display past the edge of the scaled
|
||||
// workspace, less a pre-defined gap from the edge of the workspace.
|
||||
availableWidth = scaledPanelWidth - dp.dropTargetGapPx
|
||||
- 2 * dp.dropTargetButtonWorkspaceEdgeGapPx;
|
||||
// Both buttons plus the button gap do not display past the edge of the screen.
|
||||
availableWidth = dp.availableWidthPx - dp.dropTargetGapPx;
|
||||
}
|
||||
|
||||
int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
|
||||
@@ -219,6 +217,15 @@ public class DropTargetBar extends FrameLayout
|
||||
horizontalPadding, verticalPadding / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// If text is still truncated, shrink to fit in measured width and resize both targets.
|
||||
float minTextSize =
|
||||
Math.min(firstButton.resizeTextToFit(), secondButton.resizeTextToFit());
|
||||
if (firstButton.getTextSize() != minTextSize
|
||||
|| secondButton.getTextSize() != minTextSize) {
|
||||
firstButton.setTextSize(minTextSize);
|
||||
secondButton.setTextSize(minTextSize);
|
||||
}
|
||||
}
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
@@ -73,11 +73,11 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mModel = LauncherAppState.getInstance(this).getModel();
|
||||
mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
|
||||
mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
|
||||
if (getWindow().getDecorView().isAttachedToWindow()) {
|
||||
initUi();
|
||||
}
|
||||
mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
|
||||
mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -141,6 +141,7 @@ public interface ActivityContext {
|
||||
default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { }
|
||||
|
||||
/** Onboarding preferences for any onboarding data within this context. */
|
||||
@Nullable
|
||||
default OnboardingPrefs<?> getOnboardingPrefs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user