Merge "Support sysUiStatusNavFlags for refactored TTV" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index 9df0576..fab7975 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -801,7 +801,6 @@
listener);
}
- // TODO: (b/280605790) animate it
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
super.addView(child, index, params);
diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java
deleted file mode 100644
index bb4a7ec..0000000
--- a/quickstep/src/com/android/quickstep/views/IconView.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2018 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.quickstep.views;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.views.ActivityContext;
-import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
-import com.android.quickstep.util.RecentsOrientedState;
-
-/**
- * A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
- * when the drawable changes.
- */
-public class IconView extends View implements TaskViewIcon {
- private static final int NUM_ALPHA_CHANNELS = 2;
- private static final int INDEX_CONTENT_ALPHA = 0;
- private static final int INDEX_MODAL_ALPHA = 1;
-
- private final MultiValueAlpha mMultiValueAlpha;
-
- @Nullable
- private Drawable mDrawable;
- private int mDrawableWidth, mDrawableHeight;
-
- public IconView(Context context) {
- this(context, null);
- }
-
- public IconView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public IconView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public IconView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mMultiValueAlpha = new MultiValueAlpha(this, NUM_ALPHA_CHANNELS);
- mMultiValueAlpha.setUpdateVisibility(/* updateVisibility= */ true);
- }
-
- /**
- * Sets a {@link Drawable} to be displayed.
- */
- @Override
- public void setDrawable(@Nullable Drawable d) {
- if (mDrawable != null) {
- mDrawable.setCallback(null);
- }
- mDrawable = d;
- if (mDrawable != null) {
- mDrawable.setCallback(this);
- setDrawableSizeInternal(getWidth(), getHeight());
- }
- invalidate();
- }
-
- /**
- * Sets the size of the icon drawable.
- */
- @Override
- public void setDrawableSize(int iconWidth, int iconHeight) {
- mDrawableWidth = iconWidth;
- mDrawableHeight = iconHeight;
- if (mDrawable != null) {
- setDrawableSizeInternal(getWidth(), getHeight());
- }
- }
-
- private void setDrawableSizeInternal(int selfWidth, int selfHeight) {
- Rect selfRect = new Rect(0, 0, selfWidth, selfHeight);
- Rect drawableRect = new Rect();
- Gravity.apply(Gravity.CENTER, mDrawableWidth, mDrawableHeight, selfRect, drawableRect);
- mDrawable.setBounds(drawableRect);
- }
-
- @Override
- @Nullable
- public Drawable getDrawable() {
- return mDrawable;
- }
-
- @Override
- public int getDrawableWidth() {
- return mDrawableWidth;
- }
-
- @Override
- public int getDrawableHeight() {
- return mDrawableHeight;
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- if (mDrawable != null) {
- setDrawableSizeInternal(w, h);
- }
- }
-
- @Override
- protected boolean verifyDrawable(Drawable who) {
- return super.verifyDrawable(who) || who == mDrawable;
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
-
- final Drawable drawable = mDrawable;
- if (drawable != null && drawable.isStateful()
- && drawable.setState(getDrawableState())) {
- invalidateDrawable(drawable);
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (mDrawable != null) {
- mDrawable.draw(canvas);
- }
- }
-
- @Override
- public boolean hasOverlappingRendering() {
- return false;
- }
-
- @Override
- public void setContentAlpha(float alpha) {
- mMultiValueAlpha.get(INDEX_CONTENT_ALPHA).setValue(alpha);
- }
-
- @Override
- public void setModalAlpha(float alpha) {
- mMultiValueAlpha.get(INDEX_MODAL_ALPHA).setValue(alpha);
- }
-
- /**
- * Set the tint color of the icon, useful for scrimming or dimming.
- *
- * @param color to blend in.
- * @param amount [0,1] 0 no tint, 1 full tint
- */
- @Override
- public void setIconColorTint(int color, float amount) {
- if (mDrawable != null) {
- mDrawable.setColorFilter(Utilities.makeColorTintingColorFilter(color, amount));
- }
- }
-
- @Override
- public void setIconOrientation(RecentsOrientedState orientationState, boolean isGridTask) {
- RecentsPagedOrientationHandler orientationHandler =
- orientationState.getOrientationHandler();
- boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
- DeviceProfile deviceProfile =
- ActivityContext.lookupContext(getContext()).getDeviceProfile();
-
- FrameLayout.LayoutParams iconParams = (FrameLayout.LayoutParams) getLayoutParams();
-
- int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
- int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
- int taskMargin = deviceProfile.overviewTaskMarginPx;
-
- orientationHandler.setTaskIconParams(iconParams, taskMargin, taskIconHeight,
- thumbnailTopMargin, isRtl);
- iconParams.width = iconParams.height = taskIconHeight;
- setLayoutParams(iconParams);
-
- setRotation(orientationHandler.getDegreesRotated());
- int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
- : deviceProfile.overviewTaskIconDrawableSizePx;
- setDrawableSize(iconDrawableSize, iconDrawableSize);
- }
-
- @Override
- public View asView() {
- return this;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/IconView.kt b/quickstep/src/com/android/quickstep/views/IconView.kt
new file mode 100644
index 0000000..583207f
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/IconView.kt
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2018 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.quickstep.views
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.graphics.drawable.Drawable
+import android.util.AttributeSet
+import android.view.Gravity
+import android.view.View
+import android.widget.FrameLayout
+import androidx.core.view.updateLayoutParams
+import com.android.launcher3.DeviceProfile
+import com.android.launcher3.Utilities
+import com.android.launcher3.util.MultiValueAlpha
+import com.android.launcher3.views.ActivityContext
+import com.android.quickstep.util.RecentsOrientedState
+
+/**
+ * A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
+ * when the drawable changes.
+ */
+class IconView : View, TaskViewIcon {
+ private val multiValueAlpha: MultiValueAlpha = MultiValueAlpha(this, NUM_ALPHA_CHANNELS)
+ private var drawable: Drawable? = null
+ private var drawableWidth = 0
+ private var drawableHeight = 0
+
+ constructor(context: Context) : super(context)
+
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
+
+ constructor(
+ context: Context,
+ attrs: AttributeSet?,
+ defStyleAttr: Int,
+ ) : super(context, attrs, defStyleAttr)
+
+ init {
+ multiValueAlpha.setUpdateVisibility(true)
+ }
+
+ /** Sets a [Drawable] to be displayed. */
+ override fun setDrawable(d: Drawable?) {
+ drawable?.callback = null
+
+ drawable = d
+ drawable?.let {
+ it.callback = this
+ setDrawableSizeInternal(width, height)
+ }
+ invalidate()
+ }
+
+ /** Sets the size of the icon drawable. */
+ override fun setDrawableSize(iconWidth: Int, iconHeight: Int) {
+ drawableWidth = iconWidth
+ drawableHeight = iconHeight
+ drawable?.let { setDrawableSizeInternal(width, height) }
+ }
+
+ private fun setDrawableSizeInternal(selfWidth: Int, selfHeight: Int) {
+ val selfRect = Rect(0, 0, selfWidth, selfHeight)
+ val drawableRect = Rect()
+ Gravity.apply(Gravity.CENTER, drawableWidth, drawableHeight, selfRect, drawableRect)
+ drawable?.bounds = drawableRect
+ }
+
+ override fun getDrawable(): Drawable? = drawable
+
+ override fun getDrawableWidth(): Int = drawableWidth
+
+ override fun getDrawableHeight(): Int = drawableHeight
+
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
+ super.onSizeChanged(w, h, oldw, oldh)
+ drawable?.let { setDrawableSizeInternal(w, h) }
+ }
+
+ override fun verifyDrawable(who: Drawable): Boolean =
+ super.verifyDrawable(who) || who === drawable
+
+ override fun drawableStateChanged() {
+ super.drawableStateChanged()
+ drawable?.let {
+ if (it.isStateful && it.setState(drawableState)) {
+ invalidateDrawable(it)
+ }
+ }
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ drawable?.draw(canvas)
+ }
+
+ override fun hasOverlappingRendering(): Boolean = false
+
+ override fun setContentAlpha(alpha: Float) {
+ multiValueAlpha[INDEX_CONTENT_ALPHA].setValue(alpha)
+ }
+
+ override fun setModalAlpha(alpha: Float) {
+ multiValueAlpha[INDEX_MODAL_ALPHA].setValue(alpha)
+ }
+
+ /**
+ * Set the tint color of the icon, useful for scrimming or dimming.
+ *
+ * @param color to blend in.
+ * @param amount [0,1] 0 no tint, 1 full tint
+ */
+ override fun setIconColorTint(color: Int, amount: Float) {
+ drawable?.colorFilter = Utilities.makeColorTintingColorFilter(color, amount)
+ }
+
+ override fun setIconOrientation(orientationState: RecentsOrientedState, isGridTask: Boolean) {
+ val orientationHandler = orientationState.orientationHandler
+ val deviceProfile: DeviceProfile =
+ (ActivityContext.lookupContext(context) as ActivityContext).getDeviceProfile()
+ orientationHandler.setTaskIconParams(
+ iconParams = getLayoutParams() as FrameLayout.LayoutParams,
+ taskIconMargin = deviceProfile.overviewTaskMarginPx,
+ taskIconHeight = deviceProfile.overviewTaskIconSizePx,
+ thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx,
+ isRtl = layoutDirection == LAYOUT_DIRECTION_RTL
+ )
+ updateLayoutParams<FrameLayout.LayoutParams> {
+ height = deviceProfile.overviewTaskIconSizePx
+ width = height
+ }
+ setRotation(orientationHandler.degreesRotated)
+ val iconDrawableSize =
+ if (isGridTask) deviceProfile.overviewTaskIconDrawableSizeGridPx
+ else deviceProfile.overviewTaskIconDrawableSizePx
+ setDrawableSize(iconDrawableSize, iconDrawableSize)
+ }
+
+ override fun asView(): View = this
+
+ companion object {
+ private const val NUM_ALPHA_CHANNELS = 2
+ private const val INDEX_CONTENT_ALPHA = 0
+ private const val INDEX_MODAL_ALPHA = 1
+ }
+}
diff --git a/src/com/android/launcher3/util/ShortcutUtil.java b/src/com/android/launcher3/util/ShortcutUtil.java
index 07b7941..aa4f8af 100644
--- a/src/com/android/launcher3/util/ShortcutUtil.java
+++ b/src/com/android/launcher3/util/ShortcutUtil.java
@@ -54,14 +54,6 @@
? ((WorkspaceItemInfo) info).getPersonKeys() : Utilities.EMPTY_STRING_ARRAY;
}
- /**
- * Returns true if the item is a deep shortcut.
- */
- public static boolean isDeepShortcut(ItemInfo info) {
- return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
- && info instanceof WorkspaceItemInfo;
- }
-
private static boolean isActive(ItemInfo info) {
boolean isLoading = info instanceof WorkspaceItemInfo
&& ((WorkspaceItemInfo) info).hasPromiseIconUi();
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/ShortcutUtilTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/ShortcutUtilTest.kt
new file mode 100644
index 0000000..c43e563
--- /dev/null
+++ b/tests/multivalentTests/src/com/android/launcher3/util/ShortcutUtilTest.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 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 androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.Utilities
+import com.android.launcher3.model.data.WorkspaceItemInfo
+import org.junit.Assert.assertArrayEquals
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShortcutUtilTest {
+
+ @Test
+ fun `supportsShortcuts returns true if the item is active and it is an app`() {
+ // A blank workspace item info should be active and should be ITEM_TYPE_APPLICATION
+ val itemInfo = WorkspaceItemInfo()
+ // Action
+ val result = ShortcutUtil.supportsShortcuts(itemInfo)
+ // Verify
+ assertEquals(true, result)
+ }
+
+ @Test
+ fun `supportsDeepShortcuts returns true if the app is active and an app and widgets are enabled`() {
+ // Setup
+ val itemInfo = WorkspaceItemInfo()
+ // Action
+ val result = ShortcutUtil.supportsDeepShortcuts(itemInfo)
+ // Verify
+ assertEquals(true, result)
+ }
+
+ @Test
+ fun `getShortcutIdIfPinnedShortcut returns null if the item is an app`() {
+ // Setup
+ val itemInfo = WorkspaceItemInfo()
+ // Action
+ val result = ShortcutUtil.getShortcutIdIfPinnedShortcut(itemInfo)
+ // Verify
+ assertNull(result)
+ }
+
+ @Test
+ fun `getPersonKeysIfPinnedShortcut returns empty string array if item type is an app`() {
+ // Setup
+ val itemInfo = WorkspaceItemInfo()
+ // Action
+ val result = ShortcutUtil.getPersonKeysIfPinnedShortcut(itemInfo)
+ // Verify
+ assertArrayEquals(Utilities.EMPTY_STRING_ARRAY, result)
+ }
+}