Snap for 8462842 from 2da9bd5eae to tm-qpr1-release

Change-Id: Icfbb2df2008c8d1c247e7d581524530d368d2c6a
This commit is contained in:
Android Build Coastguard Worker
2022-04-16 05:14:44 +00:00
14 changed files with 260 additions and 288 deletions
-1
View File
@@ -107,7 +107,6 @@ android_library {
"androidx.cardview_cardview",
"com.google.android.material_material",
"iconloader_base",
"modules-utils-build",
],
manifest: "AndroidManifest-common.xml",
sdk_version: "current",
@@ -53,6 +53,7 @@ import java.util.function.Consumer;
public class DepthController implements StateHandler<LauncherState>,
BaseActivity.MultiWindowModeChangedListener {
private static final boolean OVERLAY_SCROLL_ENABLED = false;
public static final FloatProperty<DepthController> DEPTH =
new FloatProperty<DepthController>("depth") {
@Override
@@ -294,6 +295,9 @@ public class DepthController implements StateHandler<LauncherState>,
}
public void onOverlayScrollChanged(float progress) {
if (!OVERLAY_SCROLL_ENABLED) {
return;
}
// Add some padding to the progress, such we don't change the depth on the last frames of
// the animation. It's possible that a user flinging the feed quickly would scroll
// horizontally by accident, causing the device to enter client composition unnecessarily.
@@ -156,14 +156,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
updateIconSize(resources);
mTaskbarHeightForIme = resources.getDimensionPixelSize(R.dimen.taskbar_ime_size);
// Inflate views.
mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
R.layout.taskbar, null, false);
TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
TaskbarScrimView taskbarScrimView = mDragLayer.findViewById(R.id.taskbar_scrim);
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
// Get display and corners first, as views might use them in constructor.
Display display = windowContext.getDisplay();
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
? windowContext.getApplicationContext()
@@ -172,6 +165,14 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
mLeftCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
// Inflate views.
mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
R.layout.taskbar, null, false);
TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
TaskbarScrimView taskbarScrimView = mDragLayer.findViewById(R.id.taskbar_scrim);
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
mAccessibilityDelegate = new TaskbarShortcutMenuAccessibilityDelegate(this);
// Construct controllers.
@@ -0,0 +1,75 @@
/*
* 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.taskbar
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import com.android.launcher3.R
/**
* Helps draw the taskbar background, made up of a rectangle plus two inverted rounded corners.
*/
class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
val paint: Paint = Paint()
var backgroundHeight = context.deviceProfile.taskbarSize.toFloat()
private val leftCornerRadius = context.leftCornerRadius.toFloat()
private val rightCornerRadius = context.rightCornerRadius.toFloat()
private val invertedLeftCornerPath: Path = Path()
private val invertedRightCornerPath: Path = Path()
init {
paint.color = context.getColor(R.color.taskbar_background)
paint.flags = Paint.ANTI_ALIAS_FLAG
paint.style = Paint.Style.FILL
// Create the paths for the inverted rounded corners above the taskbar. Start with a filled
// square, and then subtract out a circle from the appropriate corner.
val square = Path()
square.addRect(0f, 0f, leftCornerRadius, leftCornerRadius, Path.Direction.CW)
val circle = Path()
circle.addCircle(leftCornerRadius, 0f, leftCornerRadius, Path.Direction.CW)
invertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE)
square.reset()
square.addRect(0f, 0f, rightCornerRadius, rightCornerRadius, Path.Direction.CW)
circle.reset()
circle.addCircle(0f, 0f, rightCornerRadius, Path.Direction.CW)
invertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE)
}
/**
* Draws the background with the given paint and height, on the provided canvas.
*/
fun draw(canvas: Canvas) {
canvas.save()
canvas.translate(0f, canvas.height - backgroundHeight)
// Draw the background behind taskbar content.
canvas.drawRect(0f, 0f, canvas.width.toFloat(), backgroundHeight, paint)
// Draw the inverted rounded corners above the taskbar.
canvas.translate(0f, -leftCornerRadius)
canvas.drawPath(invertedLeftCornerPath, paint)
canvas.translate(0f, leftCornerRadius)
canvas.translate(canvas.width - rightCornerRadius, -rightCornerRadius)
canvas.drawPath(invertedRightCornerPath, paint)
canvas.restore()
}
}
@@ -477,7 +477,6 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
tx.setScale(dragSurface, scale, scale);
tx.setAlpha(dragSurface, alpha);
tx.apply();
tx.close();
}
});
mReturnAnimator.addListener(new AnimatorListenerAdapter() {
@@ -498,6 +497,7 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
}
private void cleanUpSurface() {
tx.close();
maybeOnDragEnd();
// Synchronize removing the drag surface with the next draw after calling
// maybeOnDragEnd()
@@ -508,7 +508,6 @@ public class TaskbarDragController extends DragController<BaseTaskbarContext> im
syncer.addToSync(syncId, viewRoot.getView());
syncer.addTransactionToSync(syncId, transaction);
syncer.markSyncReady(syncId);
mReturnAnimator = null;
}
});
@@ -20,8 +20,6 @@ import static android.view.KeyEvent.KEYCODE_BACK;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -31,7 +29,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.R;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.views.BaseDragLayer;
@@ -44,13 +41,11 @@ import com.android.systemui.shared.system.ViewTreeObserverWrapper.OnComputeInset
*/
public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
private final Paint mTaskbarBackgroundPaint;
private final Path mInvertedLeftCornerPath, mInvertedRightCornerPath;
private final TaskbarBackgroundRenderer mBackgroundRenderer;
private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets;
// Initialized in init.
private TaskbarDragLayerController.TaskbarDragLayerCallbacks mControllerCallbacks;
private float mLeftCornerRadius, mRightCornerRadius;
private float mTaskbarBackgroundOffset;
@@ -70,35 +65,13 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
public TaskbarDragLayer(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, 1 /* alphaChannelCount */);
mTaskbarBackgroundPaint = new Paint();
mTaskbarBackgroundPaint.setColor(getResources().getColor(R.color.taskbar_background));
mTaskbarBackgroundPaint.setAlpha(0);
mTaskbarBackgroundPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mTaskbarBackgroundPaint.setStyle(Paint.Style.FILL);
// Will be set in init(), but this ensures they are always non-null.
mInvertedLeftCornerPath = new Path();
mInvertedRightCornerPath = new Path();
mBackgroundRenderer = new TaskbarBackgroundRenderer(mActivity);
mBackgroundRenderer.getPaint().setAlpha(0);
}
public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) {
mControllerCallbacks = callbacks;
// Create the paths for the inverted rounded corners above the taskbar. Start with a filled
// square, and then subtracting out a circle from the appropriate corner.
mLeftCornerRadius = mActivity.getLeftCornerRadius();
mRightCornerRadius = mActivity.getRightCornerRadius();
Path square = new Path();
square.addRect(0, 0, mLeftCornerRadius, mLeftCornerRadius, Path.Direction.CW);
Path circle = new Path();
circle.addCircle(mLeftCornerRadius, 0, mLeftCornerRadius, Path.Direction.CW);
mInvertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE);
square.reset();
square.addRect(0, 0, mRightCornerRadius, mRightCornerRadius, Path.Direction.CW);
circle.reset();
circle.addCircle(0, 0, mRightCornerRadius, Path.Direction.CW);
mInvertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE);
recreateControllers();
}
@@ -151,20 +124,8 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
protected void dispatchDraw(Canvas canvas) {
float backgroundHeight = mControllerCallbacks.getTaskbarBackgroundHeight()
* (1f - mTaskbarBackgroundOffset);
canvas.save();
canvas.translate(0, canvas.getHeight() - backgroundHeight);
// Draw the background behind taskbar content.
canvas.drawRect(0, 0, canvas.getWidth(), backgroundHeight, mTaskbarBackgroundPaint);
// Draw the inverted rounded corners above the taskbar.
canvas.translate(0, -mLeftCornerRadius);
canvas.drawPath(mInvertedLeftCornerPath, mTaskbarBackgroundPaint);
canvas.translate(0, mLeftCornerRadius);
canvas.translate(canvas.getWidth() - mRightCornerRadius, -mRightCornerRadius);
canvas.drawPath(mInvertedRightCornerPath, mTaskbarBackgroundPaint);
canvas.restore();
mBackgroundRenderer.setBackgroundHeight(backgroundHeight);
mBackgroundRenderer.draw(canvas);
super.dispatchDraw(canvas);
}
@@ -173,7 +134,7 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
* @param alpha 0 is fully transparent, 1 is fully opaque.
*/
protected void setTaskbarBackgroundAlpha(float alpha) {
mTaskbarBackgroundPaint.setAlpha((int) (alpha * 255));
mBackgroundRenderer.getPaint().setAlpha((int) (alpha * 255));
invalidate();
}
@@ -17,22 +17,19 @@ package com.android.launcher3.taskbar;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import com.android.launcher3.views.ActivityContext;
/**
* View that handles scrimming the taskbar and the inverted corners it draws. The scrim is used
* when bubbles is expanded.
*/
public class TaskbarScrimView extends View {
private final Paint mTaskbarScrimPaint;
private final Path mInvertedLeftCornerPath, mInvertedRightCornerPath;
private final TaskbarBackgroundRenderer mRenderer;
private boolean mShowScrim;
private float mLeftCornerRadius, mRightCornerRadius;
private float mBackgroundHeight;
public TaskbarScrimView(Context context) {
this(context, null);
@@ -49,14 +46,9 @@ public class TaskbarScrimView extends View {
public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mTaskbarScrimPaint = new Paint();
mTaskbarScrimPaint.setColor(getResources().getColor(android.R.color.system_neutral1_1000));
mTaskbarScrimPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mTaskbarScrimPaint.setStyle(Paint.Style.FILL);
mInvertedLeftCornerPath = new Path();
mInvertedRightCornerPath = new Path();
mRenderer = new TaskbarBackgroundRenderer(ActivityContext.lookupContext(context));
mRenderer.getPaint().setColor(getResources().getColor(
android.R.color.system_neutral1_1000));
}
@Override
@@ -64,31 +56,7 @@ public class TaskbarScrimView extends View {
super.onDraw(canvas);
if (mShowScrim) {
canvas.save();
canvas.translate(0, canvas.getHeight() - mBackgroundHeight);
// Scrim the taskbar itself.
canvas.drawRect(0, 0, canvas.getWidth(), mBackgroundHeight, mTaskbarScrimPaint);
// Scrim the inverted rounded corners above the taskbar.
canvas.translate(0, -mLeftCornerRadius);
canvas.drawPath(mInvertedLeftCornerPath, mTaskbarScrimPaint);
canvas.translate(0, mLeftCornerRadius);
canvas.translate(canvas.getWidth() - mRightCornerRadius, -mRightCornerRadius);
canvas.drawPath(mInvertedRightCornerPath, mTaskbarScrimPaint);
canvas.restore();
}
}
/**
* Sets the height of the taskbar background.
* @param height the height of the background.
*/
protected void setBackgroundHeight(float height) {
mBackgroundHeight = height;
if (mShowScrim) {
invalidate();
mRenderer.draw(canvas);
}
}
@@ -98,32 +66,7 @@ public class TaskbarScrimView extends View {
*/
protected void setScrimAlpha(float alpha) {
mShowScrim = alpha > 0f;
mTaskbarScrimPaint.setAlpha((int) (alpha * 255));
mRenderer.getPaint().setAlpha((int) (alpha * 255));
invalidate();
}
/**
* Sets the radius of the left and right corners above the taskbar.
* @param leftCornerRadius the radius of the left corner.
* @param rightCornerRadius the radius of the right corner.
*/
protected void setCornerSizes(float leftCornerRadius, float rightCornerRadius) {
mLeftCornerRadius = leftCornerRadius;
mRightCornerRadius = rightCornerRadius;
Path square = new Path();
square.addRect(0, 0, mLeftCornerRadius, mLeftCornerRadius, Path.Direction.CW);
Path circle = new Path();
circle.addCircle(mLeftCornerRadius, 0, mLeftCornerRadius, Path.Direction.CW);
mInvertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE);
square.reset();
square.addRect(0, 0, mRightCornerRadius, mRightCornerRadius, Path.Direction.CW);
circle.reset();
circle.addCircle(0, 0, mRightCornerRadius, Path.Direction.CW);
mInvertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE);
if (mShowScrim) {
invalidate();
}
}
}
@@ -49,9 +49,6 @@ public class TaskbarScrimViewController implements TaskbarControllers.LoggableTa
public TaskbarScrimViewController(TaskbarActivityContext activity, TaskbarScrimView scrimView) {
mActivity = activity;
mScrimView = scrimView;
mScrimView.setCornerSizes(mActivity.getLeftCornerRadius(),
mActivity.getRightCornerRadius());
mScrimView.setBackgroundHeight(mActivity.getDeviceProfile().taskbarSize);
}
/**
@@ -106,6 +106,7 @@ import android.view.animation.Interpolator;
import android.widget.ListView;
import android.widget.OverScroller;
import android.widget.Toast;
import android.window.PictureInPictureSurfaceTransaction;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -161,6 +162,7 @@ import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.ViewUtils;
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.LauncherSplitScreenListener;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitScreenBounds;
@@ -4507,6 +4509,18 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
final SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(getContext());
systemUiProxy.notifySwipeToHomeFinished();
systemUiProxy.setShelfHeight(true, mActivity.getDeviceProfile().hotseatBarSizePx);
// Transaction to hide the task to avoid flicker for entering PiP from split-screen.
// See also {@link AbsSwipeUpHandler#maybeFinishSwipeToHome}.
PictureInPictureSurfaceTransaction tx =
new PictureInPictureSurfaceTransaction.Builder()
.setAlpha(0f)
.build();
int[] taskIds =
LauncherSplitScreenListener.INSTANCE.getNoCreate().getRunningSplitTaskIds();
for (int taskId : taskIds) {
mRecentsAnimationController.setFinishTaskTransaction(taskId,
tx, null /* overlay */);
}
}
mRecentsAnimationController.finish(toRecents, () -> {
if (onFinishComplete != null) {
+10 -4
View File
@@ -53,6 +53,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Message;
@@ -72,6 +73,7 @@ import android.view.ViewConfiguration;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
import androidx.annotation.ChecksSdkIntAtLeast;
import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
@@ -93,7 +95,6 @@ import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.modules.utils.build.SdkLevel;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -122,15 +123,20 @@ public final class Utilities {
public static final String[] EMPTY_STRING_ARRAY = new String[0];
public static final Person[] EMPTY_PERSON_ARRAY = new Person[0];
@ChecksSdkIntAtLeast(api = VERSION_CODES.P)
public static final boolean ATLEAST_P = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
@ChecksSdkIntAtLeast(api = VERSION_CODES.Q)
public static final boolean ATLEAST_Q = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
public static final boolean ATLEAST_R = SdkLevel.isAtLeastR();
@ChecksSdkIntAtLeast(api = VERSION_CODES.R)
public static final boolean ATLEAST_R = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
public static final boolean ATLEAST_S = SdkLevel.isAtLeastS();
@ChecksSdkIntAtLeast(api = VERSION_CODES.S)
public static final boolean ATLEAST_S = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
public static final boolean ATLEAST_T = SdkLevel.isAtLeastT();
@ChecksSdkIntAtLeast(api = VERSION_CODES.TIRAMISU, codename = "T")
public static final boolean ATLEAST_T = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
/**
* Set on a motion event dispatched from the nav bar. See {@link MotionEvent#setEdgeFlags(int)}.
@@ -20,9 +20,13 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Picture;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
@@ -31,10 +35,11 @@ import android.os.Build;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.Utilities;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.graphics.ShiftedBitmapDrawable;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.views.ActivityContext;
@@ -69,79 +74,104 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
return mBadge;
}
@TargetApi(Build.VERSION_CODES.P)
public static @Nullable FolderAdaptiveIcon createFolderAdaptiveIcon(
ActivityContext activity, int folderId, Point dragViewSize) {
ActivityContext activity, int folderId, Point size) {
Preconditions.assertNonUiThread();
if (!Utilities.ATLEAST_P) {
return null;
}
// Create the actual drawable on the UI thread to avoid race conditions with
// assume square
if (size.x != size.y) {
return null;
}
int requestedSize = size.x;
// Only use the size actually needed for drawing the folder icon
int drawingSize = activity.getDeviceProfile().folderIconSizePx;
int foregroundSize = Math.max(requestedSize, drawingSize);
float shift = foregroundSize - requestedSize;
Picture background = new Picture();
Picture foreground = new Picture();
Picture badge = new Picture();
Canvas bgCanvas = background.beginRecording(requestedSize, requestedSize);
Canvas badgeCanvas = badge.beginRecording(requestedSize, requestedSize);
Canvas fgCanvas = foreground.beginRecording(foregroundSize, foregroundSize);
fgCanvas.translate(shift, shift);
// Do not clip the folder drawing since the icon previews extend outside the background.
Path mask = new Path();
mask.addRect(-shift, -shift, requestedSize + shift, requestedSize + shift,
Direction.CCW);
// Initialize the actual draw commands on the UI thread to avoid race conditions with
// FolderIcon draw pass
try {
return MAIN_EXECUTOR.submit(() -> {
MAIN_EXECUTOR.submit(() -> {
FolderIcon icon = activity.findFolderIcon(folderId);
return icon == null ? null : createDrawableOnUiThread(icon, dragViewSize);
if (icon == null) {
throw new IllegalArgumentException("Folder not found with id: " + folderId);
}
initLayersOnUiThread(icon, requestedSize, bgCanvas, fgCanvas, badgeCanvas);
}).get();
} catch (Exception e) {
Log.e(TAG, "Unable to create folder icon", e);
return null;
} finally {
background.endRecording();
foreground.endRecording();
badge.endRecording();
}
// Only convert foreground to a bitmap as it can contain multiple draw commands. Other
// layers either draw a nothing or a single draw call.
Bitmap fgBitmap = Bitmap.createBitmap(foreground);
Paint foregroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// Do not use PictureDrawable as it moves the picture to the canvas bounds, whereas we want
// to draw it at (0,0)
return new FolderAdaptiveIcon(
new BitmapRendererDrawable(c -> c.drawPicture(background)),
new BitmapRendererDrawable(
c -> c.drawBitmap(fgBitmap, -shift, -shift, foregroundPaint)),
new BitmapRendererDrawable(c -> c.drawPicture(badge)),
mask);
}
private static FolderAdaptiveIcon createDrawableOnUiThread(FolderIcon icon,
Point dragViewSize) {
Preconditions.assertUIThread();
@UiThread
private static void initLayersOnUiThread(FolderIcon icon, int size,
Canvas backgroundCanvas, Canvas foregroundCanvas, Canvas badgeCanvas) {
icon.getPreviewBounds(sTmpRect);
PreviewBackground bg = icon.getFolderBackground();
// assume square
assert (dragViewSize.x == dragViewSize.y);
final int previewSize = sTmpRect.width();
final int margin = (dragViewSize.x - previewSize) / 2;
PreviewBackground bg = icon.getFolderBackground();
final int margin = (size - previewSize) / 2;
final float previewShiftX = -sTmpRect.left + margin;
final float previewShiftY = -sTmpRect.top + margin;
// Initialize badge, which consists of the outline stroke, shadow and dot; these
// must be rendered above the foreground
Bitmap badgeBmp = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
(canvas) -> {
canvas.save();
canvas.translate(previewShiftX, previewShiftY);
bg.drawShadow(canvas);
bg.drawBackgroundStroke(canvas);
icon.drawDot(canvas);
canvas.restore();
});
badgeCanvas.save();
badgeCanvas.translate(previewShiftX, previewShiftY);
icon.drawDot(badgeCanvas);
badgeCanvas.restore();
// Initialize mask
Path mask = new Path();
Matrix m = new Matrix();
m.setTranslate(previewShiftX, previewShiftY);
bg.getClipPath().transform(m, mask);
// Draw foreground
foregroundCanvas.save();
foregroundCanvas.translate(previewShiftX, previewShiftY);
icon.getPreviewItemManager().draw(foregroundCanvas);
foregroundCanvas.restore();
Bitmap previewBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
(canvas) -> {
canvas.save();
canvas.translate(previewShiftX, previewShiftY);
icon.getPreviewItemManager().draw(canvas);
canvas.restore();
});
Bitmap bgBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
(canvas) -> {
Paint p = new Paint();
p.setColor(bg.getBgColor());
canvas.drawCircle(dragViewSize.x / 2f, dragViewSize.y / 2f, bg.getRadius(), p);
});
ShiftedBitmapDrawable badge = new ShiftedBitmapDrawable(badgeBmp, 0, 0);
ShiftedBitmapDrawable foreground = new ShiftedBitmapDrawable(previewBitmap, 0, 0);
ShiftedBitmapDrawable background = new ShiftedBitmapDrawable(bgBitmap, 0, 0);
return new FolderAdaptiveIcon(background, foreground, badge, mask);
// Draw background
Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
backgroundPaint.setColor(bg.getBgColor());
bg.drawShadow(backgroundCanvas);
backgroundCanvas.drawCircle(size / 2f, size / 2f, bg.getRadius(), backgroundPaint);
bg.drawBackgroundStroke(backgroundCanvas);
}
@Override
@@ -174,4 +204,52 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
& mBadge.getChangingConfigurations();
}
}
private static class BitmapRendererDrawable extends Drawable {
private final BitmapRenderer mRenderer;
BitmapRendererDrawable(BitmapRenderer renderer) {
mRenderer = renderer;
}
@Override
public void draw(Canvas canvas) {
mRenderer.draw(canvas);
}
@Override
public void setAlpha(int i) { }
@Override
public void setColorFilter(ColorFilter colorFilter) { }
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public ConstantState getConstantState() {
return new MyConstantState(mRenderer);
}
private static class MyConstantState extends ConstantState {
private final BitmapRenderer mRenderer;
MyConstantState(BitmapRenderer renderer) {
mRenderer = renderer;
}
@Override
public Drawable newDrawable() {
return new BitmapRendererDrawable(mRenderer);
}
@Override
public int getChangingConfigurations() {
return 0;
}
}
}
}
@@ -1,105 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.graphics;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
/**
* A simple drawable which draws a bitmap at a fixed position irrespective of the bounds
*/
public class ShiftedBitmapDrawable extends Drawable {
private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
private final Bitmap mBitmap;
private float mShiftX;
private float mShiftY;
private final ConstantState mConstantState;
public ShiftedBitmapDrawable(Bitmap bitmap, float shiftX, float shiftY) {
mBitmap = bitmap;
mShiftX = shiftX;
mShiftY = shiftY;
mConstantState = new MyConstantState(mBitmap, mShiftX, mShiftY);
}
public float getShiftX() {
return mShiftX;
}
public float getShiftY() {
return mShiftY;
}
public void setShiftX(float shiftX) {
mShiftX = shiftX;
}
public void setShiftY(float shiftY) {
mShiftY = shiftY;
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, mShiftX, mShiftY, mPaint);
}
@Override
public void setAlpha(int i) { }
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public ConstantState getConstantState() {
return mConstantState;
}
private static class MyConstantState extends ConstantState {
private final Bitmap mBitmap;
private float mShiftX;
private float mShiftY;
MyConstantState(Bitmap bitmap, float shiftX, float shiftY) {
mBitmap = bitmap;
mShiftX = shiftX;
mShiftY = shiftY;
}
@Override
public Drawable newDrawable() {
return new ShiftedBitmapDrawable(mBitmap, mShiftX, mShiftY);
}
@Override
public int getChangingConfigurations() {
return 0;
}
}
}
@@ -16,6 +16,7 @@
package com.android.launcher3.model;
import android.annotation.SuppressLint;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.Build;
@@ -215,6 +216,7 @@ public class StringCache {
context, DISABLED_BY_ADMIN_MESSAGE, R.string.msg_disabled_by_admin);
}
@SuppressLint("NewApi")
private String getEnterpriseString(
Context context, String updatableStringId, int defaultStringId) {
return Utilities.ATLEAST_T
@@ -49,7 +49,6 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.FastBitmapDrawable;
@@ -413,8 +412,7 @@ public class FloatingIconView extends FrameLayout implements
@WorkerThread
@SuppressWarnings("WrongThread")
private static int getOffsetForIconBounds(Launcher l, Drawable drawable, RectF position) {
if (!(drawable instanceof AdaptiveIconDrawable)
|| (drawable instanceof FolderAdaptiveIcon)) {
if (!(drawable instanceof AdaptiveIconDrawable)) {
return 0;
}
int blurSizeOutline =