* @param fadeoutDuration the duration of the exit animation, in milliseconds
*/
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
-
- /**
- * Calculates the stable insets without running a layout.
- *
- * @param displayRotation the current display rotation
- * @param outInsets the insets to return
- * @param displayWidth the current display width
- * @param displayHeight the current display height
- */
- public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
- Rect outInsets);
}
+++ /dev/null
-/*
- * Copyright (C) 2015 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.internal.policy;
-
-import android.graphics.Rect;
-import android.view.WindowManager;
-
-/**
- * Utility functions for docked stack divider used by both window manager and System UI.
- *
- * @hide
- */
-public class DockedDividerUtils {
-
- public static void calculateBoundsForPosition(int position, int dockSide, Rect outRect,
- int displayWidth, int displayHeight, int dividerSize) {
- outRect.set(0, 0, displayWidth, displayHeight);
- switch (dockSide) {
- case WindowManager.DOCKED_LEFT:
- outRect.right = position;
- break;
- case WindowManager.DOCKED_TOP:
- outRect.bottom = position;
- break;
- case WindowManager.DOCKED_RIGHT:
- outRect.left = position + dividerSize;
- break;
- case WindowManager.DOCKED_BOTTOM:
- outRect.top = position + dividerSize;
- break;
- }
- if (outRect.left > outRect.right) {
- outRect.left = outRect.right;
- }
- if (outRect.top > outRect.bottom) {
- outRect.top = outRect.bottom;
- }
- if (outRect.right < outRect.left) {
- outRect.right = outRect.left;
- }
- if (outRect.bottom < outRect.top) {
- outRect.bottom = outRect.top;
- }
- }
-
- public static int calculatePositionForBounds(Rect bounds, int dockSide, int dividerSize) {
- switch (dockSide) {
- case WindowManager.DOCKED_LEFT:
- return bounds.right;
- case WindowManager.DOCKED_TOP:
- return bounds.bottom;
- case WindowManager.DOCKED_RIGHT:
- return bounds.left - dividerSize;
- case WindowManager.DOCKED_BOTTOM:
- return bounds.top - dividerSize;
- default:
- return 0;
- }
- }
-}
* limitations under the License.
*/
-package com.android.internal.policy;
+package com.android.systemui.stackdivider;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Rect;
+import com.android.systemui.statusbar.FlingAnimationUtils;
+
import java.util.ArrayList;
/**
* Calculates the snap targets and the snap position given a position and a velocity. All positions
* here are to be interpreted as the left/top edge of the divider rectangle.
- *
- * @hide
*/
public class DividerSnapAlgorithm {
*/
private static final int SNAP_ONLY_1_1 = 2;
- private final float mMinFlingVelocityPxPerSecond;
+ private final Context mContext;
+ private final FlingAnimationUtils mFlingAnimationUtils;
private final int mDisplayWidth;
private final int mDisplayHeight;
private final int mDividerSize;
private final SnapTarget mDismissStartTarget;
private final SnapTarget mDismissEndTarget;
- public DividerSnapAlgorithm(Resources res, float minFlingVelocityPxPerSecond,
+ public DividerSnapAlgorithm(Context ctx, FlingAnimationUtils flingAnimationUtils,
int displayWidth, int displayHeight, int dividerSize, boolean isHorizontalDivision,
Rect insets) {
- mMinFlingVelocityPxPerSecond = minFlingVelocityPxPerSecond;
+ mContext = ctx;
+ mFlingAnimationUtils = flingAnimationUtils;
mDividerSize = dividerSize;
mDisplayWidth = displayWidth;
mDisplayHeight = displayHeight;
mInsets.set(insets);
- mSnapMode = res.getInteger(
+ mSnapMode = ctx.getResources().getInteger(
com.android.internal.R.integer.config_dockedStackDividerSnapMode);
- mFixedRatio = res.getFraction(
+ mFixedRatio = ctx.getResources().getFraction(
com.android.internal.R.fraction.docked_stack_divider_fixed_ratio, 1, 1);
calculateTargets(isHorizontalDivision);
mFirstSplitTarget = mTargets.get(1);
}
public SnapTarget calculateSnapTarget(int position, float velocity) {
- if (Math.abs(velocity) < mMinFlingVelocityPxPerSecond) {
+ if (Math.abs(velocity) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
return snap(position);
}
if (position < mFirstSplitTarget.position && velocity < 0) {
}
}
- public SnapTarget calculateNonDismissingSnapTarget(int position) {
- SnapTarget target = snap(position);
- if (target == mDismissStartTarget) {
- return mFirstSplitTarget;
- } else if (target == mDismissEndTarget) {
- return mLastSplitTarget;
- } else {
- return target;
- }
- }
-
public float calculateDismissingFraction(int position) {
if (position < mFirstSplitTarget.position) {
return 1f - (float) position / mFirstSplitTarget.position;
import android.graphics.Region.Op;
import android.hardware.display.DisplayManager;
import android.util.AttributeSet;
+import android.util.MathUtils;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver.InternalInsetsInfo;
import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
+import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageButton;
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.internal.policy.DockedDividerUtils;
import com.android.systemui.R;
-import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
+import com.android.systemui.stackdivider.DividerSnapAlgorithm.SnapTarget;
import com.android.systemui.statusbar.FlingAnimationUtils;
import static android.view.PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW;
public boolean startDragging(boolean animate) {
mHandle.setTouching(true, animate);
mDockSide = mWindowManagerProxy.getDockSide();
- mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(),
- mFlingAnimationUtils.getMinVelocityPxPerSecond(), mDisplayWidth,
+ mSnapAlgorithm = new DividerSnapAlgorithm(getContext(), mFlingAnimationUtils, mDisplayWidth,
mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets);
if (mDockSide != WindowManager.DOCKED_INVALID) {
mWindowManagerProxy.setResizing(true);
return mStartPosition + touchY - mStartY;
}
+ public void calculateBoundsForPosition(int position, int dockSide, Rect outRect) {
+ outRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+ switch (dockSide) {
+ case WindowManager.DOCKED_LEFT:
+ outRect.right = position;
+ break;
+ case WindowManager.DOCKED_TOP:
+ outRect.bottom = position;
+ break;
+ case WindowManager.DOCKED_RIGHT:
+ outRect.left = position + mDividerWindowWidth - 2 * mDividerInsets;
+ break;
+ case WindowManager.DOCKED_BOTTOM:
+ outRect.top = position + mDividerWindowWidth - 2 * mDividerInsets;
+ break;
+ }
+ if (outRect.left > outRect.right) {
+ outRect.left = outRect.right;
+ }
+ if (outRect.top > outRect.bottom) {
+ outRect.top = outRect.bottom;
+ }
+ if (outRect.right < outRect.left) {
+ outRect.right = outRect.left;
+ }
+ if (outRect.bottom < outRect.top) {
+ outRect.bottom = outRect.top;
+ }
+ }
+
private int invertDockSide(int dockSide) {
switch (dockSide) {
case WindowManager.DOCKED_LEFT:
containingRect.right, containingRect.bottom);
}
- public void calculateBoundsForPosition(int position, int dockSide, Rect outRect) {
- DockedDividerUtils.calculateBoundsForPosition(position, dockSide, outRect, mDisplayWidth,
- mDisplayHeight, mDividerSize);
- }
-
public void resizeStack(int position, int taskPosition, SnapTarget taskSnapTarget) {
calculateBoundsForPosition(position, mDockSide, mDockedRect);
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.stackdivider.Divider;
-import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
+import com.android.systemui.stackdivider.DividerSnapAlgorithm.SnapTarget;
+import com.android.systemui.stackdivider.DividerView;
import com.android.systemui.tuner.TunerService;
import static android.view.WindowManager.*;
// size. We need to do this directly, instead of relying on
// it to bubble up from the nav bar, because this needs to
// change atomically with screen rotations.
- mNavigationBarOnBottom = isNavigationBarOnBottom(displayWidth, displayHeight);
+ mNavigationBarOnBottom = (!mNavigationBarCanMove || displayWidth < displayHeight);
if (mNavigationBarOnBottom) {
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
int top = displayHeight - overscanBottom
return false;
}
- private boolean isNavigationBarOnBottom(int displayWidth, int displayHeight) {
- return !mNavigationBarCanMove || displayWidth < displayHeight;
- }
-
/** {@inheritDoc} */
@Override
public int getSystemDecorLayerLw() {
}
}
- @Override
- public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
- Rect outInsets) {
- outInsets.setEmpty();
- if (mStatusBar != null) {
- outInsets.top = mStatusBarHeight;
- }
- if (mNavigationBar != null) {
- if (isNavigationBarOnBottom(displayWidth, displayHeight)) {
- outInsets.bottom = mNavigationBarHeightForRotation[displayRotation];
- } else {
- outInsets.right = mNavigationBarWidthForRotation[displayRotation];
- }
- }
- }
-
void sendCloseSystemWindows() {
PhoneWindow.sendCloseSystemWindows(mContext, null);
}
import android.app.ActivityManager.StackId;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Debug;
import android.util.EventLog;
import android.view.DisplayInfo;
import android.view.Surface;
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
-import com.android.internal.policy.DockedDividerUtils;
import com.android.server.EventLogTags;
import java.io.PrintWriter;
setBounds(null);
} else {
mTmpRect2.set(mBounds);
- int newRotation = mDisplayContent.getDisplayInfo().rotation;
- if (mRotation == newRotation) {
- setBounds(mTmpRect2);
+ mDisplayContent.rotateBounds(
+ mRotation, mDisplayContent.getDisplayInfo().rotation, mTmpRect2);
+ if (setBounds(mTmpRect2)) {
+ // Post message to inform activity manager of the bounds change simulating
+ // a one-way call. We do this to prevent a deadlock between window manager
+ // lock and activity manager lock been held.
+ mService.mH.sendMessage(mService.mH.obtainMessage(
+ RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mBounds));
}
-
- // If the rotation changes, we'll handle it in updateBoundsAfterRotation
}
}
}
- /**
- * Updates the bounds after rotating the screen. We can't handle it in
- * {@link #updateDisplayInfo} because at that point the configuration might not be fully updated
- * yet.
- */
- void updateBoundsAfterRotation() {
- final int newRotation = getDisplayInfo().rotation;
- mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
- if (mStackId == DOCKED_STACK_ID) {
- snapDockedStackAfterRotation(mTmpRect2);
- }
-
- // Post message to inform activity manager of the bounds change simulating
- // a one-way call. We do this to prevent a deadlock between window manager
- // lock and activity manager lock been held.
- mService.mH.sendMessage(mService.mH.obtainMessage(
- RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2));
- }
-
- /**
- * Snaps the bounds after rotation to the closest snap target for the docked stack.
- */
- private void snapDockedStackAfterRotation(Rect outBounds) {
-
- // Calculate the current position.
- final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
- final int dividerSize = mService.getDefaultDisplayContentLocked()
- .getDockedDividerController().getContentWidth();
- final int dockSide = getDockSide(outBounds);
- final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
- dockSide, dividerSize);
- final int displayWidth = mDisplayContent.getDisplayInfo().logicalWidth;
- final int displayHeight = mDisplayContent.getDisplayInfo().logicalHeight;
-
- // Snap the position to a target.
- final int rotation = displayInfo.rotation;
- final int orientation = mService.mCurConfiguration.orientation;
- mService.mPolicy.getStableInsetsLw(rotation, displayWidth, displayHeight, outBounds);
- final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
- mService.mContext.getResources(),
- 0 /* minFlingVelocityPxPerSecond */, displayWidth, displayHeight,
- dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds);
- final SnapTarget target = algorithm.calculateNonDismissingSnapTarget(dividerPosition);
-
- // Recalculate the bounds based on the position of the target.
- DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
- outBounds, displayInfo.logicalWidth, displayInfo.logicalHeight,
- dividerSize);
- }
-
boolean isAnimating() {
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
* information which side of the screen was the dock anchored.
*/
int getDockSide() {
- return getDockSide(mBounds);
- }
-
- int getDockSide(Rect bounds) {
if (mStackId != DOCKED_STACK_ID && !StackId.isResizeableByDockedStack(mStackId)) {
return DOCKED_INVALID;
}
final int orientation = mService.mCurConfiguration.orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// Portrait mode, docked either at the top or the bottom.
- if (bounds.top - mTmpRect.top < mTmpRect.bottom - bounds.bottom) {
+ if (mBounds.top - mTmpRect.top < mTmpRect.bottom - mBounds.bottom) {
return DOCKED_TOP;
} else {
return DOCKED_BOTTOM;
}
} else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Landscape mode, docked either on the left or on the right.
- if (bounds.left - mTmpRect.left < mTmpRect.right - bounds.right) {
+ if (mBounds.left - mTmpRect.left < mTmpRect.right - mBounds.right) {
return DOCKED_LEFT;
} else {
return DOCKED_RIGHT;
}
}
- @Override
public void setNewConfiguration(Configuration config) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setNewConfiguration()")) {
mWaitingForConfig = false;
mLastFinishedFreezeSource = "new-config";
}
- if (orientationChanged) {
- updateTaskStackBoundsAfterRotation();
- }
mWindowPlacerLocked.performSurfacePlacement();
}
}
- private void updateTaskStackBoundsAfterRotation() {
- for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) {
- final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
- stack.updateBoundsAfterRotation();
- }
- }
-
@Override
public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,