Snap for 8492635 from 357c622572 to tm-release
Change-Id: I97b60a177d98122fc9784f9ca7f89c6270829f74
This commit is contained in:
@@ -42,7 +42,6 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_BACK_SWIPE_HOME_A
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAUNCH;
|
||||
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
|
||||
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
|
||||
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
|
||||
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
|
||||
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
|
||||
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
|
||||
@@ -105,7 +104,6 @@ import com.android.launcher3.taskbar.LauncherTaskbarUIController;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.util.ActivityOptionsWrapper;
|
||||
import com.android.launcher3.util.DynamicResource;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.launcher3.util.ObjectWrapper;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.util.Themes;
|
||||
@@ -195,9 +193,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
private static final int WIDGET_CROSSFADE_DURATION_MILLIS = 125;
|
||||
|
||||
protected final BaseQuickstepLauncher mLauncher;
|
||||
|
||||
private final DragLayer mDragLayer;
|
||||
private final AlphaProperty mDragLayerAlpha;
|
||||
|
||||
final Handler mHandler;
|
||||
|
||||
@@ -241,7 +237,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
public QuickstepTransitionManager(Context context) {
|
||||
mLauncher = Launcher.cast(Launcher.getLauncher(context));
|
||||
mDragLayer = mLauncher.getDragLayer();
|
||||
mDragLayerAlpha = mDragLayer.getAlphaProperty(ALPHA_INDEX_TRANSITIONS);
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mDeviceProfile = mLauncher.getDeviceProfile();
|
||||
mBackAnimationController = new LauncherBackAnimationController(mLauncher, this);
|
||||
|
||||
@@ -176,7 +176,8 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT
|
||||
return revealAnim;
|
||||
}
|
||||
|
||||
public void onIsStashed(boolean isStashed) {
|
||||
/** Called when taskbar is stashed or unstashed. */
|
||||
public void onIsStashedChanged(boolean isStashed) {
|
||||
mRegionSamplingHelper.setWindowVisible(isStashed);
|
||||
if (isStashed) {
|
||||
mStashedHandleView.updateSampledRegion(mStashedHandleBounds);
|
||||
|
||||
@@ -559,7 +559,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
}
|
||||
}
|
||||
mWindowLayoutParams.height = height;
|
||||
mControllers.taskbarInsetsController.onTaskbarWindowHeightChanged();
|
||||
mControllers.taskbarInsetsController.onTaskbarWindowHeightOrInsetsChanged();
|
||||
mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ public class TaskbarControllers {
|
||||
taskbarForceVisibleImmersiveController.onDestroy();
|
||||
taskbarAllAppsController.onDestroy();
|
||||
navButtonController.onDestroy();
|
||||
taskbarInsetsController.onDestroy();
|
||||
|
||||
mControllersToLog = null;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
|
||||
private void onComputeTaskbarInsets(InsetsInfo insetsInfo) {
|
||||
if (mControllerCallbacks != null) {
|
||||
mControllerCallbacks.updateInsetsTouchability(insetsInfo);
|
||||
mControllerCallbacks.updateContentInsets(insetsInfo.contentInsets);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,16 +163,6 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
mControllers.taskbarInsetsController.updateInsetsTouchability(insetsInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the {@link InsetsInfo#contentInsets}. This is reported to apps but our
|
||||
* internal launcher will ignore these insets.
|
||||
*/
|
||||
public void updateContentInsets(Rect outContentInsets) {
|
||||
int contentHeight = mControllers.taskbarStashController
|
||||
.getContentHeightToReportToApps();
|
||||
outContentInsets.top = mTaskbarDragLayer.getHeight() - contentHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a child is removed from TaskbarDragLayer.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.launcher3.taskbar
|
||||
import android.graphics.Insets
|
||||
import android.view.WindowManager
|
||||
import com.android.launcher3.AbstractFloatingView
|
||||
import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.anim.AlphaUpdateListener
|
||||
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
|
||||
@@ -53,19 +54,39 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask
|
||||
)
|
||||
)
|
||||
|
||||
windowLayoutParams.providedInternalInsets = arrayOfNulls<Insets>(ITYPE_SIZE)
|
||||
windowLayoutParams.providedInternalImeInsets = arrayOfNulls<Insets>(ITYPE_SIZE)
|
||||
|
||||
onTaskbarWindowHeightChanged()
|
||||
onTaskbarWindowHeightOrInsetsChanged()
|
||||
|
||||
windowLayoutParams.insetsRoundedCornerFrame = true
|
||||
}
|
||||
|
||||
fun onTaskbarWindowHeightChanged() {
|
||||
val reducingSize = Insets.of(0, windowLayoutParams.height - taskbarHeightForIme, 0, 0)
|
||||
fun onDestroy() {}
|
||||
|
||||
fun onTaskbarWindowHeightOrInsetsChanged() {
|
||||
var reducingSize = getReducingInsetsForTaskbarInsetsHeight(
|
||||
controllers.taskbarStashController.contentHeightToReportToApps)
|
||||
windowLayoutParams.providedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
|
||||
reducingSize = getReducingInsetsForTaskbarInsetsHeight(
|
||||
controllers.taskbarStashController.tappableHeightToReportToApps)
|
||||
windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
|
||||
|
||||
reducingSize = getReducingInsetsForTaskbarInsetsHeight(taskbarHeightForIme)
|
||||
windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
|
||||
windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
|
||||
}
|
||||
|
||||
/**
|
||||
* WindowLayoutParams.providedInternal*Insets expects Insets that subtract from the window frame
|
||||
* height (i.e. WindowLayoutParams#height). So for Taskbar to report bottom insets to apps, it
|
||||
* actually provides insets from the top of its window frame.
|
||||
* @param height The number of pixels from the bottom of the screen that Taskbar insets.
|
||||
*/
|
||||
private fun getReducingInsetsForTaskbarInsetsHeight(height: Int): Insets {
|
||||
return Insets.of(0, windowLayoutParams.height - height, 0, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the touchable insets.
|
||||
* @see InsetsInfo.setTouchableInsets
|
||||
@@ -88,18 +109,11 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask
|
||||
} else if (controllers.taskbarDragController.isSystemDragInProgress) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
} else if (AbstractFloatingView.getOpenView<AbstractFloatingView?>(
|
||||
context,
|
||||
AbstractFloatingView.TYPE_TASKBAR_ALL_APPS
|
||||
) != null
|
||||
) {
|
||||
} else if (AbstractFloatingView.hasOpenView(context, TYPE_TASKBAR_ALL_APPS)) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
} else if (controllers.taskbarViewController.areIconsVisible()
|
||||
|| AbstractFloatingView.getOpenView<AbstractFloatingView?>(
|
||||
context,
|
||||
AbstractFloatingView.TYPE_ALL
|
||||
) != null
|
||||
|| AbstractFloatingView.hasOpenView(context, AbstractFloatingView.TYPE_ALL)
|
||||
|| context.isNavBarKidsModeActive
|
||||
) {
|
||||
// Taskbar has some touchable elements, take over the full taskbar area
|
||||
@@ -120,6 +134,10 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask
|
||||
override fun dumpLogs(prefix: String, pw: PrintWriter) {
|
||||
pw.println(prefix + "TaskbarInsetsController:")
|
||||
pw.println("$prefix\twindowHeight=${windowLayoutParams.height}")
|
||||
pw.println("$prefix\tprovidedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" +
|
||||
"${windowLayoutParams.providedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR]}")
|
||||
pw.println("$prefix\tprovidedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" +
|
||||
"${windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]}")
|
||||
pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" +
|
||||
"${windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]}")
|
||||
pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" +
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.annotation.Nullable;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -280,6 +281,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
|
||||
/**
|
||||
* Returns the height that taskbar will inset when inside apps.
|
||||
* @see WindowInsets.Type#navigationBars()
|
||||
* @see WindowInsets.Type#systemBars()
|
||||
*/
|
||||
public int getContentHeightToReportToApps() {
|
||||
if (supportsVisualStashing() && hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
|
||||
@@ -304,6 +307,15 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
return mUnstashedHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height that taskbar will inset when inside apps.
|
||||
* @see WindowInsets.Type#tappableElement()
|
||||
*/
|
||||
public int getTappableHeightToReportToApps() {
|
||||
int contentHeight = getContentHeightToReportToApps();
|
||||
return contentHeight <= mStashedHeight ? 0 : contentHeight;
|
||||
}
|
||||
|
||||
public int getStashedHeight() {
|
||||
return mStashedHeight;
|
||||
}
|
||||
@@ -442,7 +454,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mIsStashed = isStashed;
|
||||
onIsStashed(mIsStashed);
|
||||
onIsStashedChanged(mIsStashed);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -489,8 +501,9 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
.setDuration(TASKBAR_HINT_STASH_DURATION).start();
|
||||
}
|
||||
|
||||
private void onIsStashed(boolean isStashed) {
|
||||
mControllers.stashedHandleViewController.onIsStashed(isStashed);
|
||||
private void onIsStashedChanged(boolean isStashed) {
|
||||
mControllers.stashedHandleViewController.onIsStashedChanged(isStashed);
|
||||
mControllers.taskbarInsetsController.onTaskbarWindowHeightOrInsetsChanged();
|
||||
}
|
||||
|
||||
public void applyState() {
|
||||
|
||||
@@ -107,7 +107,6 @@ public final class RecentsViewStateController extends
|
||||
*/
|
||||
private void handleSplitSelectionState(@NonNull LauncherState toState,
|
||||
@Nullable PendingAnimation builder) {
|
||||
LauncherState currentState = mLauncher.getStateManager().getState();
|
||||
boolean animate = builder != null;
|
||||
PagedOrientationHandler orientationHandler =
|
||||
((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler();
|
||||
@@ -116,7 +115,7 @@ public final class RecentsViewStateController extends
|
||||
TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
|
||||
mLauncher.getDeviceProfile());
|
||||
|
||||
if (isSplitSelectionState(currentState, toState)) {
|
||||
if (toState == OVERVIEW_SPLIT_SELECT) {
|
||||
// Animation to "dismiss" selected taskView
|
||||
PendingAnimation splitSelectInitAnimation = mRecentsView.createSplitSelectInitAnimation(
|
||||
toState.getTransitionDuration(mLauncher));
|
||||
@@ -125,30 +124,18 @@ public final class RecentsViewStateController extends
|
||||
toState.getSplitSelectTranslation(mLauncher), LINEAR);
|
||||
splitSelectInitAnimation.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR);
|
||||
|
||||
if (!animate && isSplitSelectionState(currentState, toState)) {
|
||||
if (!animate) {
|
||||
splitSelectInitAnimation.buildAnim().start();
|
||||
} else if (animate &&
|
||||
isSplitSelectionState(currentState, toState)) {
|
||||
} else {
|
||||
builder.add(splitSelectInitAnimation.buildAnim());
|
||||
}
|
||||
}
|
||||
|
||||
if (isSplitSelectionState(currentState, toState)) {
|
||||
mRecentsView.applySplitPrimaryScrollOffset();
|
||||
} else {
|
||||
mRecentsView.resetSplitPrimaryScrollOffset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if {@param toState} is {@link LauncherState#OVERVIEW_SPLIT_SELECT}
|
||||
* and {@param fromState} is not {@link LauncherState#OVERVIEW_SPLIT_SELECT}
|
||||
*/
|
||||
private boolean isSplitSelectionState(@NonNull LauncherState fromState,
|
||||
@NonNull LauncherState toState) {
|
||||
return fromState != OVERVIEW_SPLIT_SELECT && toState == OVERVIEW_SPLIT_SELECT;
|
||||
}
|
||||
|
||||
private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config,
|
||||
LauncherState state) {
|
||||
float clearAllButtonAlpha = state.areElementsVisible(mLauncher, CLEAR_ALL_BUTTON) ? 1 : 0;
|
||||
|
||||
+6
-13
@@ -21,7 +21,8 @@ import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRES
|
||||
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_PROGRESS;
|
||||
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_ALPHA;
|
||||
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_TRANSLATION;
|
||||
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU;
|
||||
@@ -40,11 +41,9 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
@@ -148,16 +147,10 @@ public class NavBarToHomeTouchController implements TouchController,
|
||||
AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_TASK_MENU);
|
||||
} else if (mStartState == ALL_APPS) {
|
||||
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
|
||||
builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_PROGRESS,
|
||||
-mPullbackDistance / allAppsController.getShiftRange(), PULLBACK_INTERPOLATOR);
|
||||
|
||||
// Slightly fade out all apps content to further distinguish from scrolling.
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.duration = accuracy;
|
||||
config.setInterpolator(StateAnimationConfig.ANIM_ALL_APPS_FADE, Interpolators
|
||||
.mapToProgress(PULLBACK_INTERPOLATOR, 0, 0.5f));
|
||||
|
||||
allAppsController.setAlphas(mEndState, config, builder);
|
||||
builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_TRANSLATION,
|
||||
-mPullbackDistance, PULLBACK_INTERPOLATOR);
|
||||
builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_ALPHA,
|
||||
0.5f, PULLBACK_INTERPOLATOR);
|
||||
}
|
||||
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher);
|
||||
if (topView != null) {
|
||||
|
||||
@@ -1013,19 +1013,19 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
return RECENTS;
|
||||
}
|
||||
final GestureEndTarget endTarget;
|
||||
final boolean goingToNewTask;
|
||||
final boolean canGoToNewTask;
|
||||
if (mRecentsView != null) {
|
||||
if (!hasTargets()) {
|
||||
// If there are no running tasks, then we can assume that this is a continuation of
|
||||
// the last gesture, but after the recents animation has finished
|
||||
goingToNewTask = true;
|
||||
canGoToNewTask = true;
|
||||
} else {
|
||||
final int runningTaskIndex = mRecentsView.getRunningTaskIndex();
|
||||
final int taskToLaunch = mRecentsView.getNextPage();
|
||||
goingToNewTask = runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex;
|
||||
canGoToNewTask = runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex;
|
||||
}
|
||||
} else {
|
||||
goingToNewTask = false;
|
||||
canGoToNewTask = false;
|
||||
}
|
||||
final boolean reachedOverviewThreshold = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
|
||||
final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
|
||||
@@ -1034,13 +1034,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
if (isCancel) {
|
||||
endTarget = LAST_TASK;
|
||||
} else if (mDeviceState.isFullyGesturalNavMode()) {
|
||||
if (goingToNewTask && isFlingX) {
|
||||
if (canGoToNewTask && isFlingX) {
|
||||
// Flinging towards new task takes precedence over mIsMotionPaused (which only
|
||||
// checks y-velocity).
|
||||
endTarget = NEW_TASK;
|
||||
} else if (mIsMotionPaused) {
|
||||
endTarget = RECENTS;
|
||||
} else if (goingToNewTask) {
|
||||
} else if (canGoToNewTask) {
|
||||
endTarget = NEW_TASK;
|
||||
} else {
|
||||
endTarget = !reachedOverviewThreshold ? LAST_TASK : HOME;
|
||||
@@ -1048,26 +1048,22 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
} else {
|
||||
endTarget = reachedOverviewThreshold && mGestureStarted
|
||||
? RECENTS
|
||||
: goingToNewTask
|
||||
: canGoToNewTask
|
||||
? NEW_TASK
|
||||
: LAST_TASK;
|
||||
}
|
||||
} else {
|
||||
// If swiping at a diagonal, base end target on the faster velocity.
|
||||
boolean isSwipeUp = endVelocity < 0;
|
||||
boolean willGoToNewTaskOnSwipeUp =
|
||||
goingToNewTask && Math.abs(velocity.x) > Math.abs(endVelocity);
|
||||
boolean willGoToNewTask =
|
||||
canGoToNewTask && Math.abs(velocity.x) > Math.abs(endVelocity);
|
||||
|
||||
if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp && !willGoToNewTaskOnSwipeUp) {
|
||||
endTarget = HOME;
|
||||
} else if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp) {
|
||||
// If swiping at a diagonal, base end target on the faster velocity.
|
||||
endTarget = NEW_TASK;
|
||||
if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp) {
|
||||
endTarget = willGoToNewTask ? NEW_TASK : HOME;
|
||||
} else if (isSwipeUp) {
|
||||
endTarget = !reachedOverviewThreshold && willGoToNewTaskOnSwipeUp
|
||||
? NEW_TASK : RECENTS;
|
||||
endTarget = (!reachedOverviewThreshold && willGoToNewTask) ? NEW_TASK : RECENTS;
|
||||
} else {
|
||||
endTarget = goingToNewTask ? NEW_TASK : LAST_TASK;
|
||||
endTarget = willGoToNewTask ? NEW_TASK : LAST_TASK; // Swipe is downward.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1145,6 +1141,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
duration = Math.max(duration, mRecentsView.getScroller().getDuration());
|
||||
}
|
||||
}
|
||||
} else if (endTarget == LAST_TASK && mRecentsView != null) {
|
||||
mRecentsView.snapToPage(mRecentsView.getCurrentPage(), Math.toIntExact(duration));
|
||||
}
|
||||
|
||||
// Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
|
||||
|
||||
@@ -1396,6 +1396,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (taskGroups == null || taskGroups.isEmpty()) {
|
||||
removeTasksViewsAndClearAllButton();
|
||||
onTaskStackUpdated();
|
||||
// With all tasks removed, touch handling in PagedView is disabled and we need to reset
|
||||
// touch state or otherwise values will be obsolete.
|
||||
resetTouchState();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,13 @@
|
||||
android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/>
|
||||
|
||||
<TextView
|
||||
style="@style/PrimaryHeadline"
|
||||
android:id="@+id/no_widgets_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:textSize="20sp"
|
||||
android:textSize="18sp"
|
||||
android:layout_below="@id/search_and_recommendations_container"
|
||||
tools:text="No widgets available" />
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<string name="split_screen_position_left" msgid="7537793098851830883">"تقسيم لليسار"</string>
|
||||
<string name="split_screen_position_right" msgid="1569377524925193369">"تقسيم لليمين"</string>
|
||||
<string name="split_app_info_accessibility" msgid="5475288491241414932">"معلومات تطبيق %1$s"</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"انقر مع الاستمرار لنقل أداة"</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"انقر مع الاستمرار لنقل أداة."</string>
|
||||
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"انقر مرتين مع تثبيت إصبعك لنقل أداة أو استخدام الإجراءات المخصّصة."</string>
|
||||
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
|
||||
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"العرض %1$d الطول %2$d"</string>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pretražite"</string>
|
||||
<string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Obrišite tekst iz okvira za pretragu"</string>
|
||||
<string name="no_widgets_available" msgid="4337693382501046170">"Vidžeti i prečice nisu dostupni"</string>
|
||||
<string name="no_search_results" msgid="3787956167293097509">"Nije pronađen nijedan vidžet ili prečica"</string>
|
||||
<string name="no_search_results" msgid="3787956167293097509">"Nije pronađen nijedan vidžet ni prečica"</string>
|
||||
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Lično"</string>
|
||||
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
|
||||
<string name="widget_category_conversations" msgid="8894438636213590446">"Konverzacije"</string>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<string name="split_screen_position_left" msgid="7537793098851830883">"Rozdělit vlevo"</string>
|
||||
<string name="split_screen_position_right" msgid="1569377524925193369">"Rozdělit vpravo"</string>
|
||||
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informace o aplikaci %1$s"</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Klepnutím a podržením přesunete widget."</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget přesunete klepnutím a podržením."</string>
|
||||
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a podržením přesunete widget, případně použijte vlastní akce."</string>
|
||||
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
|
||||
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string>
|
||||
@@ -164,7 +164,7 @@
|
||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobní"</string>
|
||||
<string name="all_apps_work_tab" msgid="4884822796154055118">"Pracovní"</string>
|
||||
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Pracovní profil"</string>
|
||||
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Pracovní aplikace jsou označené a viditelné vašemu administrátorovi IT"</string>
|
||||
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Pracovní aplikace jsou označené a váš administrátor IT je vidí"</string>
|
||||
<string name="work_profile_edu_accept" msgid="6069788082535149071">"Rozumím"</string>
|
||||
<string name="work_apps_paused_title" msgid="3040901117349444598">"Pracovní aplikace jsou pozastaveny"</string>
|
||||
<string name="work_apps_paused_body" msgid="261634750995824906">"Pracovní aplikace vám nemohou zasílat oznámení, používat vaši baterii ani získat přístup k vaší poloze"</string>
|
||||
|
||||
@@ -124,14 +124,10 @@
|
||||
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
|
||||
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
|
||||
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
|
||||
<!-- no translation found for dialog_update_title (114234265740994042) -->
|
||||
<skip />
|
||||
<!-- no translation found for dialog_update_message (4176784553982226114) -->
|
||||
<skip />
|
||||
<!-- no translation found for dialog_update (2178028071796141234) -->
|
||||
<skip />
|
||||
<!-- no translation found for dialog_remove (6510806469849709407) -->
|
||||
<skip />
|
||||
<string name="dialog_update_title" msgid="114234265740994042">"App update required"</string>
|
||||
<string name="dialog_update_message" msgid="4176784553982226114">"The app for this icon isn\'t updated. You can update manually to re-enable this shortcut, or remove the icon."</string>
|
||||
<string name="dialog_update" msgid="2178028071796141234">"Update"</string>
|
||||
<string name="dialog_remove" msgid="6510806469849709407">"Remove"</string>
|
||||
<string name="widgets_list" msgid="796804551140113767">"Widgets list"</string>
|
||||
<string name="widgets_list_closed" msgid="6141506579418771922">"Widgets list closed"</string>
|
||||
<string name="action_add_to_workspace" msgid="215894119683164916">"Add to home screen"</string>
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<string name="work_folder_name" msgid="3753320833950115786">"Trabajo"</string>
|
||||
<string name="activity_not_found" msgid="8071924732094499514">"La aplicación no está instalada."</string>
|
||||
<string name="activity_not_available" msgid="7456344436509528827">"La aplicación no está disponible"</string>
|
||||
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo seguro"</string>
|
||||
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo seguro"</string>
|
||||
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo Seguro"</string>
|
||||
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo Seguro"</string>
|
||||
<string name="shortcut_not_available" msgid="2536503539825726397">"Acceso directo no disponible"</string>
|
||||
<string name="home_screen" msgid="5629429142036709174">"Inicio"</string>
|
||||
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
|
||||
@@ -32,7 +32,7 @@
|
||||
<string name="split_screen_position_left" msgid="7537793098851830883">"Dividir parte izquierda"</string>
|
||||
<string name="split_screen_position_right" msgid="1569377524925193369">"Dividir parte derecha"</string>
|
||||
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Información de la aplicación %1$s"</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén pulsado un widget para moverlo."</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén pulsado un widget para moverlo"</string>
|
||||
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dos veces y mantén pulsado un widget para moverlo o usar acciones personalizadas."</string>
|
||||
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
|
||||
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
|
||||
@@ -41,7 +41,7 @@
|
||||
<string name="add_to_home_screen" msgid="9168649446635919791">"Añadir a pantalla de inicio"</string>
|
||||
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> añadido a la pantalla de inicio"</string>
|
||||
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
|
||||
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# combinación de teclas}other{# combinaciones de teclas}}"</string>
|
||||
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# acceso directo}other{# accesos directos}}"</string>
|
||||
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
|
||||
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
|
||||
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Buscar"</string>
|
||||
|
||||
@@ -164,12 +164,12 @@
|
||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"મનગમતી ઍપ"</string>
|
||||
<string name="all_apps_work_tab" msgid="4884822796154055118">"ઑફિસની ઍપ"</string>
|
||||
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ઑફિસની પ્રોફાઇલ"</string>
|
||||
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ઑફિસની ઍપને બૅજ આપેલા હોય છે અને તમારા IT વ્યવસ્થાપક તેમને જોઈ શકે છે"</string>
|
||||
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ઑફિસની ઍપને બૅજ આપેલા હોય છે અને તમારા IT ઍડમિન તેમને જોઈ શકે છે"</string>
|
||||
<string name="work_profile_edu_accept" msgid="6069788082535149071">"સમજાઈ ગયું"</string>
|
||||
<string name="work_apps_paused_title" msgid="3040901117349444598">"ઑફિસ માટેની ઍપ થોભાવવામાં આવેલ છે"</string>
|
||||
<string name="work_apps_paused_title" msgid="3040901117349444598">"ઑફિસ માટેની ઍપ થોભાવવામાં આવી છે"</string>
|
||||
<string name="work_apps_paused_body" msgid="261634750995824906">"ઑફિસ માટેની તમારી ઍપ તમને નોટિફિકેશન મોકલી શકતી નથી, તમારી બૅટરી વાપરી શકતી નથી કે તમારું સ્થાન ઍક્સેસ કરી શકતી નથી"</string>
|
||||
<string name="work_apps_paused_content_description" msgid="5149623040804051095">"ઑફિસ માટેની ઍપ બંધ છે. ઑફિસ માટેની તમારી ઍપ તમને નોટિફિકેશન મોકલી શકતી નથી, તમારી બૅટરી વાપરી શકતી નથી કે તમારું સ્થાન ઍક્સેસ કરી શકતી નથી"</string>
|
||||
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ઑફિસની ઍપને બૅજ આપેલા હોય છે અને તમારા IT વ્યવસ્થાપક તેમને જોઈ શકે છે"</string>
|
||||
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ઑફિસની ઍપને બૅજ આપેલા હોય છે અને તમારા IT ઍડમિન તેમને જોઈ શકે છે"</string>
|
||||
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"સમજાઈ ગયું"</string>
|
||||
<string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ઑફિસ માટેની ઍપ બંધ કરો"</string>
|
||||
<string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ઑફિસ માટેની ઍપ ચાલુ કરો"</string>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<string name="split_screen_position_left" msgid="7537793098851830883">"פיצול שמאלה"</string>
|
||||
<string name="split_screen_position_right" msgid="1569377524925193369">"פיצול ימינה"</string>
|
||||
<string name="split_app_info_accessibility" msgid="5475288491241414932">"פרטים על האפליקציה %1$s"</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"כדי להעביר ווידג\'ט למקום אחר יש לגעת ולא להרפות."</string>
|
||||
<string name="long_press_widget_to_add" msgid="3587712543577675817">"להעברת ווידג\'ט למקום אחר לוחצים עליו לחיצה ארוכה."</string>
|
||||
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"כדי להעביר ווידג\'ט למקום אחר או להשתמש בפעולות מותאמות אישית, יש ללחוץ פעמיים ולא להרפות."</string>
|
||||
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
|
||||
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"רוחב %1$d על גובה %2$d"</string>
|
||||
@@ -161,7 +161,7 @@
|
||||
<string name="action_dismiss_notification" msgid="5909461085055959187">"סגירה"</string>
|
||||
<string name="accessibility_close" msgid="2277148124685870734">"סגירה"</string>
|
||||
<string name="notification_dismissed" msgid="6002233469409822874">"ההתראה נסגרה"</string>
|
||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"אישיות"</string>
|
||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"אישי"</string>
|
||||
<string name="all_apps_work_tab" msgid="4884822796154055118">"עבודה"</string>
|
||||
<string name="work_profile_toggle_label" msgid="3081029915775481146">"פרופיל עבודה"</string>
|
||||
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"האפליקציות לעבודה מתויגות ומוצגות למנהל ה-IT"</string>
|
||||
@@ -171,7 +171,7 @@
|
||||
<string name="work_apps_paused_content_description" msgid="5149623040804051095">"האפליקציות לעבודה מושבתות. האפליקציות לא יכולות לשלוח לך התראות, להשתמש בסוללה או לגשת למיקום שלך"</string>
|
||||
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"האפליקציות לעבודה מתויגות ומוצגות למנהל ה-IT"</string>
|
||||
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"הבנתי"</string>
|
||||
<string name="work_apps_pause_btn_text" msgid="1921059713673767460">"כיבוי של אפליקציות לעבודה"</string>
|
||||
<string name="work_apps_pause_btn_text" msgid="1921059713673767460">"השבתה של אפליקציות לעבודה"</string>
|
||||
<string name="work_apps_enable_btn_text" msgid="1156432622148413741">"הפעלה של אפליקציות לעבודה"</string>
|
||||
<string name="developer_options_filter_hint" msgid="5896817443635989056">"סינון"</string>
|
||||
<string name="remote_action_failed" msgid="1383965239183576790">"הפעולה נכשלה: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personlig"</string>
|
||||
<string name="all_apps_work_tab" msgid="4884822796154055118">"Jobb"</string>
|
||||
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Jobbprofil"</string>
|
||||
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Jobbapper er merket og synlige for IT-administratoren din"</string>
|
||||
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Jobbapper er merket og synlige for IT-administratoren"</string>
|
||||
<string name="work_profile_edu_accept" msgid="6069788082535149071">"Greit"</string>
|
||||
<string name="work_apps_paused_title" msgid="3040901117349444598">"Jobbapper er satt på pause"</string>
|
||||
<string name="work_apps_paused_body" msgid="261634750995824906">"Jobbapper kan ikke sende deg varsler, bruke batteriet eller få tilgang til posisjonen din"</string>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Претражите"</string>
|
||||
<string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Обришите текст из оквира за претрагу"</string>
|
||||
<string name="no_widgets_available" msgid="4337693382501046170">"Виџети и пречице нису доступни"</string>
|
||||
<string name="no_search_results" msgid="3787956167293097509">"Није пронађен ниједан виџет или пречица"</string>
|
||||
<string name="no_search_results" msgid="3787956167293097509">"Није пронађен ниједан виџет ни пречица"</string>
|
||||
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Лично"</string>
|
||||
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Посао"</string>
|
||||
<string name="widget_category_conversations" msgid="8894438636213590446">"Конверзације"</string>
|
||||
|
||||
@@ -207,6 +207,13 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch
|
||||
return getView(activity, type, true /* mustBeOpen */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is at least one view of the given type where {@link #isOpen()} == true.
|
||||
*/
|
||||
public static boolean hasOpenView(ActivityContext activity, @FloatingViewType int type) {
|
||||
return getOpenView(activity, type) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view matching FloatingViewType, and {@link #isOpen()} may be false (if animating
|
||||
* closed).
|
||||
|
||||
@@ -42,7 +42,6 @@ import static com.android.launcher3.LauncherState.NO_SCALE;
|
||||
import static com.android.launcher3.LauncherState.SPRING_LOADED;
|
||||
import static com.android.launcher3.Utilities.postAsyncCallback;
|
||||
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
|
||||
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
|
||||
import static com.android.launcher3.logging.StatsLogManager.EventEnum;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
@@ -65,7 +64,6 @@ import static com.android.launcher3.util.ItemInfoMatcher.forFolderMatch;
|
||||
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.Notification;
|
||||
@@ -109,7 +107,7 @@ import android.view.Menu;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.ViewTreeObserver.OnPreDrawListener;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
@@ -130,7 +128,6 @@ import com.android.launcher3.allapps.AllAppsStore;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.allapps.BaseAllAppsContainerView;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.anim.PropertyListBuilder;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
@@ -186,8 +183,6 @@ import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSet;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
@@ -341,6 +336,7 @@ public class Launcher extends StatefulActivity<LauncherState>
|
||||
private Runnable mOnDeferredActivityLaunchCallback;
|
||||
|
||||
private ViewOnDrawExecutor mPendingExecutor;
|
||||
private OnPreDrawListener mOnInitialBindListener;
|
||||
|
||||
private LauncherModel mModel;
|
||||
private ModelWriter mModelWriter;
|
||||
@@ -503,11 +499,10 @@ public class Launcher extends StatefulActivity<LauncherState>
|
||||
|
||||
if (!mModel.addCallbacksAndLoad(this)) {
|
||||
if (!internalStateHandled) {
|
||||
Log.d(BAD_STATE, "Launcher onCreate not binding sync, setting DragLayer alpha "
|
||||
+ "ALPHA_INDEX_LAUNCHER_LOAD to 0");
|
||||
// If we are not binding synchronously, show a fade in animation when
|
||||
// the first page bind completes.
|
||||
mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
|
||||
Log.d(BAD_STATE, "Launcher onCreate not binding sync, prevent drawing");
|
||||
// If we are not binding synchronously, pause drawing until initial bind complete,
|
||||
// so that the system could continue to show the device loading prompt
|
||||
mOnInitialBindListener = Boolean.FALSE::booleanValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,25 +510,9 @@ public class Launcher extends StatefulActivity<LauncherState>
|
||||
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
|
||||
|
||||
setContentView(getRootView());
|
||||
getRootView().getViewTreeObserver().addOnPreDrawListener(
|
||||
new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
// Checks the status of fade in animation.
|
||||
final AlphaProperty property =
|
||||
mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD);
|
||||
if (property.getValue() == 0) {
|
||||
Log.d(BAD_STATE, "Launcher onPreDraw ALPHA_INDEX_LAUNCHER_LOAD not"
|
||||
+ " started yet, cancelling draw.");
|
||||
// Animation haven't started yet; suspend.
|
||||
return false;
|
||||
} else {
|
||||
// The animation is started; start drawing.
|
||||
getRootView().getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (mOnInitialBindListener != null) {
|
||||
getRootView().getViewTreeObserver().addOnPreDrawListener(mOnInitialBindListener);
|
||||
}
|
||||
getRootView().dispatchInsets();
|
||||
|
||||
// Listen for broadcasts
|
||||
@@ -2692,36 +2671,12 @@ public class Launcher extends StatefulActivity<LauncherState>
|
||||
AllAppsStore.DEFER_UPDATES_NEXT_DRAW));
|
||||
}
|
||||
|
||||
AlphaProperty property = mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD);
|
||||
if (property.getValue() < 1) {
|
||||
ObjectAnimator anim = ObjectAnimator.ofFloat(property, MultiValueAlpha.VALUE, 1);
|
||||
|
||||
Log.d(BAD_STATE, "Launcher onInitialBindComplete toAlpha=" + 1);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
Log.d(BAD_STATE, "Launcher onInitialBindComplete onStart");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
float alpha = mDragLayer == null
|
||||
? -1
|
||||
: mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).getValue();
|
||||
Log.d(BAD_STATE, "Launcher onInitialBindComplete onCancel, alpha=" + alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
Log.d(BAD_STATE, "Launcher onInitialBindComplete onEnd");
|
||||
}
|
||||
});
|
||||
|
||||
anim.addListener(AnimatorListeners.forEndCallback(executor::onLoadAnimationCompleted));
|
||||
anim.start();
|
||||
} else {
|
||||
executor.onLoadAnimationCompleted();
|
||||
if (mOnInitialBindListener != null) {
|
||||
getRootView().getViewTreeObserver().removeOnPreDrawListener(mOnInitialBindListener);
|
||||
mOnInitialBindListener = null;
|
||||
}
|
||||
|
||||
executor.onLoadAnimationCompleted();
|
||||
executor.attachTo(this);
|
||||
if (Utilities.ATLEAST_S) {
|
||||
Trace.endAsyncSection(DISPLAY_WORKSPACE_TRACE_METHOD_NAME,
|
||||
|
||||
@@ -1440,7 +1440,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
return Math.abs(velocity) > threshold;
|
||||
}
|
||||
|
||||
private void resetTouchState() {
|
||||
protected void resetTouchState() {
|
||||
releaseVelocityTracker();
|
||||
mIsBeingDragged = false;
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
|
||||
@@ -44,6 +44,8 @@ import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.util.MultiAdditivePropertyFactory;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
|
||||
@@ -76,20 +78,56 @@ public class AllAppsTransitionController
|
||||
}
|
||||
};
|
||||
|
||||
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PULL_BACK_PROGRESS =
|
||||
new FloatProperty<AllAppsTransitionController>("allAppsPullBackProgress") {
|
||||
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PULL_BACK_TRANSLATION =
|
||||
new FloatProperty<AllAppsTransitionController>("allAppsPullBackTranslation") {
|
||||
|
||||
@Override
|
||||
public Float get(AllAppsTransitionController controller) {
|
||||
return controller.mPullBackProgress;
|
||||
if (controller.mIsTablet) {
|
||||
return controller.mAppsView.getRecyclerViewContainer().getTranslationY();
|
||||
} else {
|
||||
return controller.getAppsViewPullbackTranslationY().get(
|
||||
controller.mAppsView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(AllAppsTransitionController controller, float progress) {
|
||||
controller.setPullBackProgress(progress);
|
||||
public void setValue(AllAppsTransitionController controller, float translation) {
|
||||
if (controller.mIsTablet) {
|
||||
controller.mAppsView.getRecyclerViewContainer().setTranslationY(
|
||||
translation);
|
||||
} else {
|
||||
controller.getAppsViewPullbackTranslationY().set(controller.mAppsView,
|
||||
translation);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PULL_BACK_ALPHA =
|
||||
new FloatProperty<AllAppsTransitionController>("allAppsPullBackAlpha") {
|
||||
|
||||
@Override
|
||||
public Float get(AllAppsTransitionController controller) {
|
||||
if (controller.mIsTablet) {
|
||||
return controller.mAppsView.getRecyclerViewContainer().getAlpha();
|
||||
} else {
|
||||
return controller.getAppsViewPullbackAlpha().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(AllAppsTransitionController controller, float alpha) {
|
||||
if (controller.mIsTablet) {
|
||||
controller.mAppsView.getRecyclerViewContainer().setAlpha(alpha);
|
||||
} else {
|
||||
controller.getAppsViewPullbackAlpha().setValue(alpha);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static final int INDEX_APPS_VIEW_PROGRESS = 0;
|
||||
private static final int INDEX_APPS_VIEW_PULLBACK = 1;
|
||||
private static final int APPS_VIEW_INDEX_COUNT = 2;
|
||||
|
||||
private ActivityAllAppsContainerView<Launcher> mAppsView;
|
||||
|
||||
@@ -104,18 +142,23 @@ public class AllAppsTransitionController
|
||||
// When {@link mProgress} is 1, all apps container is pulled down.
|
||||
private float mShiftRange; // changes depending on the orientation
|
||||
private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent
|
||||
private float mPullBackProgress; // [0, 1], mShiftRange * mPullBackProgress = shiftCurrent
|
||||
|
||||
private ScrimView mScrimView;
|
||||
private View mPullBackView;
|
||||
|
||||
private final MultiAdditivePropertyFactory<View>
|
||||
mAppsViewTranslationYPropertyFactory = new MultiAdditivePropertyFactory<>(
|
||||
"appsViewTranslationY", View.TRANSLATION_Y);
|
||||
private MultiValueAlpha mAppsViewAlpha;
|
||||
|
||||
private boolean mIsTablet;
|
||||
|
||||
public AllAppsTransitionController(Launcher l) {
|
||||
mLauncher = l;
|
||||
DeviceProfile dp = mLauncher.getDeviceProfile();
|
||||
setShiftRange(dp.allAppsShiftRange);
|
||||
mProgress = 1f;
|
||||
mPullBackProgress = 1f;
|
||||
mIsVerticalLayout = dp.isVerticalBarLayout();
|
||||
mIsTablet = dp.isTablet;
|
||||
mLauncher.addOnDeviceProfileChangeListener(this);
|
||||
}
|
||||
|
||||
@@ -133,7 +176,7 @@ public class AllAppsTransitionController
|
||||
mLauncher.getWorkspace().getPageIndicator().setTranslationY(0);
|
||||
}
|
||||
|
||||
mPullBackView = dp.isTablet ? mAppsView.getRecyclerViewContainer() : mAppsView;
|
||||
mIsTablet = dp.isTablet;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,16 +189,27 @@ public class AllAppsTransitionController
|
||||
*/
|
||||
public void setProgress(float progress) {
|
||||
mProgress = progress;
|
||||
mAppsView.setTranslationY(mProgress * mShiftRange);
|
||||
getAppsViewProgressTranslationY().set(mAppsView, mProgress * mShiftRange);
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
return mProgress;
|
||||
}
|
||||
|
||||
private void setPullBackProgress(float progress) {
|
||||
mPullBackProgress = progress;
|
||||
mPullBackView.setTranslationY(mPullBackProgress * mShiftRange);
|
||||
private FloatProperty<View> getAppsViewProgressTranslationY() {
|
||||
return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PROGRESS);
|
||||
}
|
||||
|
||||
private FloatProperty<View> getAppsViewPullbackTranslationY() {
|
||||
return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PULLBACK);
|
||||
}
|
||||
|
||||
private MultiValueAlpha.AlphaProperty getAppsViewProgressAlpha() {
|
||||
return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PROGRESS);
|
||||
}
|
||||
|
||||
private MultiValueAlpha.AlphaProperty getAppsViewPullbackAlpha() {
|
||||
return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PULLBACK);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,8 +218,6 @@ public class AllAppsTransitionController
|
||||
*/
|
||||
@Override
|
||||
public void setState(LauncherState state) {
|
||||
// Always reset pull back progress when switching states.
|
||||
setPullBackProgress(0f);
|
||||
setProgress(state.getVerticalProgress(mLauncher));
|
||||
setAlphas(state, new StateAnimationConfig(), NO_ANIM_PROPERTY_SETTER);
|
||||
onProgressAnimationEnd();
|
||||
@@ -180,10 +232,13 @@ public class AllAppsTransitionController
|
||||
StateAnimationConfig config, PendingAnimation builder) {
|
||||
if (NORMAL.equals(toState) && mLauncher.isInState(ALL_APPS)) {
|
||||
UiThreadHelper.hideKeyboardAsync(mLauncher, mLauncher.getAppsView().getWindowToken());
|
||||
builder.addEndListener(success -> {
|
||||
// Reset pull back progress and alpha after switching states.
|
||||
ALL_APPS_PULL_BACK_TRANSLATION.set(this, 0f);
|
||||
ALL_APPS_PULL_BACK_ALPHA.set(this, 1f);
|
||||
});
|
||||
}
|
||||
|
||||
// Always reset pull back progress when switching states.
|
||||
setPullBackProgress(0f);
|
||||
float targetProgress = toState.getVerticalProgress(mLauncher);
|
||||
if (Float.compare(mProgress, targetProgress) == 0) {
|
||||
setAlphas(toState, config, builder);
|
||||
@@ -222,7 +277,8 @@ public class AllAppsTransitionController
|
||||
boolean hasAllAppsContent = (visibleElements & ALL_APPS_CONTENT) != 0;
|
||||
|
||||
Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
|
||||
setter.setViewAlpha(mAppsView, hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
setter.setFloat(getAppsViewProgressAlpha(), MultiValueAlpha.VALUE,
|
||||
hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
|
||||
boolean shouldProtectHeader =
|
||||
ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
|
||||
@@ -245,8 +301,8 @@ public class AllAppsTransitionController
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
}
|
||||
mAppsView.setScrimView(scrimView);
|
||||
mPullBackView = mLauncher.getDeviceProfile().isTablet
|
||||
? mAppsView.getRecyclerViewContainer() : mAppsView;
|
||||
mAppsViewAlpha = new MultiValueAlpha(mAppsView, APPS_VIEW_INDEX_COUNT);
|
||||
mAppsViewAlpha.setUpdateVisibility(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,9 +65,7 @@ import java.util.ArrayList;
|
||||
public class DragLayer extends BaseDragLayer<Launcher> {
|
||||
|
||||
public static final int ALPHA_INDEX_OVERLAY = 0;
|
||||
public static final int ALPHA_INDEX_LAUNCHER_LOAD = 1;
|
||||
public static final int ALPHA_INDEX_TRANSITIONS = 2;
|
||||
private static final int ALPHA_CHANNEL_COUNT = 3;
|
||||
private static final int ALPHA_CHANNEL_COUNT = 1;
|
||||
|
||||
public static final int ANIMATION_END_DISAPPEAR = 0;
|
||||
public static final int ANIMATION_END_REMAIN_VISIBLE = 2;
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.util.ArrayMap;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.Log;
|
||||
import android.util.Property;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Allows to combine multiple values set by several sources.
|
||||
*
|
||||
* The various sources are meant to use [set], providing different `setterIndex` params. When it is
|
||||
* not set, 0 is used. This is meant to cover the case multiple animations are going on at the same
|
||||
* time.
|
||||
*
|
||||
* This class behaves similarly to [MultiValueAlpha], but is meant to be more abstract and reusable.
|
||||
* It sets the addition of all values.
|
||||
*
|
||||
* @param <T> Type where to apply the property.
|
||||
*/
|
||||
public class MultiAdditivePropertyFactory<T extends View> {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "MultiAdditivePropertyFactory";
|
||||
private final String mName;
|
||||
private final ArrayMap<Integer, MultiAdditiveProperty> mProperties =
|
||||
new ArrayMap<>();
|
||||
|
||||
// This is an optimization for cases when set is called repeatedly with the same setterIndex.
|
||||
private float mAggregationOfOthers = 0f;
|
||||
private Integer mLastIndexSet = -1;
|
||||
private final Property<View, Float> mProperty;
|
||||
|
||||
public MultiAdditivePropertyFactory(String name, Property<View, Float> property) {
|
||||
mName = name;
|
||||
mProperty = property;
|
||||
}
|
||||
|
||||
/** Returns the [MultiFloatProperty] associated with [inx], creating it if not present. */
|
||||
public MultiAdditiveProperty get(Integer index) {
|
||||
return mProperties.computeIfAbsent(index,
|
||||
(k) -> new MultiAdditiveProperty(index, mName + "_" + index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Each [setValue] will be aggregated with the other properties values created by the
|
||||
* corresponding factory.
|
||||
*/
|
||||
class MultiAdditiveProperty extends FloatProperty<T> {
|
||||
private final int mInx;
|
||||
private float mValue = 0f;
|
||||
|
||||
MultiAdditiveProperty(int inx, String name) {
|
||||
super(name);
|
||||
mInx = inx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(T obj, float newValue) {
|
||||
if (mLastIndexSet != mInx) {
|
||||
mAggregationOfOthers = 0f;
|
||||
mProperties.forEach((key, property) -> {
|
||||
if (key != mInx) {
|
||||
mAggregationOfOthers += property.mValue;
|
||||
}
|
||||
});
|
||||
mLastIndexSet = mInx;
|
||||
}
|
||||
float lastAggregatedValue = mAggregationOfOthers + newValue;
|
||||
mValue = newValue;
|
||||
apply(obj, lastAggregatedValue);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "name=" + mName
|
||||
+ " newValue=" + newValue + " mInx=" + mInx
|
||||
+ " aggregated=" + lastAggregatedValue + " others= " + mProperties);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(T view) {
|
||||
// The scale of the view should match mLastAggregatedValue. Still, if it has been
|
||||
// changed without using this property, it can differ. As this get method is usually
|
||||
// used to set the starting point on an animation, this would result in some jumps
|
||||
// when the view scale is different than the last aggregated value. To stay on the
|
||||
// safe side, let's return the real view scale.
|
||||
return mProperty.get(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(mValue);
|
||||
}
|
||||
}
|
||||
|
||||
protected void apply(View view, float value) {
|
||||
mProperty.set(view, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.view.View
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/** Unit tests for [MultiAdditivePropertyFactory] */
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MultiAdditivePropertyTest {
|
||||
|
||||
private val received = mutableListOf<Float>()
|
||||
|
||||
private val factory =
|
||||
object : MultiAdditivePropertyFactory<View?>("Test", View.TRANSLATION_X) {
|
||||
override fun apply(obj: View?, value: Float) {
|
||||
received.add(value)
|
||||
}
|
||||
}
|
||||
|
||||
private val p1 = factory.get(1)
|
||||
private val p2 = factory.get(2)
|
||||
private val p3 = factory.get(3)
|
||||
|
||||
@Test
|
||||
fun set_sameIndexes_allApplied() {
|
||||
val v1 = 50f
|
||||
val v2 = 100f
|
||||
p1.set(null, v1)
|
||||
p1.set(null, v1)
|
||||
p1.set(null, v2)
|
||||
|
||||
assertThat(received).containsExactly(v1, v1, v2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun set_differentIndexes_aggregationApplied() {
|
||||
val v1 = 50f
|
||||
val v2 = 100f
|
||||
val v3 = 150f
|
||||
p1.set(null, v1)
|
||||
p2.set(null, v2)
|
||||
p3.set(null, v3)
|
||||
|
||||
assertThat(received).containsExactly(v1, v1 + v2, v1 + v2 + v3)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.view.View
|
||||
|
||||
Reference in New Issue
Block a user