Merge "Show and hide taskbar tooltips immediately." into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 258e920..a36d5f0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -286,9 +286,10 @@
RemovedBubble removedBubble = update.removedBubbles.get(0);
BubbleBarBubble bubbleToRemove = mBubbles.remove(removedBubble.getKey());
mBubbles.put(update.addedBubble.getKey(), update.addedBubble);
+ boolean showOverflow = update.showOverflowChanged && update.showOverflow;
if (bubbleToRemove != null) {
mBubbleBarViewController.addBubbleAndRemoveBubble(update.addedBubble,
- bubbleToRemove, isExpanding, suppressAnimation);
+ bubbleToRemove, isExpanding, suppressAnimation, showOverflow);
} else {
mBubbleBarViewController.addBubble(update.addedBubble, isExpanding,
suppressAnimation);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index d911fd4..ffab936 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -758,7 +758,8 @@
}
/** Add a new bubble and remove an old bubble from the bubble bar. */
- public void addBubbleAndRemoveBubble(BubbleView addedBubble, BubbleView removedBubble) {
+ public void addBubbleAndRemoveBubble(BubbleView addedBubble, BubbleView removedBubble,
+ Runnable onEndRunnable) {
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams((int) mIconSize, (int) mIconSize,
Gravity.LEFT);
boolean isOverflowSelected = mSelectedBubbleView.isOverflow();
@@ -792,6 +793,9 @@
removeView(removedBubble);
updateWidth();
mBubbleAnimator = null;
+ if (onEndRunnable != null) {
+ onEndRunnable.run();
+ }
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 3261262..4fe4ace 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -496,8 +496,10 @@
/** Adds a new bubble and removes an old bubble at the same time. */
public void addBubbleAndRemoveBubble(BubbleBarBubble addedBubble,
- BubbleBarBubble removedBubble, boolean isExpanding, boolean suppressAnimation) {
- mBarView.addBubbleAndRemoveBubble(addedBubble.getView(), removedBubble.getView());
+ BubbleBarBubble removedBubble, boolean isExpanding, boolean suppressAnimation,
+ boolean addOverflowToo) {
+ mBarView.addBubbleAndRemoveBubble(addedBubble.getView(), removedBubble.getView(),
+ addOverflowToo ? () -> showOverflow(true) : null);
addedBubble.getView().setOnClickListener(mBubbleClickListener);
addedBubble.getView().setController(mBubbleViewController);
removedBubble.getView().setController(null);
@@ -531,7 +533,8 @@
public void addOverflowAndRemoveBubble(BubbleBarBubble removedBubble) {
if (mOverflowAdded) return;
mOverflowAdded = true;
- mBarView.addBubbleAndRemoveBubble(mOverflowBubble.getView(), removedBubble.getView());
+ mBarView.addBubbleAndRemoveBubble(mOverflowBubble.getView(), removedBubble.getView(),
+ null /* onEndRunnable */);
mOverflowBubble.getView().setOnClickListener(mBubbleClickListener);
mOverflowBubble.getView().setController(mBubbleViewController);
removedBubble.getView().setController(null);
@@ -541,7 +544,8 @@
public void removeOverflowAndAddBubble(BubbleBarBubble addedBubble) {
if (!mOverflowAdded) return;
mOverflowAdded = false;
- mBarView.addBubbleAndRemoveBubble(addedBubble.getView(), mOverflowBubble.getView());
+ mBarView.addBubbleAndRemoveBubble(addedBubble.getView(), mOverflowBubble.getView(),
+ null /* onEndRunnable */);
addedBubble.getView().setOnClickListener(mBubbleClickListener);
addedBubble.getView().setController(mBubbleViewController);
mOverflowBubble.getView().setController(null);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 6c706be..fac372b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2708,6 +2708,10 @@
mWidgetPickerDataProvider.dump(prefix, writer);
mDeviceProfile.dump(this, prefix, writer);
mAppsView.getAppsStore().dump(prefix, writer);
+ mAppsView.getPersonalAppList().dump(prefix, writer);
+ if (mAppsView.shouldShowTabs()) {
+ mAppsView.getWorkAppList().dump(prefix, writer);
+ }
try {
FileLog.flushAll(writer);
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index ad660d2..227ac2b 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.Flags.enableExpandingPauseWorkButton;
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
+import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.WORK;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
@@ -1313,6 +1314,10 @@
return mAH.get(MAIN).mAppsList;
}
+ public AlphabeticalAppsList<T> getWorkAppList() {
+ return mAH.get(WORK).mAppsList;
+ }
+
public FloatingHeaderView getFloatingHeaderView() {
return mHeader;
}
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index a3cabc2..6dd811a 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -26,6 +26,7 @@
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
+import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -39,6 +40,7 @@
import com.android.launcher3.util.LabelComparator;
import com.android.launcher3.views.ActivityContext;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -270,6 +272,7 @@
List<AdapterItem> oldItems = new ArrayList<>(mAdapterItems);
// Prepare to update the list of sections, filtered apps, etc.
mFastScrollerSections.clear();
+ Log.d(TAG, "Clearing FastScrollerSections.");
mAdapterItems.clear();
mAccessibilityResultsCount = 0;
@@ -290,6 +293,7 @@
mFastScrollerSections.add(new FastScrollSectionInfo(
mActivityContext.getResources().getString(
R.string.work_profile_edu_section), 0));
+ Log.d(TAG, "Adding FastScrollSection for work edu card.");
}
position = addAppsWithSections(mApps, position);
}
@@ -303,6 +307,7 @@
mFastScrollerSections.add(new FastScrollSectionInfo(
mFastScrollerSections.get(mFastScrollerSections.size() - 1).sectionName,
position++));
+ Log.d(TAG, "Adding FastScrollSection duplicate to scroll to the bottom.");
}
}
mAccessibilityResultsCount = (int) mAdapterItems.stream()
@@ -346,6 +351,7 @@
&& !mPrivateApps.isEmpty()) {
// Always add PS Header if Space is present and visible.
position = mPrivateProviderManager.addPrivateSpaceHeader(mAdapterItems);
+ Log.d(TAG, "Adding FastScrollSection for Private Space header. ");
mFastScrollerSections.add(new FastScrollSectionInfo(
mPrivateProfileAppScrollerBadge, position));
int privateSpaceState = mPrivateProviderManager.getCurrentState();
@@ -407,6 +413,7 @@
hasPrivateApps = appList.stream().
allMatch(mPrivateProviderManager.getItemInfoMatcher());
}
+ Log.d(TAG, "Adding apps with sections. HasPrivateApps: " + hasPrivateApps);
for (int i = 0; i < appList.size(); i++) {
AppInfo info = appList.get(i);
// Apply decorator to private apps.
@@ -421,6 +428,8 @@
String sectionName = info.sectionName;
// Create a new section if the section names do not match
if (!sectionName.equals(lastSectionName)) {
+ Log.d(TAG, "addAppsWithSections: adding sectionName: " + sectionName
+ + " with appInfoTitle: " + info.title);
lastSectionName = sectionName;
mFastScrollerSections.add(new FastScrollSectionInfo(hasPrivateApps ?
mPrivateProfileAppScrollerBadge : sectionName, position));
@@ -471,6 +480,13 @@
return mPrivateProviderManager;
}
+ public void dump(String prefix, PrintWriter writer) {
+ writer.println(prefix + "SectionInfo[] size: " + mFastScrollerSections.size());
+ for (int i = 0; i < mFastScrollerSections.size(); i++) {
+ writer.println("\tFastScrollSection: " + mFastScrollerSections.get(i).sectionName);
+ }
+ }
+
private static class MyDiffCallback extends DiffUtil.Callback {
private final List<AdapterItem> mOldList;
diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
index 4f8d53e..d593f80 100644
--- a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
+++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
@@ -3,6 +3,7 @@
import android.content.Context;
import android.icu.text.AlphabeticIndex;
import android.os.LocaleList;
+import android.util.Log;
import androidx.annotation.NonNull;
@@ -12,6 +13,9 @@
public class AlphabeticIndexCompat {
+ // TODO(b/336947811): Set to false after root causing is done.
+ private static final boolean DEBUG = true;
+ private static final String TAG = "AlphabeticIndexCompat";
private static final String MID_DOT = "\u2219";
private final String mDefaultMiscLabel;
@@ -49,6 +53,9 @@
public String computeSectionName(@NonNull CharSequence cs) {
String s = Utilities.trim(cs);
String sectionName = mBaseIndex.getBucket(mBaseIndex.getBucketIndex(s)).getLabel();
+ if (DEBUG) {
+ Log.d(TAG, "computeSectionName: cs: " + cs + " sectionName: " + sectionName);
+ }
if (Utilities.trim(sectionName).isEmpty() && s.length() > 0) {
int c = s.codePointAt(0);
boolean startsWithDigit = Character.isDigit(c);
diff --git a/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java b/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java
index 480e8f3..ec0efe0 100644
--- a/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java
+++ b/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java
@@ -199,6 +199,10 @@
}
protected void changeFocus(T item, boolean hasFocus) {
+ if (mLastFocusedItem != item && !hasFocus) {
+ return;
+ }
+
if (hasFocus) {
endCurrentAnimation();
diff --git a/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt b/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt
new file mode 100644
index 0000000..e27926f
--- /dev/null
+++ b/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt
@@ -0,0 +1,97 @@
+/*
+ * 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.icons
+
+import android.content.ComponentName
+import android.content.pm.PackageInfo
+import android.database.Cursor
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.icons.cache.BaseIconCache
+import com.android.launcher3.icons.cache.CachingLogic
+import com.android.launcher3.icons.cache.IconCacheUpdateHandler
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doReturn
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class IconCacheUpdateHandlerTest {
+
+ @Mock private lateinit var cursor: Cursor
+ @Mock private lateinit var user: UserHandle
+ @Mock private lateinit var cachingLogic: CachingLogic<String>
+ @Mock private lateinit var baseIconCache: BaseIconCache
+
+ private var componentMap: HashMap<ComponentName, String> = hashMapOf()
+ private var ignorePackages: Set<String> = setOf()
+ private var packageInfoMap: HashMap<String, PackageInfo> = hashMapOf()
+
+ private val dummyRowData =
+ IconCacheRowData(
+ "com.android.fake/.FakeActivity",
+ System.currentTimeMillis(),
+ 1,
+ 1.0.toLong(),
+ "stateOfConfusion"
+ )
+
+ @Before
+ fun setup() {
+
+ MockitoAnnotations.initMocks(this)
+ // Load in a specific row to the database
+ doReturn(0).`when`(cursor).getColumnIndex(BaseIconCache.IconDB.COLUMN_COMPONENT)
+ doReturn(1).`when`(cursor).getColumnIndex(BaseIconCache.IconDB.COLUMN_LAST_UPDATED)
+ doReturn(2).`when`(cursor).getColumnIndex(BaseIconCache.IconDB.COLUMN_VERSION)
+ doReturn(3).`when`(cursor).getColumnIndex(BaseIconCache.IconDB.COLUMN_ROWID)
+ doReturn(4).`when`(cursor).getColumnIndex(BaseIconCache.IconDB.COLUMN_SYSTEM_STATE)
+ doReturn(dummyRowData.component).`when`(cursor).getString(0)
+ doReturn(dummyRowData.lastUpdated).`when`(cursor).getLong(1)
+ doReturn(dummyRowData.version).`when`(cursor).getInt(2)
+ doReturn(dummyRowData.row).`when`(cursor).getLong(3)
+ doReturn(dummyRowData.systemState).`when`(cursor).getString(4)
+ }
+
+ @Test
+ fun `IconCacheUpdateHandler returns null if the component name is malformed`() {
+ val updateHandlerUnderTest = IconCacheUpdateHandler(packageInfoMap, baseIconCache)
+
+ val result =
+ updateHandlerUnderTest.updateOrDeleteIcon(
+ cursor,
+ componentMap,
+ ignorePackages,
+ user,
+ cachingLogic
+ )
+
+ assert(result == null)
+ }
+}
+
+data class IconCacheRowData(
+ val component: String,
+ val lastUpdated: Long,
+ val version: Int,
+ val row: Long,
+ val systemState: String
+)
diff --git a/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java b/tests/multivalentTests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java
similarity index 100%
rename from tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java
rename to tests/multivalentTests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java