Merge "Update sysui flags" into ub-launcher3-qt-dev
diff --git a/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java b/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java
index 6bc859a..af07aa3 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java
@@ -23,8 +23,10 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
-import android.graphics.Point;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.util.Log;
import android.view.ViewDebug;
@@ -36,33 +38,51 @@
private static final String TAG = "DotRenderer";
// The dot size is defined as a percentage of the app icon size.
- private static final float SIZE_PERCENTAGE = 0.38f;
+ private static final float SIZE_PERCENTAGE = 0.228f;
- // Extra scale down of the dot
- private static final float DOT_SCALE = 0.6f;
-
- // Offset the dot slightly away from the icon if there's space.
- private static final float OFFSET_PERCENTAGE = 0.02f;
-
- private final float mDotCenterOffset;
- private final int mOffset;
private final float mCircleRadius;
private final Paint mCirclePaint = new Paint(ANTI_ALIAS_FLAG | FILTER_BITMAP_FLAG);
private final Bitmap mBackgroundWithShadow;
private final float mBitmapOffset;
- public DotRenderer(int iconSizePx) {
- mDotCenterOffset = SIZE_PERCENTAGE * iconSizePx;
- mOffset = (int) (OFFSET_PERCENTAGE * iconSizePx);
+ // Stores the center x and y position as a percentage (0 to 1) of the icon size
+ private final float[] mRightDotPosition;
+ private final float[] mLeftDotPosition;
- int size = (int) (DOT_SCALE * mDotCenterOffset);
+ public DotRenderer(int iconSizePx, Path iconShapePath, int pathSize) {
+ int size = Math.round(SIZE_PERCENTAGE * iconSizePx);
ShadowGenerator.Builder builder = new ShadowGenerator.Builder(Color.TRANSPARENT);
builder.ambientShadowAlpha = 88;
mBackgroundWithShadow = builder.setupBlurForSize(size).createPill(size, size);
mCircleRadius = builder.radius;
mBitmapOffset = -mBackgroundWithShadow.getHeight() * 0.5f; // Same as width.
+
+ // Find the points on the path that are closest to the top left and right corners.
+ mLeftDotPosition = getPathPoint(iconShapePath, pathSize, -1);
+ mRightDotPosition = getPathPoint(iconShapePath, pathSize, 1);
+ }
+
+ private static float[] getPathPoint(Path path, float size, float direction) {
+ float halfSize = size / 2;
+ // Small delta so that we don't get a zero size triangle
+ float delta = 1;
+
+ float x = halfSize + direction * halfSize;
+ Path trianglePath = new Path();
+ trianglePath.moveTo(halfSize, halfSize);
+ trianglePath.lineTo(x + delta * direction, 0);
+ trianglePath.lineTo(x, -delta);
+ trianglePath.close();
+
+ trianglePath.op(path, Path.Op.INTERSECT);
+ float[] pos = new float[2];
+ new PathMeasure(trianglePath, false).getPosTan(0, pos, null);
+
+ pos[0] = pos[0] / size;
+ pos[1] = pos[1] / size;
+ return pos;
}
/**
@@ -74,15 +94,21 @@
return;
}
canvas.save();
- // We draw the dot relative to its center.
- float dotCenterX = params.leftAlign
- ? params.iconBounds.left + mDotCenterOffset / 2
- : params.iconBounds.right - mDotCenterOffset / 2;
- float dotCenterY = params.iconBounds.top + mDotCenterOffset / 2;
- int offsetX = Math.min(mOffset, params.spaceForOffset.x);
- int offsetY = Math.min(mOffset, params.spaceForOffset.y);
- canvas.translate(dotCenterX + offsetX, dotCenterY - offsetY);
+ Rect iconBounds = params.iconBounds;
+ float[] dotPosition = params.leftAlign ? mLeftDotPosition : mRightDotPosition;
+ float dotCenterX = iconBounds.left + iconBounds.width() * dotPosition[0];
+ float dotCenterY = iconBounds.top + iconBounds.height() * dotPosition[1];
+
+ // Ensure dot fits entirely in canvas clip bounds.
+ Rect canvasBounds = canvas.getClipBounds();
+ float offsetX = params.leftAlign
+ ? Math.max(0, canvasBounds.left - (dotCenterX + mBitmapOffset))
+ : Math.min(0, canvasBounds.right - (dotCenterX - mBitmapOffset));
+ float offsetY = Math.max(0, canvasBounds.top - (dotCenterY + mBitmapOffset));
+
+ // We draw the dot relative to its center.
+ canvas.translate(dotCenterX + offsetX, dotCenterY + offsetY);
canvas.scale(params.scale, params.scale);
mCirclePaint.setColor(Color.BLACK);
@@ -102,9 +128,6 @@
/** The progress of the animation, from 0 to 1. */
@ViewDebug.ExportedProperty(category = "notification dot")
public float scale;
- /** Overrides internally calculated offset if specified value is smaller. */
- @ViewDebug.ExportedProperty(category = "notification dot")
- public Point spaceForOffset = new Point();
/** Whether the dot should align to the top left of the icon rather than the top right. */
@ViewDebug.ExportedProperty(category = "notification dot")
public boolean leftAlign;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 61ae880..a343a36 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -429,8 +429,7 @@
MotionEvent event = (MotionEvent) ev;
TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked());
if (event.getAction() == ACTION_DOWN) {
- if (isInValidSystemUiState()
- && mSwipeTouchRegion.contains(event.getX(), event.getY())) {
+ if (mSwipeTouchRegion.contains(event.getX(), event.getY())) {
boolean useSharedState = mConsumer.useSharedSwipeState();
mConsumer.onConsumerAboutToBeSwitched();
mConsumer = newConsumer(useSharedState, event);
@@ -443,15 +442,45 @@
mUncheckedConsumer.onMotionEvent(event);
}
- private boolean isInValidSystemUiState() {
- return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
- && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
- && !ActivityManagerWrapper.getInstance().isLockToAppActive();
- }
private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) {
- // TODO: this makes a binder call every touch down. we should move to a listener pattern.
- if (!mIsUserUnlocked || mKM.isDeviceLocked()) {
+ boolean validSystemUIFlags = (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0;
+ boolean topTaskLocked = ActivityManagerWrapper.getInstance().isLockToAppActive();
+ boolean isInValidSystemUiState = validSystemUIFlags && !topTaskLocked;
+
+ if (!mIsUserUnlocked) {
+ if (isInValidSystemUiState) {
+ // This handles apps launched in direct boot mode (e.g. dialer) as well as apps
+ // launched while device is locked even after exiting direct boot mode (e.g. camera).
+ return new DeviceLockedInputConsumer(this);
+ } else {
+ return InputConsumer.NO_OP;
+ }
+ }
+
+ InputConsumer base = isInValidSystemUiState
+ ? newBaseConsumer(useSharedState, event) : InputConsumer.NO_OP;
+ if (mMode == Mode.NO_BUTTON) {
+ final ActivityControlHelper activityControl =
+ mOverviewComponentObserver.getActivityControlHelper();
+ if (mAssistantAvailable && !topTaskLocked
+ && AssistantTouchConsumer.withinTouchRegion(this, event)) {
+ base = new AssistantTouchConsumer(this, mISystemUiProxy, activityControl, base,
+ mInputMonitorCompat);
+ }
+
+ if ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) {
+ base = new AccessibilityInputConsumer(this, mISystemUiProxy,
+ (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0, base,
+ mInputMonitorCompat);
+ }
+ }
+ return base;
+ }
+
+ private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) {
+ if (mKM.isDeviceLocked()) {
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps launched
// while device is locked even after exiting direct boot mode (e.g. camera).
return new DeviceLockedInputConsumer(this);
@@ -465,42 +494,26 @@
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
- InputConsumer base;
if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher
&& !mSwipeSharedState.recentsAnimationFinishInterrupted) {
- base = InputConsumer.NO_OP;
+ return InputConsumer.NO_OP;
} else if (mSwipeSharedState.recentsAnimationFinishInterrupted) {
// If the finish animation was interrupted, then continue using the other activity input
// consumer but with the next task as the running task
RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
info.id = mSwipeSharedState.nextRunningTaskId;
- base = createOtherActivityInputConsumer(event, info);
+ return createOtherActivityInputConsumer(event, info);
} else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
- base = OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
+ return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
activityControl.isInLiveTileMode()) {
- base = OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
+ return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
} else if (mGestureBlockingActivity != null && runningTaskInfo != null
&& mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
- base = InputConsumer.NO_OP;
+ return InputConsumer.NO_OP;
} else {
- base = createOtherActivityInputConsumer(event, runningTaskInfo);
+ return createOtherActivityInputConsumer(event, runningTaskInfo);
}
-
- if (mMode == Mode.NO_BUTTON) {
- if (mAssistantAvailable && AssistantTouchConsumer.withinTouchRegion(this, event)) {
- base = new AssistantTouchConsumer(this, mISystemUiProxy, activityControl, base,
- mInputMonitorCompat);
- }
-
- if ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) {
- base = new AccessibilityInputConsumer(this, mISystemUiProxy,
- (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0, base,
- mInputMonitorCompat);
- }
- }
-
- return base;
}
private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event,
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
new file mode 100644
index 0000000..82b0b8d
--- /dev/null
+++ b/res/layout/hotseat.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.launcher3.Hotseat
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/hotseat"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:theme="@style/HomeScreenElementTheme"
+ android:importantForAccessibility="no"
+ launcher:containerType="hotseat" />
\ No newline at end of file
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index 6ecc1f5..cca899b 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -39,13 +39,9 @@
launcher:pageIndicator="@+id/page_indicator" />
<!-- DO NOT CHANGE THE ID -->
- <com.android.launcher3.Hotseat
+ <include
android:id="@+id/hotseat"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:theme="@style/HomeScreenElementTheme"
- android:importantForAccessibility="no"
- launcher:containerType="hotseat" />
+ layout="@layout/hotseat" />
<include
android:id="@+id/overview_panel"
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 8291acc..bff7f42 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -46,10 +46,12 @@
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.graphics.IconPalette;
+import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconCache.IconLoadRequest;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
+import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.views.ActivityContext;
@@ -388,7 +390,7 @@
protected void drawDotIfNecessary(Canvas canvas) {
if (!mForceHideDot && (hasDot() || mDotParams.scale > 0)) {
getIconBounds(mDotParams.iconBounds);
- mDotParams.spaceForOffset.set((getWidth() - mIconSize) / 2, getPaddingTop());
+ Utilities.scaleRectAboutCenter(mDotParams.iconBounds, IconShape.getNormalizationScale());
final int scrollX = getScrollX();
final int scrollY = getScrollY();
canvas.translate(scrollX, scrollY);
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index c0affb9..3d2d7cf 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -24,15 +24,13 @@
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.Surface;
-import android.view.View;
import android.view.WindowManager;
import com.android.launcher3.CellLayout.ContainerType;
+import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconNormalizer;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
-
public class DeviceProfile {
public final InvariantDeviceProfile inv;
@@ -240,7 +238,8 @@
updateWorkspacePadding();
// This is done last, after iconSizePx is calculated above.
- mDotRenderer = new DotRenderer(iconSizePx);
+ mDotRenderer = new DotRenderer(iconSizePx, IconShape.getShapePath(),
+ IconShape.DEFAULT_PATH_SIZE);
}
public DeviceProfile copy(Context context) {
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 6fa9ba9..8d9c520 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -36,6 +36,8 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.Alarm;
import com.android.launcher3.AppInfo;
import com.android.launcher3.BubbleTextView;
@@ -50,11 +52,11 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.OnAlarmListener;
import com.android.launcher3.R;
-import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.StylusEventHelper;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
+import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dot.FolderDotInfo;
import com.android.launcher3.dragndrop.BaseItemDragListener;
@@ -68,8 +70,6 @@
import java.util.ArrayList;
import java.util.List;
-import androidx.annotation.NonNull;
-
/**
* An icon that can appear on in the workspace representing an {@link Folder}.
*/
@@ -510,10 +510,11 @@
Rect iconBounds = mDotParams.iconBounds;
BubbleTextView.getIconBounds(this, iconBounds,
mLauncher.getWallpaperDeviceProfile().iconSizePx);
+ float iconScale = (float) mBackground.previewSize / iconBounds.width();
+ Utilities.scaleRectAboutCenter(iconBounds, iconScale);
// If we are animating to the accepting state, animate the dot out.
mDotParams.scale = Math.max(0, mDotScale - mBackground.getScaleProgress());
- mDotParams.spaceForOffset.set(getWidth() - iconBounds.right, iconBounds.top);
mDotParams.color = mBackground.getDotColor();
mDotRenderer.draw(canvas, mDotParams);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index f5c5a8d..87ef044 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -374,16 +374,6 @@
event -> true,
"Pressing Home didn't produce any events");
mDevice.waitForIdle();
-
- // Temporarily press home twice as the first click sometimes gets ignored (b/124239413)
- executeAndWaitForEvent(
- () -> {
- log("LauncherInstrumentation.pressHome before clicking");
- waitForSystemUiObject("home").click();
- },
- event -> true,
- "Pressing Home didn't produce any events");
- mDevice.waitForIdle();
}
try (LauncherInstrumentation.Closable c = addContextLayer(
"performed action to switch to Home - " + action)) {