Merge "Import translations. DO NOT MERGE ANYWHERE" into 24D1-dev
diff --git a/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml b/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml
index a1bcad0..b004dfd 100644
--- a/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/redesigned_gesture_tutorial_fragment.xml
@@ -134,11 +134,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
+ android:layout_above="@id/gesture_tutorial_fragment_action_button"
android:layout_centerHorizontal="true"
android:background="@android:color/transparent"
- android:paddingEnd="24dp"
- android:paddingStart="24dp"
- android:paddingTop="24dp">
+ android:paddingTop="24dp"
+ android:paddingHorizontal="24dp"
+ android:layout_marginBottom="16dp">
<TextView
android:id="@+id/gesture_tutorial_fragment_feedback_title"
@@ -169,7 +170,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:layout_constraintBottom_toBottomOf="@id/gesture_tutorial_fragment_action_button"
+ app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -193,7 +194,7 @@
android:id="@+id/checkmark_animation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="44dp"
+ android:layout_marginBottom="28dp"
android:gravity="center"
android:scaleType="centerCrop"
app:lottie_loop="false"
@@ -204,19 +205,6 @@
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_subtitle"
app:layout_constraintBottom_toBottomOf="parent" />
- <Button
- android:id="@+id/gesture_tutorial_fragment_action_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/gesture_tutorial_action_button_background"
- android:stateListAnimator="@null"
- android:text="@string/gesture_tutorial_action_button_label"
- android:visibility="invisible"
- android:layout_marginBottom="60dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/checkmark_animation" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -228,4 +216,18 @@
android:src="@drawable/gesture_tutorial_finger_dot"
android:visibility="gone" />
+ <Button
+ android:id="@+id/gesture_tutorial_fragment_action_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/gesture_tutorial_done_button_end_margin"
+ android:layout_marginBottom="@dimen/gesture_tutorial_done_button_bottom_margin"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:background="@drawable/gesture_tutorial_action_button_background"
+ android:stateListAnimator="@null"
+ android:text="@string/gesture_tutorial_action_button_label"
+ android:visibility="invisible"
+ />
+
</com.android.quickstep.interaction.RootSandboxLayout>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index cdb257a..dbcba49 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -175,6 +175,8 @@
<dimen name="gesture_tutorial_menu_done_button_top_spacing">0dp</dimen>
<dimen name="gesture_tutorial_menu_back_shape_bottom_margin">0dp</dimen>
<dimen name="gesture_tutorial_menu_done_button_spacing">72dp</dimen>
+ <dimen name="gesture_tutorial_done_button_bottom_margin">40dp</dimen>
+ <dimen name="gesture_tutorial_done_button_end_margin">24dp</dimen>
<!-- Gesture Tutorial mock conversations -->
<dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
index 694475a..84c2ed2 100644
--- a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -28,14 +28,15 @@
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
+import android.view.accessibility.AccessibilityManager;
import androidx.annotation.ColorInt;
import androidx.core.content.ContextCompat;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
-import com.android.launcher3.util.Themes;
/**
* A view which shows a horizontal divider
@@ -54,6 +55,7 @@
private final @ColorInt int mStrokeColor;
private final @ColorInt int mAllAppsLabelTextColor;
+ private final AccessibilityManager mAccessibilityManager;
private Layout mAllAppsLabelLayout;
private boolean mShowAllAppsLabel;
@@ -87,7 +89,8 @@
mAllAppsLabelTextColor = ContextCompat.getColor(context,
R.color.material_color_on_surface_variant);
- mShowAllAppsLabel = !ALL_APPS_VISITED_COUNT.hasReachedMax(context);
+ mAccessibilityManager = AccessibilityManager.getInstance(context);
+ setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(context));
}
public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) {
@@ -99,6 +102,9 @@
/** {@code true} if all apps label should be shown in place of divider. */
public void setShowAllAppsLabel(boolean showAllAppsLabel) {
+ if (mAccessibilityManager.isEnabled() && !Utilities.isRunningInTestHarness()) {
+ showAllAppsLabel = true;
+ }
if (showAllAppsLabel != mShowAllAppsLabel) {
mShowAllAppsLabel = showAllAppsLabel;
updateDividerType();
@@ -148,6 +154,7 @@
mDividerType = dividerType;
int topPadding;
int bottomPadding;
+ setContentDescription(null);
switch (dividerType) {
case LINE:
topPadding = 0;
@@ -161,6 +168,7 @@
bottomPadding = getResources()
.getDimensionPixelSize(R.dimen.all_apps_label_bottom_padding);
mPaint.setColor(mAllAppsLabelTextColor);
+ setContentDescription(mAllAppsLabelLayout.getText());
break;
case NONE:
default:
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index 9df568e..2a27dea 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -136,21 +136,16 @@
});
}
- if (!ALL_APPS_VISITED_COUNT.hasReachedMax(launcher)) {
+ if (!Utilities.isRunningInTestHarness()) {
launcher.getStateManager().addStateListener(new StateListener<LauncherState>() {
@Override
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState == ALL_APPS) {
ALL_APPS_VISITED_COUNT.increment(launcher);
- return;
}
-
- boolean hasReachedMaxCount = ALL_APPS_VISITED_COUNT.hasReachedMax(launcher);
- launcher.getAppsView().getFloatingHeaderView().findFixedRowByType(
- AppsDividerView.class).setShowAllAppsLabel(!hasReachedMaxCount);
- if (hasReachedMaxCount) {
- launcher.getStateManager().removeStateListener(this);
- }
+ launcher.getAppsView().getFloatingHeaderView()
+ .findFixedRowByType(AppsDividerView.class)
+ .setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(launcher));
}
});
}
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index fd38af3..b615850 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -181,6 +181,9 @@
}
}
}
+ if (intent.`package` == null) {
+ intent.`package` = targetPkg
+ }
// else if cn == null => can't infer much, leave it
// else if !validPkg => could be restored icon or missing sd-card
when {
diff --git a/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
index 30957fc..2f0f2eb 100644
--- a/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
+++ b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
@@ -64,13 +64,13 @@
@Mock private lateinit var mockBgDataModel: BgDataModel
@Mock private lateinit var mockContext: Context
@Mock private lateinit var mockAppState: LauncherAppState
- @Mock private lateinit var mockIntent: Intent
@Mock private lateinit var mockPmHelper: PackageManagerHelper
@Mock private lateinit var mockLauncherApps: LauncherApps
@Mock private lateinit var mockCursor: LoaderCursor
@Mock private lateinit var mockUserManagerState: UserManagerState
@Mock private lateinit var mockWidgetInflater: WidgetInflater
+ private lateinit var intent: Intent
private lateinit var userHandle: UserHandle
private lateinit var iconRequestInfos: MutableList<IconRequestInfo<WorkspaceItemInfo>>
private lateinit var componentName: ComponentName
@@ -90,11 +90,11 @@
mockBgDataModel = mock<BgDataModel>()
componentName = ComponentName("package", "class")
unlockedUsersArray = LongSparseArray<Boolean>(1).apply { put(101, true) }
- mockIntent =
- mock<Intent>().apply {
- whenever(component).thenReturn(componentName)
- whenever(`package`).thenReturn("pkg")
- whenever(getStringExtra(ShortcutKey.EXTRA_SHORTCUT_ID)).thenReturn("")
+ intent =
+ Intent().apply {
+ component = componentName
+ `package` = "pkg"
+ putExtra(ShortcutKey.EXTRA_SHORTCUT_ID, "")
}
mockContext =
mock<Context>().apply {
@@ -110,7 +110,7 @@
mockPmHelper =
mock<PackageManagerHelper>().apply {
whenever(getAppLaunchIntent(componentName.packageName, userHandle))
- .thenReturn(mockIntent)
+ .thenReturn(intent)
}
mockLauncherApps =
mock<LauncherApps>().apply {
@@ -124,10 +124,9 @@
id = 1
restoreFlag = 1
serialNumber = 101
- whenever(parseIntent()).thenReturn(mockIntent)
+ whenever(parseIntent()).thenReturn(intent)
whenever(markRestored()).doAnswer { restoreFlag = 0 }
- whenever(updater().put(Favorites.INTENT, mockIntent.toUri(0)).commit())
- .thenReturn(1)
+ whenever(updater().put(Favorites.INTENT, intent.toUri(0)).commit()).thenReturn(1)
whenever(getAppShortcutInfo(any(), any(), any(), any()))
.thenReturn(mockWorkspaceInfo)
whenever(createIconRequestInfo(any(), any())).thenReturn(mockIconRequestInfo)
@@ -185,9 +184,11 @@
fun `When user is null then mark item deleted`() {
// Given
mockCursor = mock<LoaderCursor>().apply { id = 1 }
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
+
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
+
// Then
verify(mockCursor).markDeleted("User has been deleted for item id=1", PROFILE_DELETED)
verify(mockCursor, times(0)).checkAndAddItem(any(), any(), anyOrNull())
@@ -197,8 +198,9 @@
fun `When app has null intent then mark deleted`() {
// Given
mockCursor.apply { whenever(parseIntent()).thenReturn(null) }
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
+
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
verify(mockCursor).markDeleted("Null intent from db for item id=1", MISSING_INFO)
@@ -209,13 +211,13 @@
fun `When app has null target package then mark deleted`() {
// Given
- mockIntent.apply {
- whenever(component).thenReturn(null)
- whenever(`package`).thenReturn(null)
+ intent.apply {
+ component = null
+ `package` = null
}
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -228,11 +230,11 @@
// Given
componentName = ComponentName("", "")
- whenever(mockIntent.component).thenReturn(componentName)
- whenever(mockCursor.parseIntent()).thenReturn(mockIntent)
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
+ intent.component = componentName
+ intent.`package` = ""
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -243,10 +245,8 @@
@Test
fun `When valid app then mark restored`() {
- // Given
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
-
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -271,18 +271,18 @@
mockPmHelper =
mock<PackageManagerHelper>().apply {
whenever(getAppLaunchIntent(componentName.packageName, userHandle))
- .thenReturn(mockIntent)
+ .thenReturn(intent)
}
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
assertWithMessage("item restoreFlag should be set to 0")
.that(mockCursor.restoreFlag)
.isEqualTo(0)
- verify(mockCursor.updater().put(Favorites.INTENT, mockIntent.toUri(0))).commit()
+ verify(mockCursor.updater().put(Favorites.INTENT, intent.toUri(0))).commit()
assertThat(iconRequestInfos).containsExactly(mockIconRequestInfo)
verify(mockCursor).checkAndAddItem(mockWorkspaceInfo, mockBgDataModel, null)
}
@@ -300,9 +300,9 @@
mock<PackageManagerHelper>().apply {
whenever(getAppLaunchIntent(componentName.packageName, userHandle)).thenReturn(null)
}
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -336,13 +336,13 @@
whenever(disabledReason).thenReturn(0)
whenever(persons).thenReturn(EMPTY_PERSON_ARRAY)
}
- val shortcutKey = ShortcutKey.fromIntent(mockIntent, mockCursor.user)
+ val shortcutKey = ShortcutKey.fromIntent(intent, mockCursor.user)
keyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo
iconRequestInfos = mutableListOf()
- itemProcessorUnderTest =
- createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts)
// When
+ itemProcessorUnderTest =
+ createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts)
itemProcessorUnderTest.processItem()
// Then
@@ -362,9 +362,9 @@
mockCursor.itemType = ITEM_TYPE_DEEP_SHORTCUT
iconRequestInfos = mutableListOf()
keyToPinnedShortcutsMap = hashMapOf()
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -381,6 +381,45 @@
}
@Test
+ fun `When valid Pinned Deep Shortcut with null intent package then use targetPkg`() {
+
+ // Given
+ mockCursor.itemType = ITEM_TYPE_DEEP_SHORTCUT
+ val expectedShortcutInfo =
+ mock<ShortcutInfo>().apply {
+ whenever(id).thenReturn("")
+ whenever(`package`).thenReturn("")
+ whenever(activity).thenReturn(mock())
+ whenever(longLabel).thenReturn("")
+ whenever(isEnabled).thenReturn(true)
+ whenever(disabledMessage).thenReturn("")
+ whenever(disabledReason).thenReturn(0)
+ whenever(persons).thenReturn(EMPTY_PERSON_ARRAY)
+ }
+ iconRequestInfos = mutableListOf()
+ // Make sure shortcuts map has expected key from expected package
+ intent.`package` = componentName.packageName
+ val shortcutKey = ShortcutKey.fromIntent(intent, mockCursor.user)
+ keyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo
+ // set intent package back to null to test scenario
+ intent.`package` = null
+
+ // When
+ itemProcessorUnderTest =
+ createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts)
+ itemProcessorUnderTest.processItem()
+
+ // Then
+ assertWithMessage("item restoreFlag should be set to 0")
+ .that(mockCursor.restoreFlag)
+ .isEqualTo(0)
+ assertThat(iconRequestInfos).isEmpty()
+ assertThat(allDeepShortcuts).containsExactly(expectedShortcutInfo)
+ verify(mockCursor).markRestored()
+ verify(mockCursor).checkAndAddItem(any(), any(), anyOrNull())
+ }
+
+ @Test
fun `When processing Folder then create FolderInfo and mark restored`() {
val actualFolderInfo = FolderInfo()
mockBgDataModel =