Snap for 12116631 from 7c0fe2d17f to 24Q4-release

Change-Id: If0218714acb5c876d8184476382c206261c7d03a
This commit is contained in:
Android Build Coastguard Worker
2024-07-20 01:20:53 +00:00
135 changed files with 2904 additions and 1148 deletions
+1 -1
View File
@@ -16,7 +16,7 @@
-->
<resources>
<!-- App themes -->
<style name="LauncherTheme" parent="@style/BaseLauncherTheme">
<style name="LauncherTheme" parent="@style/DynamicColorsBaseLauncherTheme">
<item name="overviewButtonTextColor">@color/go_overview_text_color</item>
<item name="overviewButtonIconColor">@color/go_overview_text_color</item>
<item name="overviewButtonBackgroundColor">@color/go_overview_button_color</item>
+1 -1
View File
@@ -15,5 +15,5 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:color="?androidprv:attr/materialColorPrimaryContainer"/>
<item android:color="?attr/materialColorPrimaryContainer"/>
</selector>
+1 -1
View File
@@ -15,5 +15,5 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:color="?androidprv:attr/materialColorTertiary"/>
<item android:color="?attr/materialColorTertiary"/>
</selector>
@@ -15,5 +15,5 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:alpha="0.35" android:color="?androidprv:attr/materialColorPrimaryContainer" />
<item android:alpha="0.35" android:color="?attr/materialColorPrimaryContainer" />
</selector>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_hovered="false" android:color="?androidprv:attr/materialColorSurfaceBright" />
<item android:state_hovered="true" android:color="?androidprv:attr/materialColorSurfaceVariant" />
<item android:state_hovered="false" android:color="?attr/materialColorSurfaceBright" />
<item android:state_hovered="true" android:color="?attr/materialColorSurfaceVariant" />
</selector>
@@ -20,5 +20,5 @@
<solid android:color="@color/bubblebar_drop_target_bg_color" />
<stroke
android:width="1dp"
android:color="?androidprv:attr/materialColorPrimaryContainer" />
android:color="?attr/materialColorPrimaryContainer" />
</shape>
@@ -22,6 +22,6 @@
<solid android:color="@color/bubblebar_drop_target_bg_color" />
<stroke
android:width="1dp"
android:color="?androidprv:attr/materialColorPrimaryContainer" />
android:color="?attr/materialColorPrimaryContainer" />
</shape>
</inset>
@@ -19,5 +19,5 @@
android:shape="rectangle">
<corners android:radius="@dimen/rounded_button_radius" />
<solid android:color="?androidprv:attr/materialColorPrimaryContainer" />
<solid android:color="?attr/materialColorPrimaryContainer" />
</shape>
@@ -21,7 +21,7 @@
<shape android:shape="rectangle"
android:tint="?colorButtonNormal">
<corners android:radius="@dimen/recents_clear_all_outline_radius" />
<solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
<solid android:color="?attr/materialColorSurfaceBright"/>
</shape>
</item>
</ripple>
@@ -18,5 +18,5 @@
android:shape="rectangle">
<corners android:radius="@dimen/dialogCornerRadius" />
<solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
<solid android:color="?attr/materialColorSurfaceBright"/>
</shape>
@@ -16,6 +16,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<solid android:color="?androidprv:attr/materialColorSecondaryFixed" />
<solid android:color="?attr/materialColorSecondaryFixed" />
<corners android:radius="?android:attr/dialogCornerRadius" />
</shape>
+1 -1
View File
@@ -19,7 +19,7 @@
android:width="48dp"
android:height="48dp"
android:autoMirrored="true"
android:tint="?androidprv:attr/materialColorOnSurface"
android:tint="?attr/materialColorOnSurface"
android:viewportHeight="48"
android:viewportWidth="48">
<group
@@ -17,6 +17,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<solid android:color="?androidprv:attr/materialColorSurfaceBright" />
<solid android:color="?attr/materialColorSurfaceBright" />
<corners android:radius="@dimen/keyboard_quick_switch_task_view_radius" />
</shape>
@@ -21,6 +21,6 @@
android:viewportHeight="960"
android:viewportWidth="960">
<path
android:fillColor="?androidprv:attr/materialColorOnSurface"
android:fillColor="?attr/materialColorOnSurface"
android:pathData="M40,840L480,80L920,840L40,840ZM178,760L782,760L480,240L178,760ZM480,720Q497,720 508.5,708.5Q520,697 520,680Q520,663 508.5,651.5Q497,640 480,640Q463,640 451.5,651.5Q440,663 440,680Q440,697 451.5,708.5Q463,720 480,720ZM440,600L520,600L520,400L440,400L440,600ZM480,500L480,500L480,500L480,500Z" />
</vector>
@@ -23,7 +23,7 @@
android:importantForAccessibility="yes"
android:background="@drawable/keyboard_quick_switch_task_view_background"
android:clipToOutline="true"
launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
launcher:focusBorderColor="?attr/materialColorOutline">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
@@ -20,7 +20,7 @@
android:theme="@style/GestureTutorialActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?androidprv:attr/materialColorSurfaceContainer"
android:background="?attr/materialColorSurfaceContainer"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
@@ -163,7 +163,7 @@
android:layout_marginVertical="16dp"
android:text="@string/gesture_tutorial_action_button_label"
android:background="@drawable/gesture_tutorial_action_button_background"
android:backgroundTint="?androidprv:attr/materialColorPrimary"
android:backgroundTint="?attr/materialColorPrimary"
android:stateListAnimator="@null"
app:layout_constraintTop_toBottomOf="@id/guideline"
@@ -24,7 +24,7 @@
android:forceHasOverlappingRendering="false"
android:gravity="center"
android:importantForAccessibility="noHideDescendants"
android:textColor="?androidprv:attr/materialColorOnSecondaryFixed"
android:textColor="?attr/materialColorOnSecondaryFixed"
android:textSize="14sp"
android:autoSizeTextType="uniform"
android:autoSizeMaxTextSize="14sp"/>
@@ -20,7 +20,7 @@
android:theme="@style/GestureTutorialActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?androidprv:attr/materialColorSurfaceContainer"
android:background="?attr/materialColorSurfaceContainer"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
@@ -161,7 +161,7 @@
android:layout_marginVertical="16dp"
android:text="@string/gesture_tutorial_action_button_label"
android:background="@drawable/gesture_tutorial_action_button_background"
android:backgroundTint="?androidprv:attr/materialColorPrimary"
android:backgroundTint="?attr/materialColorPrimary"
android:stateListAnimator="@null"
app:layout_constraintTop_toBottomOf="@id/guideline"
+1 -1
View File
@@ -26,7 +26,7 @@
android:importantForAccessibility="no"
android:autoMirrored="true"
android:elevation="@dimen/task_thumbnail_icon_menu_elevation"
android:background="?androidprv:attr/materialColorSurfaceBright">
android:background="?attr/materialColorSurfaceBright">
<!-- ignoring warning because the user of the anchor is a Rect where RTL is not needed -->
<!-- This anchor's bounds is in the expected location after rotations and translations are
@@ -23,7 +23,7 @@
android:importantForAccessibility="yes"
android:background="@drawable/keyboard_quick_switch_task_view_background"
android:clipToOutline="true"
launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
launcher:focusBorderColor="?attr/materialColorOutline">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
@@ -22,7 +22,7 @@
android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
android:clipToOutline="true"
android:importantForAccessibility="yes"
launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
launcher:focusBorderColor="?attr/materialColorOutline">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
@@ -40,7 +40,7 @@
android:layout_width="@dimen/keyboard_quick_switch_recents_icon_size"
android:layout_height="@dimen/keyboard_quick_switch_recents_icon_size"
android:layout_marginBottom="8dp"
android:tint="?androidprv:attr/materialColorOnSurface"
android:tint="?attr/materialColorOnSurface"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintTop_toTopOf="parent"
@@ -43,7 +43,7 @@
android:layout_height="@dimen/keyboard_quick_switch_no_recent_items_icon_size"
android:layout_marginBottom="@dimen/keyboard_quick_switch_no_recent_items_icon_margin"
android:src="@drawable/view_carousel"
android:tint="?androidprv:attr/materialColorOnSurface"
android:tint="?attr/materialColorOnSurface"
android:importantForAccessibility="no"
app:layout_constraintVertical_chainStyle="packed"
@@ -23,6 +23,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/recents_clear_all"
android:textColor="?androidprv:attr/materialColorOnSurface"
launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
android:textColor="?attr/materialColorOnSurface"
launcher:focusBorderColor="?attr/materialColorOutline"
android:textSize="14sp" />
+2 -2
View File
@@ -25,8 +25,8 @@
android:clipChildren="false"
android:defaultFocusHighlightEnabled="false"
android:focusable="true"
launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
launcher:hoverBorderColor="?androidprv:attr/materialColorPrimary">
launcher:focusBorderColor="?attr/materialColorOutline"
launcher:hoverBorderColor="?attr/materialColorPrimary">
<include layout="@layout/task_thumbnail_deprecated" />
+2 -2
View File
@@ -25,8 +25,8 @@
android:clipChildren="true"
android:defaultFocusHighlightEnabled="false"
android:focusable="true"
launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
launcher:hoverBorderColor="?androidprv:attr/materialColorPrimary"
launcher:focusBorderColor="?attr/materialColorOutline"
launcher:hoverBorderColor="?attr/materialColorPrimary"
android:clipToPadding="true"
android:padding="0.1dp">
<!-- Setting a padding of 0.1 dp since android:clipToPadding needs a non-zero value for
+2 -2
View File
@@ -30,8 +30,8 @@
android:clipChildren="false"
android:defaultFocusHighlightEnabled="false"
android:focusable="true"
launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
launcher:hoverBorderColor="?androidprv:attr/materialColorPrimary">
launcher:focusBorderColor="?attr/materialColorOutline"
launcher:hoverBorderColor="?attr/materialColorPrimary">
<include layout="@layout/task_thumbnail_deprecated"/>
@@ -31,7 +31,7 @@
android:layout_height="@dimen/system_shortcut_icon_size"
android:layout_marginStart="@dimen/task_menu_option_start_margin"
android:layout_gravity="center_horizontal"
android:backgroundTint="?androidprv:attr/materialColorOnSurface"/>
android:backgroundTint="?attr/materialColorOnSurface"/>
<TextView
style="@style/BaseIcon"
@@ -40,7 +40,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/task_menu_option_text_start_margin"
android:textSize="14sp"
android:textColor="?androidprv:attr/materialColorOnSurface"
android:textColor="?attr/materialColorOnSurface"
android:focusable="false"
android:gravity="start"
android:ellipsize="end" />
+2 -2
View File
@@ -26,6 +26,6 @@
<!-- Turn on work apps button -->
<color name="work_turn_on_stroke">?androidprv:attr/colorAccentSecondaryVariant</color>
<color name="work_fab_bg_color">?androidprv:attr/materialColorPrimaryFixedDim</color>
<color name="work_fab_icon_color">?androidprv:attr/materialColorOnPrimaryFixed</color>
<color name="work_fab_bg_color">?attr/materialColorPrimaryFixedDim</color>
<color name="work_fab_icon_color">?attr/materialColorOnPrimaryFixed</color>
</resources>
+10 -10
View File
@@ -82,16 +82,16 @@
<style name="GestureTutorialActivity" parent="@style/AppTheme">
<item name="background">@android:color/transparent</item>
<item name="tutorialSubtitle">@android:color/white</item>
<item name="surfaceContainer">?androidprv:attr/materialColorSurfaceContainer</item>
<item name="onSurfaceHome">?androidprv:attr/materialColorPrimaryFixedDim</item>
<item name="surfaceHome">?androidprv:attr/materialColorOnPrimaryFixedVariant</item>
<item name="secondaryHome">?androidprv:attr/materialColorOnPrimaryFixed</item>
<item name="onSurfaceBack">?androidprv:attr/materialColorTertiaryFixedDim</item>
<item name="surfaceBack">?androidprv:attr/materialColorOnTertiaryFixedVariant</item>
<item name="secondaryBack">?androidprv:attr/materialColorOnTertiaryFixed</item>
<item name="onSurfaceOverview">?androidprv:attr/materialColorPrimaryFixed</item>
<item name="surfaceOverview">?androidprv:attr/materialColorOnSecondaryFixedVariant</item>
<item name="secondaryOverview">?androidprv:attr/materialColorOnSecondaryFixed</item>
<item name="surfaceContainer">?attr/materialColorSurfaceContainer</item>
<item name="onSurfaceHome">?attr/materialColorPrimaryFixedDim</item>
<item name="surfaceHome">?attr/materialColorOnPrimaryFixedVariant</item>
<item name="secondaryHome">?attr/materialColorOnPrimaryFixed</item>
<item name="onSurfaceBack">?attr/materialColorTertiaryFixedDim</item>
<item name="surfaceBack">?attr/materialColorOnTertiaryFixedVariant</item>
<item name="secondaryBack">?attr/materialColorOnTertiaryFixed</item>
<item name="onSurfaceOverview">?attr/materialColorPrimaryFixed</item>
<item name="surfaceOverview">?attr/materialColorOnSecondaryFixedVariant</item>
<item name="secondaryOverview">?attr/materialColorOnSecondaryFixed</item>
</style>
</resources>
+2 -2
View File
@@ -95,6 +95,6 @@
<!-- Turn on work apps button -->
<color name="work_turn_on_stroke">?androidprv:attr/colorAccentPrimaryVariant</color>
<color name="work_fab_bg_color">?androidprv:attr/materialColorPrimaryFixedDim</color>
<color name="work_fab_icon_color">?androidprv:attr/materialColorOnPrimaryFixed</color>
<color name="work_fab_bg_color">?attr/materialColorPrimaryFixedDim</color>
<color name="work_fab_icon_color">?attr/materialColorOnPrimaryFixed</color>
</resources>
+2
View File
@@ -449,11 +449,13 @@
<dimen name="bubblebar_icon_size_small">32dp</dimen>
<dimen name="bubblebar_icon_size">36dp</dimen>
<dimen name="bubblebar_icon_size_persistent_taskbar">28dp</dimen>
<dimen name="bubblebar_badge_size">24dp</dimen>
<dimen name="bubblebar_icon_overlap">12dp</dimen>
<dimen name="bubblebar_overflow_inset">16dp</dimen>
<dimen name="bubblebar_icon_spacing">6dp</dimen>
<dimen name="bubblebar_icon_spacing_large">8dp</dimen>
<dimen name="bubblebar_icon_spacing_persistent_taskbar">@dimen/bubblebar_icon_spacing</dimen>
<dimen name="bubblebar_expanded_icon_spacing">12dp</dimen>
<dimen name="bubblebar_icon_elevation">1dp</dimen>
+15 -15
View File
@@ -124,7 +124,7 @@
<style name="TextAppearance.GestureTutorial.ButtonLabel"
parent="TextAppearance.GestureTutorial.CallToAction">
<item name="android:gravity">center</item>
<item name="android:textColor">?androidprv:attr/materialColorOnPrimary</item>
<item name="android:textColor">?attr/materialColorOnPrimary</item>
<item name="android:letterSpacing">0.02</item>
<item name="android:textSize">16sp</item>
<item name="android:textAllCaps">false</item>
@@ -268,46 +268,46 @@
<style name="KeyboardQuickSwitchText">
<item name="fontFamily">google-sans-text</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
<item name="android:textColor">?attr/materialColorOnSurface</item>
<item name="lineHeight">20sp</item>
</style>
<style name="KeyboardQuickSwitchText.OnBackground" parent="KeyboardQuickSwitchText">
<item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
<item name="android:textColor">?attr/materialColorOnSurface</item>
</style>
<style name="GestureTutorialActivity" parent="@style/AppTheme">
<item name="background">@android:color/transparent</item>
<item name="tutorialSubtitle">@android:color/black</item>
<item name="surfaceContainer">?androidprv:attr/materialColorSurfaceContainer</item>
<item name="onSurfaceHome">?androidprv:attr/materialColorPrimaryFixed</item>
<item name="surfaceContainer">?attr/materialColorSurfaceContainer</item>
<item name="onSurfaceHome">?attr/materialColorPrimaryFixed</item>
<item name="surfaceHome">@android:color/system_accent1_300</item>
<item name="secondaryHome">?androidprv:attr/materialColorOnPrimaryFixedVariant</item>
<item name="onSurfaceBack">?androidprv:attr/materialColorTertiaryFixed</item>
<item name="secondaryHome">?attr/materialColorOnPrimaryFixedVariant</item>
<item name="onSurfaceBack">?attr/materialColorTertiaryFixed</item>
<item name="surfaceBack">@android:color/system_accent3_300</item>
<item name="secondaryBack">?androidprv:attr/materialColorOnTertiaryFixedVariant</item>
<item name="onSurfaceOverview">?androidprv:attr/materialColorPrimaryFixed</item>
<item name="secondaryBack">?attr/materialColorOnTertiaryFixedVariant</item>
<item name="onSurfaceOverview">?attr/materialColorPrimaryFixed</item>
<item name="surfaceOverview">@android:color/system_accent2_300</item>
<item name="secondaryOverview">?androidprv:attr/materialColorOnSecondaryFixedVariant</item>
<item name="secondaryOverview">?attr/materialColorOnSecondaryFixedVariant</item>
</style>
<style name="rotate_prompt_title" parent="TextAppearance.GestureTutorial.Dialog.Title">
<item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
<item name="android:textColor">?attr/materialColorOnSurface</item>
</style>
<style name="rotate_prompt_subtitle" parent="TextAppearance.GestureTutorial.Dialog.Subtitle">
<item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
<item name="android:textColor">?attr/materialColorOnSurfaceVariant</item>
</style>
<style name="ArrowTipTaskbarStyle">
<item name="arrowTipBackground">?androidprv:attr/materialColorSurfaceContainer</item>
<item name="arrowTipTextColor">?androidprv:attr/materialColorOnSurface</item>
<item name="arrowTipBackground">?attr/materialColorSurfaceContainer</item>
<item name="arrowTipTextColor">?attr/materialColorOnSurface</item>
</style>
<style name="IconAppChipMenuTextStyle">
<item name="android:fontFamily">google-sans-text-medium</item>
<item name="android:textSize">@dimen/task_thumbnail_icon_menu_text_size</item>
<item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
<item name="android:textColor">?attr/materialColorOnSurface</item>
<item name="android:letterSpacing">0.025</item>
<item name="android:lineHeight">20sp</item>
</style>
@@ -356,6 +356,14 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
options.setOnAnimationAbortListener(endCallback);
options.setOnAnimationFinishedListener(endCallback);
// Prepare taskbar for animation synchronization. This needs to happen here before any
// app transition is created.
LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
if (enableScalingRevealHomeAnimation() && taskbarController != null) {
taskbarController.setIgnoreInAppFlagForSync(true);
onEndCallback.add(() -> taskbarController.setIgnoreInAppFlagForSync(false));
}
IBinder cookie = mAppLaunchRunner.supportsReturnTransition()
? ((ContainerAnimationRunner) mAppLaunchRunner).getCookie() : null;
addLaunchCookie(cookie, (ItemInfo) v.getTag(), options);
@@ -1924,6 +1932,21 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
anim.addListener(mForceInvisibleListener);
}
// Syncs the app launch animation and taskbar stash animation (if exists).
if (enableScalingRevealHomeAnimation()) {
LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
if (taskbarController != null) {
taskbarController.setIgnoreInAppFlagForSync(false);
if (launcherClosing) {
Animator taskbar = taskbarController.createAnimToApp();
if (taskbar != null) {
anim.play(taskbar);
}
}
}
}
result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy,
skipFirstFrame);
}
@@ -47,11 +47,11 @@ import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetPredictionsRequester;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.model.WidgetsListBaseEntriesBuilder;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import java.util.ArrayList;
@@ -60,10 +60,8 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** An Activity that can host Launcher's widget picker. */
public class WidgetPickerActivity extends BaseActivity {
@@ -112,7 +110,8 @@ public class WidgetPickerActivity extends BaseActivity {
private WidgetsModel mModel;
private LauncherAppState mApp;
private WidgetPredictionsRequester mWidgetPredictionsRequester;
private final PopupDataProvider mPopupDataProvider = new PopupDataProvider(i -> {});
private final PopupDataProvider mPopupDataProvider = new PopupDataProvider(i -> {
});
private int mDesiredWidgetWidth;
private int mDesiredWidgetHeight;
@@ -287,45 +286,41 @@ public class WidgetPickerActivity extends BaseActivity {
};
}
/** Updates the model with widgets, applies filters and launches the widgets sheet once
* widgets are available */
/**
* Updates the model with widgets, applies filters and launches the widgets sheet once
* widgets are available
*/
private void refreshAndBindWidgets() {
MODEL_EXECUTOR.execute(() -> {
LauncherAppState app = LauncherAppState.getInstance(this);
Context context = app.getContext();
mModel.update(app, null);
final List<WidgetsListBaseEntry> allWidgets =
mModel.getFilteredWidgetsListForPicker(context, mWidgetsFilter);
final List<WidgetsListBaseEntry> defaultWidgets =
shouldShowDefaultWidgets() ? mModel.getFilteredWidgetsListForPicker(context,
mDefaultWidgetsFilter) : List.of();
bindWidgets(allWidgets, defaultWidgets);
bindWidgets(mModel.getWidgetsByPackageItem());
// Open sheet once widgets are available, so that it doesn't interrupt the open
// animation.
openWidgetsSheet();
if (mUiSurface != null) {
Map<ComponentKey, WidgetItem> allWidgetItems = allWidgets.stream()
.filter(entry -> entry instanceof WidgetsListContentEntry)
.flatMap(entry -> entry.mWidgets.stream())
.distinct()
.collect(Collectors.toMap(
widget -> new ComponentKey(widget.componentName, widget.user),
Function.identity()
));
mWidgetPredictionsRequester = new WidgetPredictionsRequester(app.getContext(),
mUiSurface, allWidgetItems);
mUiSurface, mModel.getWidgetsByComponentKey());
mWidgetPredictionsRequester.request(mAddedWidgets, this::bindRecommendedWidgets);
}
});
}
private void bindWidgets(List<WidgetsListBaseEntry> allWidgets,
List<WidgetsListBaseEntry> defaultWidgets) {
private void bindWidgets(Map<PackageItemInfo, List<WidgetItem>> widgets) {
WidgetsListBaseEntriesBuilder builder = new WidgetsListBaseEntriesBuilder(
mApp.getContext());
final List<WidgetsListBaseEntry> allWidgets = builder.build(widgets, mWidgetsFilter);
final List<WidgetsListBaseEntry> defaultWidgets =
shouldShowDefaultWidgets() ? builder.build(widgets,
mDefaultWidgetsFilter) : List.of();
MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setAllWidgets(allWidgets, defaultWidgets));
}
private void openWidgetsSheet() {
private void openWidgetsSheet() {
MAIN_EXECUTOR.execute(() -> {
mWidgetSheet = WidgetsFullSheet.show(this, true);
mWidgetSheet.mayUpdateTitleAndDescription(mTitle, mDescription);
@@ -392,7 +387,7 @@ public class WidgetPickerActivity extends BaseActivity {
mActiveOnBackAnimationCallback.onBackCancelled();
mActiveOnBackAnimationCallback = null;
}
};
}
private boolean shouldShowDefaultWidgets() {
// If optional filters such as size filter are present, we display them as default widgets.
@@ -31,12 +31,12 @@ 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
@@ -84,10 +84,9 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
getResources().getDimensionPixelSize(R.dimen.all_apps_divider_height)
};
mStrokeColor = ContextCompat.getColor(context, R.color.material_color_outline_variant);
mStrokeColor = Themes.getAttrColor(context, R.attr.materialColorOutlineVariant);
mAllAppsLabelTextColor = ContextCompat.getColor(context,
R.color.material_color_on_surface_variant);
mAllAppsLabelTextColor = Themes.getAttrColor(context, R.attr.materialColorOnSurfaceVariant);
mAccessibilityManager = AccessibilityManager.getInstance(context);
setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(context));
@@ -19,6 +19,7 @@ import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR
import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE;
import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_VISIBLE;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IGNORE_IN_APP;
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.window.flags.Flags.enableDesktopWindowingWallpaperActivity;
@@ -256,6 +257,24 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
return mTaskbarLauncherStateController.createAnimToLauncher(toState, callbacks, duration);
}
/**
* Create Taskbar animation to be played alongside the Launcher app launch animation.
*/
public @Nullable Animator createAnimToApp() {
TaskbarStashController stashController = mControllers.taskbarStashController;
stashController.updateStateForFlag(TaskbarStashController.FLAG_IN_APP, true);
return stashController.createApplyStateAnimator(stashController.getStashDuration());
}
/**
* Temporarily ignore FLAG_IN_APP for app launches to prevent premature taskbar stashing.
* This is needed because taskbar gets a signal to stash before we actually start the
* app launch animation.
*/
public void setIgnoreInAppFlagForSync(boolean enabled) {
mControllers.taskbarStashController.updateStateForFlag(FLAG_IGNORE_IN_APP, enabled);
}
public void updateTaskbarLauncherStateGoingHome() {
mTaskbarLauncherStateController.updateStateForFlag(FLAG_VISIBLE, true);
mTaskbarLauncherStateController.applyState();
@@ -53,8 +53,7 @@ constructor(
private val activityContext: ActivityContext = ActivityContext.lookupContext(context)
private val backgroundColor =
Themes.getAttrColor(context, com.android.internal.R.attr.materialColorSurfaceBright)
private val backgroundColor = Themes.getAttrColor(context, R.attr.materialColorSurfaceBright)
private val tooltipCornerRadius = Themes.getDialogCornerRadius(context)
private val arrowWidth = resources.getDimension(R.dimen.popup_arrow_width)
@@ -95,6 +95,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
public static final int FLAG_STASHED_SYSUI = 1 << 9; // app pinning,...
public static final int FLAG_STASHED_DEVICE_LOCKED = 1 << 10; // device is locked: keyguard, ...
public static final int FLAG_IN_OVERVIEW = 1 << 11; // launcher is in overview
public static final int FLAG_IGNORE_IN_APP = 1 << 12; // used to sync with app launch animation
// If any of these flags are enabled, isInApp should return true.
private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
@@ -1263,6 +1264,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
*/
@Nullable
public Animator createSetStateAnimator(long flags, long duration) {
// We do this when we want to synchronize the app launch and taskbar stash animations.
if (hasAnyFlag(FLAG_IGNORE_IN_APP) && hasAnyFlag(flags, FLAG_IN_APP)) {
flags = flags & ~FLAG_IN_APP;
}
boolean isStashed = mStashCondition.test(flags);
if (DEBUG) {
@@ -635,8 +635,8 @@ public class BubbleBarController extends IBubblesListener.Stub {
final TypedArray ta = mContext.obtainStyledAttributes(
new int[]{
com.android.internal.R.attr.materialColorOnPrimaryFixed,
com.android.internal.R.attr.materialColorPrimaryFixed
R.attr.materialColorOnPrimaryFixed,
R.attr.materialColorPrimaryFixed
});
int overflowIconColor = ta.getColor(0, Color.WHITE);
int overflowBackgroundColor = ta.getColor(1, Color.BLACK);
@@ -31,6 +31,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.taskbar.TaskbarActivityContext;
@@ -62,6 +63,7 @@ public class BubbleBarViewController {
private final TaskbarActivityContext mActivity;
private final BubbleBarView mBarView;
private int mIconSize;
private int mBubbleBarPadding;
// Initialized in init.
private BubbleStashController mBubbleStashController;
@@ -110,10 +112,9 @@ public class BubbleBarViewController {
mTaskbarStashController = controllers.taskbarStashController;
mTaskbarInsetsController = controllers.taskbarInsetsController;
mBubbleBarViewAnimator = new BubbleBarViewAnimator(mBarView, mBubbleStashController);
onBubbleBarConfigurationChanged(/* animate= */ false);
mActivity.addOnDeviceProfileChangeListener(
dp -> updateBubbleBarIconSize(dp.taskbarIconSize, /* animate= */ true));
updateBubbleBarIconSize(mActivity.getDeviceProfile().taskbarIconSize, /* animate= */ false);
dp -> onBubbleBarConfigurationChanged(/* animate= */ true));
mBubbleBarScale.updateValue(1f);
mBubbleClickListener = v -> onBubbleClicked((BubbleView) v);
mBubbleBarClickListener = v -> onBubbleBarClicked();
@@ -335,27 +336,60 @@ public class BubbleBarViewController {
// Modifying view related properties.
//
private void updateBubbleBarIconSize(int newIconSize, boolean animate) {
/** Notifies controller of configuration change, so bubble bar can be adjusted */
public void onBubbleBarConfigurationChanged(boolean animate) {
int newIconSize;
int newPadding;
Resources res = mActivity.getResources();
if (mBubbleStashController.isBubblesShowingOnHome()) {
newIconSize = getBubbleBarIconSizeFromDeviceProfile(res);
newPadding = getBubbleBarPaddingFromDeviceProfile(res);
} else {
// the bubble bar is shown inside the persistent task bar, use preset sizes
newIconSize = res.getDimensionPixelSize(R.dimen.bubblebar_icon_size_persistent_taskbar);
newPadding = res.getDimensionPixelSize(
R.dimen.bubblebar_icon_spacing_persistent_taskbar);
}
updateBubbleBarIconSizeAndPadding(newIconSize, newPadding, animate);
}
private int getBubbleBarIconSizeFromDeviceProfile(Resources res) {
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
DisplayMetrics dm = res.getDisplayMetrics();
float smallIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
APP_ICON_SMALL_DP, dm);
float mediumIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
APP_ICON_MEDIUM_DP, dm);
float largeIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
APP_ICON_LARGE_DP, dm);
float smallMediumThreshold = (smallIconSize + mediumIconSize) / 2f;
float mediumLargeThreshold = (mediumIconSize + largeIconSize) / 2f;
mIconSize = newIconSize <= smallMediumThreshold
int taskbarIconSize = deviceProfile.taskbarIconSize;
return taskbarIconSize <= smallMediumThreshold
? res.getDimensionPixelSize(R.dimen.bubblebar_icon_size_small) :
res.getDimensionPixelSize(R.dimen.bubblebar_icon_size);
float bubbleBarPadding = newIconSize >= mediumLargeThreshold
}
private int getBubbleBarPaddingFromDeviceProfile(Resources res) {
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
DisplayMetrics dm = res.getDisplayMetrics();
float mediumIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
APP_ICON_MEDIUM_DP, dm);
float largeIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
APP_ICON_LARGE_DP, dm);
float mediumLargeThreshold = (mediumIconSize + largeIconSize) / 2f;
return deviceProfile.taskbarIconSize >= mediumLargeThreshold
? res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing_large) :
res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
}
private void updateBubbleBarIconSizeAndPadding(int iconSize, int padding, boolean animate) {
if (mIconSize == iconSize && mBubbleBarPadding == padding) return;
mIconSize = iconSize;
mBubbleBarPadding = padding;
if (animate) {
mBarView.animateBubbleBarIconSize(mIconSize, bubbleBarPadding);
mBarView.animateBubbleBarIconSize(iconSize, padding);
} else {
mBarView.setIconSizeAndPadding(mIconSize, bubbleBarPadding);
mBarView.setIconSizeAndPadding(iconSize, padding);
}
}
@@ -1631,14 +1631,17 @@ public abstract class AbsSwipeUpHandler<T extends RecentsViewContainer,
mRecentsAnimationController.screenshotTask(taskId));
});
// let SystemUi reparent the overlay leash as soon as possible
// let SystemUi reparent the overlay leash as soon as possible;
// make sure to pass in an empty src-rect-hint if overlay is present, since we
// use our own calculated source-rect-hint for the animation.
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getComponentName(),
mSwipePipToHomeAnimator.getDestinationBounds(),
mSwipePipToHomeAnimator.getContentOverlay(),
mSwipePipToHomeAnimator.getAppBounds(),
mSwipePipToHomeAnimator.getSourceRectHint());
mSwipePipToHomeAnimator.getContentOverlay() != null ? new Rect()
: mSwipePipToHomeAnimator.getSourceRectHint());
windowAnim = mSwipePipToHomeAnimators;
} else {
@@ -300,8 +300,12 @@ public class RecentTasksList {
@VisibleForTesting
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
int currentUserId = Process.myUserHandle().getIdentifier();
ArrayList<GroupedRecentTaskInfo> rawTasks =
mSysUiProxy.getRecentTasks(numTasks, currentUserId);
ArrayList<GroupedRecentTaskInfo> rawTasks;
try {
rawTasks = mSysUiProxy.getRecentTasks(numTasks, currentUserId);
} catch (SystemUiProxy.GetRecentTasksException e) {
return INVALID_RESULT;
}
// The raw tasks are given in most-recent to least-recent order, we need to reverse it
Collections.reverse(rawTasks);
@@ -416,8 +420,12 @@ public class RecentTasksList {
}
writer.println(prefix + " ]");
int currentUserId = Process.myUserHandle().getIdentifier();
ArrayList<GroupedRecentTaskInfo> rawTasks =
mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId);
ArrayList<GroupedRecentTaskInfo> rawTasks;
try {
rawTasks = mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId);
} catch (SystemUiProxy.GetRecentTasksException e) {
rawTasks = new ArrayList<>();
}
writer.println(prefix + " rawTasks=[");
for (GroupedRecentTaskInfo task : rawTasks) {
TaskInfo taskInfo1 = task.getTaskInfo1();
@@ -33,6 +33,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -416,7 +417,8 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
| SYSUI_STATE_QUICK_SETTINGS_EXPANDED
| SYSUI_STATE_MAGNIFICATION_OVERLAP
| SYSUI_STATE_DEVICE_DREAMING
| SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
| SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION
| SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
return (gestureDisablingStates & mSystemUiStateFlags) == 0 && homeOrOverviewEnabled;
}
@@ -1394,10 +1394,26 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
}
}
public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {
public static class GetRecentTasksException extends Exception {
public GetRecentTasksException(String message) {
super(message);
}
public GetRecentTasksException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* Retrieves a list of Recent tasks from ActivityManager.
* @throws GetRecentTasksException if IRecentTasks is not initialized, or when we get
* RemoteException from server side
*/
public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId)
throws GetRecentTasksException {
if (mRecentTasks == null) {
Log.w(TAG, "getRecentTasks() failed due to null mRecentTasks");
return new ArrayList<>();
Log.e(TAG, "getRecentTasks() failed due to null mRecentTasks");
throw new GetRecentTasksException("null mRecentTasks");
}
try {
final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
@@ -1407,8 +1423,8 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
}
return new ArrayList<>(Arrays.asList(rawTasks));
} catch (RemoteException e) {
Log.w(TAG, "Failed call getRecentTasks", e);
return new ArrayList<>();
Log.e(TAG, "Failed call getRecentTasks", e);
throw new GetRecentTasksException("Failed call getRecentTasks", e);
}
}
@@ -39,7 +39,8 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.Xml;
import com.android.launcher3.AutoInstallsLayout;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.logging.InstanceId;
@@ -73,7 +74,6 @@ public class SettingsChangeLogger implements
new MainThreadInitializedObject<>(SettingsChangeLogger::new);
private static final String TAG = "SettingsChangeLogger";
private static final String ROOT_TAG = "androidx.preference.PreferenceScreen";
private static final String BOOLEAN_PREF = "SwitchPreference";
private final Context mContext;
@@ -85,8 +85,13 @@ public class SettingsChangeLogger implements
private StatsLogManager.LauncherEvent mHomeScreenSuggestionEvent;
private SettingsChangeLogger(Context context) {
this(context, StatsLogManager.newInstance(context));
}
@VisibleForTesting
SettingsChangeLogger(Context context, StatsLogManager statsLogManager) {
mContext = context;
mStatsLogManager = StatsLogManager.newInstance(mContext);
mStatsLogManager = statsLogManager;
mLoggablePrefs = loadPrefKeys(context);
DisplayController.INSTANCE.get(context).addChangeListener(this);
mNavMode = DisplayController.getNavigationMode(context);
@@ -105,7 +110,13 @@ public class SettingsChangeLogger implements
ArrayMap<String, LoggablePref> result = new ArrayMap<>();
try {
AutoInstallsLayout.beginDocument(parser, ROOT_TAG);
// Move cursor to first tag because it could be
// androidx.preference.PreferenceScreen or PreferenceScreen
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG
&& eventType != XmlPullParser.END_DOCUMENT) {
eventType = parser.next();
}
final int depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG
@@ -189,13 +200,19 @@ public class SettingsChangeLogger implements
prefs.getBoolean(key, lp.defaultValue) ? lp.eventIdOn : lp.eventIdOff));
}
@VisibleForTesting
ArrayMap<String, LoggablePref> getLoggingPrefs() {
return mLoggablePrefs;
}
@Override
public void close() {
getPrefs(mContext).unregisterOnSharedPreferenceChangeListener(this);
getDevicePrefs(mContext).unregisterOnSharedPreferenceChangeListener(this);
}
private static class LoggablePref {
@VisibleForTesting
static class LoggablePref {
public boolean defaultValue;
public int eventIdOn;
public int eventIdOff;
@@ -0,0 +1,251 @@
/*
* 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.quickstep.recents.di
import android.content.Context
import android.util.Log
import android.view.View
import com.android.quickstep.RecentsModel
import com.android.quickstep.recents.data.RecentTasksRepository
import com.android.quickstep.recents.data.TasksRepository
import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
import com.android.quickstep.recents.usecase.GetThumbnailUseCase
import com.android.quickstep.recents.viewmodel.RecentsViewData
import com.android.quickstep.task.viewmodel.TaskContainerData
import com.android.quickstep.task.viewmodel.TaskOverlayViewModel
import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
import com.android.quickstep.task.viewmodel.TaskViewData
import com.android.quickstep.task.viewmodel.TaskViewModel
import com.android.quickstep.views.TaskViewType
import com.android.systemui.shared.recents.model.Task
import java.util.logging.Level
internal typealias RecentsScopeId = String
class RecentsDependencies private constructor(private val appContext: Context) {
private val scopes = mutableMapOf<RecentsScopeId, RecentsDependenciesScope>()
init {
startDefaultScope(appContext)
}
/**
* This function initialised the default scope with RecentsView dependencies. These dependencies
* are used multiple times and should be a singleton to share across Recents classes.
*/
private fun startDefaultScope(appContext: Context) {
createScope(DEFAULT_SCOPE_ID).apply {
set(RecentsViewData::class.java.simpleName, RecentsViewData())
// Create RecentsTaskRepository singleton
val recentTasksRepository: RecentTasksRepository =
with(RecentsModel.INSTANCE.get(appContext)) {
TasksRepository(this, thumbnailCache, iconCache)
}
set(RecentTasksRepository::class.java.simpleName, recentTasksRepository)
}
}
inline fun <reified T> inject(
scopeId: RecentsScopeId = "",
extras: RecentsDependenciesExtras = RecentsDependenciesExtras(),
noinline factory: ((extras: RecentsDependenciesExtras) -> T)? = null,
): T = inject(T::class.java, scopeId = scopeId, extras = extras, factory = factory)
@Suppress("UNCHECKED_CAST")
@JvmOverloads
fun <T> inject(
modelClass: Class<T>,
scopeId: RecentsScopeId = DEFAULT_SCOPE_ID,
extras: RecentsDependenciesExtras = RecentsDependenciesExtras(),
factory: ((extras: RecentsDependenciesExtras) -> T)? = null,
): T {
val currentScopeId = scopeId.ifEmpty { DEFAULT_SCOPE_ID }
val scope = scopes[currentScopeId] ?: createScope(currentScopeId)
log("inject ${modelClass.simpleName} into ${scope.scopeId}", Log.INFO)
var instance: T?
synchronized(this) {
instance = getDependency(scope, modelClass)
log("found instance? $instance", Log.INFO)
if (instance == null) {
instance =
factory?.invoke(extras) as T ?: createDependency(modelClass, scopeId, extras)
scope[modelClass.simpleName] = instance!!
}
}
return instance!!
}
inline fun <reified T> provide(scopeId: RecentsScopeId = "", noinline factory: () -> T): T =
provide(T::class.java, scopeId = scopeId, factory = factory)
@JvmOverloads
fun <T> provide(
modelClass: Class<T>,
scopeId: RecentsScopeId = DEFAULT_SCOPE_ID,
factory: () -> T,
) = inject(modelClass, scopeId, factory = { factory.invoke() })
private fun <T> getDependency(scope: RecentsDependenciesScope, modelClass: Class<T>): T? {
var instance: T? = scope[modelClass.simpleName] as T?
if (instance == null) {
instance =
scope.scopeIdsLinked.firstNotNullOfOrNull { scopeId ->
getScope(scopeId)[modelClass.simpleName]
} as T?
}
if (instance != null) log("Found dependency: $instance", Log.INFO)
return instance
}
fun getScope(scope: Any): RecentsDependenciesScope {
val scopeId: RecentsScopeId = scope as? RecentsScopeId ?: scope.hashCode().toString()
return getScope(scopeId)
}
fun getScope(scopeId: RecentsScopeId): RecentsDependenciesScope =
scopes[scopeId] ?: createScope(scopeId)
// TODO(b/353912757): Create a factory so we can prevent this method of growing indefinitely.
// Each class should be responsible for providing a factory function to create a new instance.
@Suppress("UNCHECKED_CAST")
private fun <T> createDependency(
modelClass: Class<T>,
scopeId: RecentsScopeId,
extras: RecentsDependenciesExtras,
): T {
log("createDependency ${modelClass.simpleName} with $scopeId and $extras", Log.WARN)
val instance: Any =
when (modelClass) {
RecentTasksRepository::class.java -> {
with(RecentsModel.INSTANCE.get(appContext)) {
TasksRepository(this, thumbnailCache, iconCache)
}
}
RecentsViewData::class.java -> RecentsViewData()
TaskViewModel::class.java -> TaskViewModel(taskViewData = inject(scopeId, extras))
TaskViewData::class.java -> {
val taskViewType = extras["TaskViewType"] as TaskViewType
TaskViewData(taskViewType)
}
TaskContainerData::class.java -> TaskContainerData()
TaskThumbnailViewModel::class.java ->
TaskThumbnailViewModel(
recentsViewData = inject(),
taskViewData = inject(scopeId, extras),
taskContainerData = inject(),
getThumbnailPositionUseCase = inject(),
tasksRepository = inject()
)
TaskOverlayViewModel::class.java -> {
val task = extras["Task"] as Task
TaskOverlayViewModel(
task = task,
recentsViewData = inject(),
recentTasksRepository = inject(),
getThumbnailPositionUseCase = inject()
)
}
GetThumbnailUseCase::class.java -> GetThumbnailUseCase(taskRepository = inject())
GetThumbnailPositionUseCase::class.java ->
GetThumbnailPositionUseCase(
deviceProfileRepository = inject(),
rotationStateRepository = inject(),
tasksRepository = inject()
)
else -> {
log("Factory for ${modelClass.simpleName} not defined!", Log.ERROR)
error("Factory for ${modelClass.simpleName} not defined!")
}
}
return instance as T
}
private fun createScope(scopeId: RecentsScopeId): RecentsDependenciesScope {
return RecentsDependenciesScope(scopeId).also { scopes[scopeId] = it }
}
private fun log(message: String, @Log.Level level: Int = Log.DEBUG) {
if (DEBUG) {
when (level) {
Log.WARN -> Log.w(TAG, message)
Log.VERBOSE -> Log.v(TAG, message)
Log.INFO -> Log.i(TAG, message)
Log.ERROR -> Log.e(TAG, message)
else -> Log.d(TAG, message)
}
}
}
companion object {
private const val DEFAULT_SCOPE_ID = "RecentsDependencies::GlobalScope"
private const val TAG = "RecentsDependencies"
private const val DEBUG = false
@Volatile private lateinit var instance: RecentsDependencies
fun initialize(view: View): RecentsDependencies = initialize(view.context)
fun initialize(context: Context): RecentsDependencies {
synchronized(this) {
if (!Companion::instance.isInitialized) {
instance = RecentsDependencies(context.applicationContext)
}
}
return instance
}
fun getInstance(): RecentsDependencies {
if (!Companion::instance.isInitialized) {
throw UninitializedPropertyAccessException(
"Recents dependencies are not initialized. " +
"Call `RecentsDependencies.initialize` before using this container."
)
}
return instance
}
fun destroy() {
instance.scopes.clear()
instance.startDefaultScope(instance.appContext)
}
}
}
inline fun <reified T> RecentsDependencies.Companion.inject(
scope: Any = "",
vararg extras: Pair<String, Any>,
noinline factory: ((extras: RecentsDependenciesExtras) -> T)? = null,
): Lazy<T> = lazy { get(scope, RecentsDependenciesExtras(extras), factory) }
inline fun <reified T> RecentsDependencies.Companion.get(
scope: Any = "",
extras: RecentsDependenciesExtras = RecentsDependenciesExtras(),
noinline factory: ((extras: RecentsDependenciesExtras) -> T)? = null,
): T {
val scopeId: RecentsScopeId = scope as? RecentsScopeId ?: scope.hashCode().toString()
return getInstance().inject(scopeId, extras, factory)
}
inline fun <reified T> RecentsDependencies.Companion.get(
scope: Any = "",
vararg extras: Pair<String, Any>,
noinline factory: ((extras: RecentsDependenciesExtras) -> T)? = null,
): T = get(scope, RecentsDependenciesExtras(extras), factory)
fun RecentsDependencies.Companion.getScope(scopeId: Any) = getInstance().getScope(scopeId)
@@ -0,0 +1,27 @@
/*
* 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.quickstep.recents.di
data class RecentsDependenciesExtras(private val data: MutableMap<String, Any> = mutableMapOf()) {
constructor(value: Array<out Pair<String, Any>>) : this(value.toMap().toMutableMap())
operator fun get(key: String) = data[key]
operator fun set(key: String, value: Any) {
data[key] = value
}
}
@@ -0,0 +1,71 @@
/*
* 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.quickstep.recents.di
import android.util.Log
class RecentsDependenciesScope(
val scopeId: RecentsScopeId,
private val dependencies: MutableMap<String, Any> = mutableMapOf(),
private val scopeIds: MutableList<RecentsScopeId> = mutableListOf()
) {
val scopeIdsLinked: List<RecentsScopeId>
get() = scopeIds.toList()
operator fun get(identifier: String): Any? {
log("get $identifier")
return dependencies[identifier]
}
operator fun set(key: String, value: Any) {
synchronized(this) {
log("set $key")
dependencies[key] = value
}
}
fun remove(key: String): Any? {
synchronized(this) {
log("remove $key")
return dependencies.remove(key)
}
}
fun linkTo(scope: RecentsDependenciesScope) {
log("linking to ${scope.scopeId}")
scopeIds += scope.scopeId
}
fun close() {
log("reset")
synchronized(this) { dependencies.clear() }
}
private fun log(message: String) {
if (DEBUG) Log.d(TAG, "[scopeId=$scopeId] $message")
}
override fun toString(): String =
"scopeId: $scopeId" +
"\n dependencies: ${dependencies.map { "${it.key}=${it.value}" }.joinToString(", ")}" +
"\n linked to: ${scopeIds.joinToString(", ")}"
private companion object {
private const val TAG = "RecentsDependenciesScope"
private const val DEBUG = false
}
}
@@ -0,0 +1,48 @@
/*
* 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.quickstep.recents.viewmodel
import com.android.quickstep.recents.data.RecentTasksRepository
class RecentsViewModel(
private val recentsTasksRepository: RecentTasksRepository,
private val recentsViewData: RecentsViewData
) {
fun refreshAllTaskData() {
recentsTasksRepository.getAllTaskData(true)
}
fun updateVisibleTasks(visibleTaskIdList: List<Int>) {
recentsTasksRepository.setVisibleTasks(visibleTaskIdList)
}
fun updateScale(scale: Float) {
recentsViewData.scale.value = scale
}
fun updateFullscreenProgress(fullscreenProgress: Float) {
recentsViewData.fullscreenProgress.value = fullscreenProgress
}
fun updateTasksFullyVisible(taskIds: Set<Int>) {
recentsViewData.settledFullyVisibleTaskIds.value = taskIds
}
fun setOverlayEnabled(isOverlayEnabled: Boolean) {
recentsViewData.overlayEnabled.value = isOverlayEnabled
}
}
@@ -31,15 +31,14 @@ import androidx.core.view.isVisible
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.util.ViewPool
import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
import com.android.quickstep.recents.di.RecentsDependencies
import com.android.quickstep.recents.di.inject
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.BackgroundOnly
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.LiveTile
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Snapshot
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
import com.android.quickstep.util.TaskCornerRadius
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskView
import com.android.systemui.shared.system.QuickStepContract
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
@@ -50,25 +49,8 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
// TODO(b/335649589): Ideally create and obtain this from DI. This ViewModel should be scoped
// to [TaskView], and also shared between [TaskView] and [TaskThumbnailView]
// This is using a lazy for now because the dependencies cannot be obtained without DI.
val viewModel by lazy {
val recentsView =
RecentsViewContainer.containerFromContext<RecentsViewContainer>(context)
.getOverviewPanel<RecentsView<*, *>>()
TaskThumbnailViewModel(
recentsView.mRecentsViewData!!,
(parent as TaskView).taskViewData,
(parent as TaskView).getTaskContainerForTaskThumbnailView(this)!!.taskContainerData,
recentsView.mTasksRepository!!,
GetThumbnailPositionUseCase(
recentsView.mDeviceProfileRepository!!,
recentsView.mOrientedStateRepository!!,
recentsView.mTasksRepository!!
)
)
}
private val viewModel: TaskThumbnailViewModel by RecentsDependencies.inject(this)
private lateinit var viewAttachedScope: CoroutineScope
@@ -18,13 +18,12 @@ package com.android.quickstep.task.util
import android.util.Log
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
import com.android.quickstep.recents.di.RecentsDependencies
import com.android.quickstep.recents.di.get
import com.android.quickstep.task.thumbnail.TaskOverlayUiState
import com.android.quickstep.task.thumbnail.TaskOverlayUiState.Disabled
import com.android.quickstep.task.thumbnail.TaskOverlayUiState.Enabled
import com.android.quickstep.task.viewmodel.TaskOverlayViewModel
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.systemui.shared.recents.model.Task
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
@@ -42,24 +41,12 @@ class TaskOverlayHelper(val task: Task, val overlay: TaskOverlayFactory.TaskOver
private lateinit var overlayInitializedScope: CoroutineScope
private var uiState: TaskOverlayUiState = Disabled
// TODO(b/335649589): Ideally create and obtain this from DI. This ViewModel should be scoped
// to [TaskView], and also shared between [TaskView] and [TaskThumbnailView]
// This is using a lazy for now because the dependencies cannot be obtained without DI.
private val viewModel by lazy {
val recentsView =
RecentsViewContainer.containerFromContext<RecentsViewContainer>(
overlay.taskView.context
)
.getOverviewPanel<RecentsView<*, *>>()
private val viewModel: TaskOverlayViewModel by lazy {
TaskOverlayViewModel(
task,
recentsView.mRecentsViewData!!,
recentsView.mTasksRepository!!,
GetThumbnailPositionUseCase(
recentsView.mDeviceProfileRepository!!,
recentsView.mOrientedStateRepository!!,
recentsView.mTasksRepository
)
task = task,
recentsViewData = RecentsDependencies.get(),
getThumbnailPositionUseCase = RecentsDependencies.get(),
recentTasksRepository = RecentsDependencies.get()
)
}
@@ -34,14 +34,14 @@ import kotlinx.coroutines.runBlocking
class TaskOverlayViewModel(
private val task: Task,
recentsViewData: RecentsViewData,
tasksRepository: RecentTasksRepository,
private val getThumbnailPositionUseCase: GetThumbnailPositionUseCase
private val getThumbnailPositionUseCase: GetThumbnailPositionUseCase,
recentTasksRepository: RecentTasksRepository,
) {
val overlayState =
combine(
recentsViewData.overlayEnabled,
recentsViewData.settledFullyVisibleTaskIds.map { it.contains(task.key.id) },
tasksRepository.getThumbnailById(task.key.id)
recentTasksRepository.getThumbnailById(task.key.id)
) { isOverlayEnabled, isFullyVisible, thumbnailData ->
if (isOverlayEnabled && isFullyVisible) {
Enabled(
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.quickstep.task.thumbnail
package com.android.quickstep.task.viewmodel
import android.annotation.ColorInt
import android.graphics.Matrix
@@ -23,12 +23,12 @@ import com.android.quickstep.recents.data.RecentTasksRepository
import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
import com.android.quickstep.recents.usecase.ThumbnailPositionState
import com.android.quickstep.recents.viewmodel.RecentsViewData
import com.android.quickstep.task.thumbnail.TaskThumbnail
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.BackgroundOnly
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.LiveTile
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Snapshot
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
import com.android.quickstep.task.viewmodel.TaskContainerData
import com.android.quickstep.task.viewmodel.TaskViewData
import com.android.systemui.shared.recents.model.Task
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -0,0 +1,25 @@
/*
* 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.quickstep.task.viewmodel
import androidx.lifecycle.ViewModel
class TaskViewModel(private val taskViewData: TaskViewData) : ViewModel() {
fun updateScale(scale: Float) {
taskViewData.scale.value = scale
}
}
@@ -191,10 +191,12 @@ import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.TopTaskTracker;
import com.android.quickstep.ViewUtils;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.recents.data.RecentTasksRepository;
import com.android.quickstep.recents.data.RecentsDeviceProfileRepository;
import com.android.quickstep.recents.data.RecentsRotationStateRepository;
import com.android.quickstep.recents.data.TasksRepository;
import com.android.quickstep.recents.di.RecentsDependencies;
import com.android.quickstep.recents.viewmodel.RecentsViewData;
import com.android.quickstep.recents.viewmodel.RecentsViewModel;
import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.AnimUtils;
@@ -241,8 +243,9 @@ import java.util.stream.Collectors;
/**
* A list of recent tasks.
*
* @param <CONTAINER_TYPE> : the container that should host recents view
* @param <STATE_TYPE> : the type of base state that will be used
* @param <STATE_TYPE> : the type of base state that will be used
*/
public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewContainer,
@@ -391,7 +394,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
view.setScaleX(scale);
view.setScaleY(scale);
if (enableRefactorTaskThumbnail()) {
view.mRecentsViewData.getScale().setValue(scale);
view.mRecentsViewModel.updateScale(scale);
}
view.mLastComputedTaskStartPushOutDistance = null;
view.mLastComputedTaskEndPushOutDistance = null;
@@ -463,15 +466,6 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
private static final float FOREGROUND_SCRIM_TINT = 0.32f;
@Nullable
public final RecentsViewData mRecentsViewData = new RecentsViewData();
@Nullable
public final TasksRepository mTasksRepository;
@Nullable
public final RecentsRotationStateRepository mOrientedStateRepository;
@Nullable
public final RecentsDeviceProfileRepository mDeviceProfileRepository;
protected final RecentsOrientedState mOrientationState;
protected final BaseContainerInterface<STATE_TYPE, CONTAINER_TYPE> mSizeStrategy;
@Nullable
@@ -726,10 +720,12 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
private final SplitSelectionListener mSplitSelectionListener = new SplitSelectionListener() {
@Override
public void onSplitSelectionConfirmed() { }
public void onSplitSelectionConfirmed() {
}
@Override
public void onSplitSelectionActive() { }
public void onSplitSelectionActive() {
}
@Override
public void onSplitSelectionExit(boolean launchedSplit) {
@@ -808,10 +804,13 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
*/
private boolean mAnyTaskHasBeenDismissed;
private final RecentsViewModel mRecentsViewModel;
public RecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
BaseContainerInterface sizeStrategy) {
super(context, attrs, defStyleAttr);
setEnableFreeScroll(true);
mSizeStrategy = sizeStrategy;
mContainer = RecentsViewContainer.containerFromContext(context);
mOrientationState = new RecentsOrientedState(
@@ -819,22 +818,30 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
final int rotation = mContainer.getDisplay().getRotation();
mOrientationState.setRecentsRotation(rotation);
// Start Recents Dependency graph
if (enableRefactorTaskThumbnail()) {
RecentsDependencies recentsDependencies = RecentsDependencies.Companion.initialize(
this);
mRecentsViewModel = new RecentsViewModel(
recentsDependencies.inject(RecentTasksRepository.class),
recentsDependencies.inject(RecentsViewData.class)
);
recentsDependencies.provide(RecentsRotationStateRepository.class,
() -> new RecentsRotationStateRepository(mOrientationState));
recentsDependencies.provide(RecentsDeviceProfileRepository.class,
() -> new RecentsDeviceProfileRepository(mContainer));
} else {
mRecentsViewModel = null;
}
mScrollHapticMinGapMillis = getResources()
.getInteger(R.integer.recentsScrollHapticMinGapMillis);
mFastFlingVelocity = getResources()
.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
mModel = RecentsModel.INSTANCE.get(context);
mIdp = InvariantDeviceProfile.INSTANCE.get(context);
if (enableRefactorTaskThumbnail()) {
mTasksRepository = new TasksRepository(
mModel, mModel.getThumbnailCache(), mModel.getIconCache());
mOrientedStateRepository = new RecentsRotationStateRepository(mOrientationState);
mDeviceProfileRepository = new RecentsDeviceProfileRepository(mContainer);
} else {
mTasksRepository = null;
mOrientedStateRepository = null;
mDeviceProfileRepository = null;
}
mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
.inflate(R.layout.overview_clear_all_button, this, false);
@@ -1077,6 +1084,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
/**
* Update the thumbnail(s) of the relevant TaskView.
*
* @param refreshNow Refresh immediately if it's true.
*/
@Nullable
@@ -1137,6 +1145,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
/**
* See overridden implementations
*
* @return {@code true} if child TaskViews can be launched when user taps on them
*/
protected boolean canLaunchFullscreenTask() {
@@ -2061,7 +2070,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
public void setFullscreenProgress(float fullscreenProgress) {
mFullscreenProgress = fullscreenProgress;
if (enableRefactorTaskThumbnail()) {
mRecentsViewData.getFullscreenProgress().setValue(mFullscreenProgress);
mRecentsViewModel.updateFullscreenProgress(mFullscreenProgress);
}
int taskCount = getTaskViewCount();
for (int i = 0; i < taskCount; i++) {
@@ -2459,7 +2468,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
}
}
if (enableRefactorTaskThumbnail()) {
mTasksRepository.setVisibleTasks(visibleTaskIds);
mRecentsViewModel.updateVisibleTasks(visibleTaskIds);
}
}
@@ -2526,6 +2535,13 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
mFocusedTaskViewId = -1;
mAnyTaskHasBeenDismissed = false;
if (enableRefactorTaskThumbnail()) {
// TODO(b/353917593): RecentsView is never destroyed, so its dependencies need to
// be cleaned up during the reset, but re-created when RecentsView is "resumed".
// RecentsDependencies.Companion.destroy();
}
Log.d(TAG, "reset - mEnableDrawingLiveTile: " + mEnableDrawingLiveTile
+ ", mRecentsAnimationController: " + mRecentsAnimationController);
if (mEnableDrawingLiveTile) {
@@ -2636,6 +2652,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
/**
* Get the index of the task view whose id matches {@param taskId}.
*
* @return -1 if there is no task view for the task id, else the index of the task view.
*/
public int getTaskIndexForId(int taskId) {
@@ -2651,7 +2668,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
mTaskListChangeId = mModel.getTasks(this::applyLoadPlan, RecentsFilterState
.getFilter(mFilterState.getPackageNameToFilter()));
if (enableRefactorTaskThumbnail()) {
mTasksRepository.getAllTaskData(/* forceRefresh = */ true);
mRecentsViewModel.refreshAllTaskData();
}
}
}
@@ -2861,7 +2878,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
// When we create a placeholder task view mSplitBoundsConfig will be null, but with
// the actual app running we won't need to show the thumbnail until all the tasks
// load later anyways
((GroupedTaskView)taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
((GroupedTaskView) taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
mOrientationState, mTaskOverlayFactory, mSplitBoundsConfig);
} else {
taskView = getTaskViewFromPool(TaskViewType.SINGLE);
@@ -3189,7 +3206,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
(mIsRtl
? mLastComputedTaskSize.right
: deviceProfile.widthPx - mLastComputedTaskSize.left)
- longRowWidth - deviceProfile.overviewGridSideMargin;
- longRowWidth - deviceProfile.overviewGridSideMargin;
clearAllShortTotalWidthTranslation = mIsRtl
? -mClearAllShortTotalWidthTranslation : mClearAllShortTotalWidthTranslation;
if (snappedTaskRowWidth == longRowWidth) {
@@ -3219,9 +3236,9 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
(mIsRtl
? mLastComputedTaskSize.left
: deviceProfile.widthPx - mLastComputedTaskSize.right)
- deviceProfile.overviewGridSideMargin - mPageSpacing
+ (mTaskWidth - snappedTaskView.getLayoutParams().width)
- mClearAllShortTotalWidthTranslation;
- deviceProfile.overviewGridSideMargin - mPageSpacing
+ (mTaskWidth - snappedTaskView.getLayoutParams().width)
- mClearAllShortTotalWidthTranslation;
if (distanceFromClearAll < minimumDistance) {
int distanceDifference = minimumDistance - distanceFromClearAll;
snappedTaskGridTranslationX += mIsRtl ? distanceDifference : -distanceDifference;
@@ -3301,12 +3318,12 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
mLayoutTransition.addTransitionListener(new TransitionListener() {
@Override
public void startTransition(LayoutTransition transition, ViewGroup viewGroup,
View view, int i) {
View view, int i) {
}
@Override
public void endTransition(LayoutTransition transition, ViewGroup viewGroup,
View view, int i) {
View view, int i) {
// When the unpinned task is added, snap to first page and disable transitions
if (view instanceof TaskView) {
snapToPage(0);
@@ -3458,11 +3475,13 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
/**
* Creates a {@link PendingAnimation} for dismissing the specified {@link TaskView}.
* @param dismissedTaskView the {@link TaskView} to be dismissed
* @param animateTaskView whether the {@link TaskView} to be dismissed should be animated
* @param shouldRemoveTask whether the associated {@link Task} should be removed from
* ActivityManager after dismissal
* @param duration duration of the animation
*
* @param dismissedTaskView the {@link TaskView} to be dismissed
* @param animateTaskView whether the {@link TaskView} to be dismissed should be
* animated
* @param shouldRemoveTask whether the associated {@link Task} should be removed from
* ActivityManager after dismissal
* @param duration duration of the animation
* @param dismissingForSplitSelection task dismiss animation is used for entering split
* selection state from app icon
*/
@@ -3727,7 +3746,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
float animationEndProgress = isSplitSelectionActive()
? Utilities.boundToRange(splitTimings.getGridSlideStartOffset()
+ splitTimings.getGridSlideDurationOffset(), 0f, 1f)
+ splitTimings.getGridSlideDurationOffset(), 0f, 1f)
: 1f;
// Slide tiles in horizontally to fill dismissed area
@@ -3771,16 +3790,16 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
// dismissed index or next focused index. Offset successive task dismissal
// durations for a staggered effect.
distanceFromDismissedTask++;
int staggerColumn = isStagingFocusedTask
int staggerColumn = isStagingFocusedTask
? (int) Math.ceil(distanceFromDismissedTask / 2f)
: distanceFromDismissedTask;
// Set timings based on if user is initiating splitscreen on the focused task,
// or splitting/dismissing some other task.
float animationStartProgress = isStagingFocusedTask
? Utilities.boundToRange(
splitTimings.getGridSlideStartOffset()
+ (splitTimings.getGridSlideStaggerOffset()
* staggerColumn),
splitTimings.getGridSlideStartOffset()
+ (splitTimings.getGridSlideStaggerOffset()
* staggerColumn),
0f,
dismissTranslationInterpolationEnd)
: Utilities.boundToRange(
@@ -3789,9 +3808,9 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
* staggerColumn, 0f, dismissTranslationInterpolationEnd);
float animationEndProgress = isStagingFocusedTask
? Utilities.boundToRange(
splitTimings.getGridSlideStartOffset()
+ (splitTimings.getGridSlideStaggerOffset() * staggerColumn)
+ splitTimings.getGridSlideDurationOffset(),
splitTimings.getGridSlideStartOffset()
+ (splitTimings.getGridSlideStaggerOffset() * staggerColumn)
+ splitTimings.getGridSlideDurationOffset(),
0f,
dismissTranslationInterpolationEnd)
: dismissTranslationInterpolationEnd;
@@ -4007,8 +4026,9 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
RecentsView.this);
int taskSize = (int) (
getPagedOrientationHandler().getMeasuredSize(
taskView) * taskView
.getSizeAdjustment(/*fullscreenEnabled=*/false));
taskView) * taskView
.getSizeAdjustment(/*fullscreenEnabled=*/
false));
int taskEnd = taskStart + taskSize;
shouldRebalance = taskEnd >= screenEnd - mPageSpacing;
@@ -4651,6 +4671,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
/**
* Computes the distance to offset the given child such that it is completely offscreen when
* translating away from the given midpoint.
*
* @param offsetProgress From 0 to 1 where 0 means no offset and 1 means offset offscreen.
*/
private float getHorizontalOffsetSize(int childIndex, int midpointIndex, float offsetProgress) {
@@ -4872,7 +4893,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
mContainer.getDeviceProfile(),
mSplitHiddenTaskView.getWidth(), mSplitHiddenTaskView.getHeight(),
primaryTaskSelected);
builder.addOnFrameCallback(() ->{
builder.addOnFrameCallback(() -> {
// TODO(b/334826842): Handle splash icon for new TTV.
if (!enableRefactorTaskThumbnail()) {
taskContainer.getThumbnailViewDeprecated().refreshSplashView();
@@ -4896,17 +4917,21 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
* @param containerTaskView If our second selected app is currently running in Recents, this is
* the "container" TaskView from Recents. If we are starting a fresh
* instance of the app from an Intent, this will be null.
* @param task The Task corresponding to our second selected app. If we are starting a fresh
* instance of the app from an Intent, this will be null.
* @param drawable The Drawable corresponding to our second selected app's icon.
* @param secondView The View representing the current space on the screen where the second app
* is (either the ThumbnailView or the tapped icon).
* @param intent If we are launching a fresh instance of the app, this is the Intent for it. If
* the second app is already running in Recents, this will be null.
* @param user If we are launching a fresh instance of the app, this is the UserHandle for it.
* If the second app is already running in Recents, this will be null.
* @param task The Task corresponding to our second selected app. If we are
* starting a fresh
* instance of the app from an Intent, this will be null.
* @param drawable The Drawable corresponding to our second selected app's icon.
* @param secondView The View representing the current space on the screen where the
* second app
* is (either the ThumbnailView or the tapped icon).
* @param intent If we are launching a fresh instance of the app, this is the Intent
* for it. If
* the second app is already running in Recents, this will be null.
* @param user If we are launching a fresh instance of the app, this is the
* UserHandle for it.
* If the second app is already running in Recents, this will be null.
* @return true if waiting for confirmation of second app or if split animations are running,
* false otherwise
* false otherwise
*/
public boolean confirmSplitSelect(TaskView containerTaskView, Task task, Drawable drawable,
View secondView, @Nullable Bitmap thumbnail, Intent intent, UserHandle user,
@@ -4994,7 +5019,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
"Second tile selected");
// Fade out all other views underneath placeholders
ObjectAnimator tvFade = ObjectAnimator.ofFloat(this, RecentsView.CONTENT_ALPHA,1, 0);
ObjectAnimator tvFade = ObjectAnimator.ofFloat(this, RecentsView.CONTENT_ALPHA, 1, 0);
pendingAnimation.add(tvFade, DECELERATE_2, SpringProperty.DEFAULT);
pendingAnimation.buildAnim().start();
return true;
@@ -5142,7 +5167,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
if (mShowEmptyMessage && hasValidSize && mEmptyTextLayout == null) {
int availableWidth = mLastMeasureSize.x - mEmptyMessagePadding - mEmptyMessagePadding;
mEmptyTextLayout = StaticLayout.Builder.obtain(mEmptyMessage, 0, mEmptyMessage.length(),
mEmptyMessagePaint, availableWidth)
mEmptyMessagePaint, availableWidth)
.setAlignment(Layout.Alignment.ALIGN_CENTER)
.build();
int totalHeight = mEmptyTextLayout.getHeight()
@@ -5269,7 +5294,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
updateScrollSynchronously();
int targetSysUiFlags = tv.getTaskContainers().getFirst().getSysUiStatusNavFlags();
final boolean[] passedOverviewThreshold = new boolean[] {false};
final boolean[] passedOverviewThreshold = new boolean[]{false};
ValueAnimator progressAnim = ValueAnimator.ofFloat(0, 1);
progressAnim.addUpdateListener(animator -> {
// Once we pass a certain threshold, update the sysui flags to match the target
@@ -5390,7 +5415,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
fullyVisibleTaskIds.addAll(taskIds);
}
}
mRecentsViewData.getSettledFullyVisibleTaskIds().setValue(fullyVisibleTaskIds);
mRecentsViewModel.updateTasksFullyVisible(fullyVisibleTaskIds);
}
}
@@ -5789,6 +5814,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
* Sets whether or not we should clamp the scroll offset.
* This is used to avoid x-axis movement when swiping up transient taskbar.
* Should only be set at the beginning and end of the gesture, otherwise a jump may occur.
*
* @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is
* met.
*/
@@ -5821,11 +5847,11 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
// Don't dampen the scroll (due to overscroll) if the adjacent tasks are offscreen, so that
// the page can move freely given there's no visual indication why it shouldn't.
int overScrollShift = mAdjacentPageHorizontalOffset > 0
? (int) Utilities.mapRange(
mAdjacentPageHorizontalOffset,
getOverScrollShift(),
getUndampedOverScrollShift())
: getOverScrollShift();
? (int) Utilities.mapRange(
mAdjacentPageHorizontalOffset,
getOverScrollShift(),
getUndampedOverScrollShift())
: getOverScrollShift();
return getScrollForPage(pageIndex) - getPagedOrientationHandler().getPrimaryScroll(this)
+ overScrollShift + getOffsetFromScrollPosition(pageIndex);
}
@@ -5942,7 +5968,10 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
if (mOverlayEnabled != overlayEnabled) {
mOverlayEnabled = overlayEnabled;
updateEnabledOverlays();
mRecentsViewData.getOverlayEnabled().setValue(overlayEnabled);
if (enableRefactorTaskThumbnail()) {
mRecentsViewModel.setOverlayEnabled(overlayEnabled);
}
}
}
@@ -6130,7 +6159,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
public boolean showAsGrid() {
return mOverviewGridEnabled || (mCurrentGestureEndTarget != null
&& mSizeStrategy.stateFromGestureEndTarget(mCurrentGestureEndTarget)
.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
}
private boolean showAsFullscreen() {
@@ -6171,7 +6200,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
/**
* @return Corner radius in pixel value for PiP window, which is updated via
* {@link #mIPipAnimationListener}
* {@link #mIPipAnimationListener}
*/
public int getPipCornerRadius() {
return mPipCornerRadius;
@@ -6179,7 +6208,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
/**
* @return Shadow radius in pixel value for PiP window, which is updated via
* {@link #mIPipAnimationListener}
* {@link #mIPipAnimationListener}
*/
public int getPipShadowRadius() {
return mPipShadowRadius;
@@ -29,10 +29,15 @@ import com.android.launcher3.util.SplitConfigurationOptions
import com.android.launcher3.util.TransformingTouchDelegate
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.TaskUtils
import com.android.quickstep.recents.di.RecentsDependencies
import com.android.quickstep.recents.di.get
import com.android.quickstep.recents.di.getScope
import com.android.quickstep.recents.di.inject
import com.android.quickstep.recents.usecase.GetThumbnailUseCase
import com.android.quickstep.task.thumbnail.TaskThumbnail
import com.android.quickstep.task.thumbnail.TaskThumbnailView
import com.android.quickstep.task.viewmodel.TaskContainerData
import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
import com.android.systemui.shared.recents.model.Task
/** Holder for all Task dependent information. */
@@ -55,21 +60,22 @@ class TaskContainer(
taskOverlayFactory: TaskOverlayFactory
) {
val overlay: TaskOverlayFactory.TaskOverlay<*> = taskOverlayFactory.createOverlay(this)
val taskContainerData = TaskContainerData()
private val getThumbnailUseCase by lazy {
// TODO(b/335649589): Ideally create and obtain this from DI.
val recentsView =
RecentsViewContainer.containerFromContext<RecentsViewContainer>(
overlay.taskView.context
)
.getOverviewPanel<RecentsView<*, *>>()
GetThumbnailUseCase(recentsView.mTasksRepository!!)
}
lateinit var taskContainerData: TaskContainerData
private val getThumbnailUseCase: GetThumbnailUseCase by RecentsDependencies.inject()
private val taskThumbnailViewModel: TaskThumbnailViewModel by
RecentsDependencies.inject(snapshotView)
init {
if (enableRefactorTaskThumbnail()) {
require(snapshotView is TaskThumbnailView)
taskContainerData = RecentsDependencies.get(this)
RecentsDependencies.getScope(snapshotView).apply {
val taskViewScope = RecentsDependencies.getScope(taskView)
linkTo(taskViewScope)
val taskContainerScope = RecentsDependencies.getScope(this)
linkTo(taskContainerScope)
}
} else {
require(snapshotView is TaskThumbnailViewDeprecated)
}
@@ -146,12 +152,10 @@ class TaskContainer(
overlay.destroy()
}
// TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
// so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
fun bindThumbnailView() {
// TODO(b/343364498): Existing view has shouldShowScreenshot as an override as well but
// this should be decided inside TaskThumbnailViewModel.
thumbnailView.viewModel.bind(TaskThumbnail(task.key.id, taskView.isRunningTask))
taskThumbnailViewModel.bind(TaskThumbnail(task.key.id, taskView.isRunningTask))
}
fun setOverlayEnabled(enabled: Boolean) {
@@ -80,8 +80,10 @@ import com.android.quickstep.TaskAnimationManager
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.TaskViewUtils
import com.android.quickstep.orientation.RecentsPagedOrientationHandler
import com.android.quickstep.recents.di.RecentsDependencies
import com.android.quickstep.recents.di.get
import com.android.quickstep.task.thumbnail.TaskThumbnailView
import com.android.quickstep.task.viewmodel.TaskViewData
import com.android.quickstep.task.viewmodel.TaskViewModel
import com.android.quickstep.util.ActiveGestureErrorDetector
import com.android.quickstep.util.ActiveGestureLog
import com.android.quickstep.util.BorderAnimator
@@ -115,7 +117,8 @@ constructor(
@IntDef(FLAG_UPDATE_ALL, FLAG_UPDATE_ICON, FLAG_UPDATE_THUMBNAIL, FLAG_UPDATE_CORNER_RADIUS)
annotation class TaskDataChanges
val taskViewData = TaskViewData(type)
private lateinit var taskViewModel: TaskViewModel
val taskIds: IntArray
/** Returns a copy of integer array containing taskIds of all tasks in the TaskView. */
get() = taskContainers.map { it.task.key.id }.toIntArray()
@@ -441,6 +444,11 @@ constructor(
init {
setOnClickListener { _ -> onClick() }
if (enableRefactorTaskThumbnail()) {
taskViewModel = RecentsDependencies.get(this, "TaskViewType" to type)
}
val keyboardFocusHighlightEnabled =
(ENABLE_KEYBOARD_QUICK_SWITCH.get() || enableFocusOutline())
val cursorHoverStatesEnabled = enableCursorHoverStates()
@@ -638,6 +646,7 @@ constructor(
orientedState: RecentsOrientedState,
taskOverlayFactory: TaskOverlayFactory
) {
cancelPendingLoadTasks()
taskContainers =
listOf(
@@ -1404,7 +1413,7 @@ constructor(
scaleX = scale
scaleY = scale
if (enableRefactorTaskThumbnail()) {
taskViewData.scale.value = scale
taskViewModel.updateScale(scale)
}
updateSnapshotRadius()
}
@@ -1483,8 +1492,6 @@ constructor(
/** Updates [TaskThumbnailView] to reflect the latest [Task] state (i.e., task isRunning). */
fun notifyIsRunningTaskUpdated() {
// TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
// so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
taskContainers.forEach { it.bindThumbnailView() }
}
@@ -0,0 +1,131 @@
/*
* 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.quickstep.logging
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.launcher3.LauncherPrefs
import com.android.launcher3.LauncherPrefs.Companion.backedUpItem
import com.android.launcher3.logging.InstanceId
import com.android.launcher3.logging.StatsLogManager
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.atLeastOnce
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class SettingsChangeLoggerTest {
private val mContext: Context = ApplicationProvider.getApplicationContext()
private val mInstanceId = InstanceId.fakeInstanceId(1)
private lateinit var mSystemUnderTest: SettingsChangeLogger
@Mock private lateinit var mStatsLogManager: StatsLogManager
@Mock private lateinit var mMockLogger: StatsLogManager.StatsLogger
@Captor private lateinit var mEventCaptor: ArgumentCaptor<StatsLogManager.EventEnum>
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
whenever(mStatsLogManager.logger()).doReturn(mMockLogger)
whenever(mStatsLogManager.logger().withInstanceId(any())).doReturn(mMockLogger)
mSystemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager)
}
@After
fun tearDown() {
mSystemUnderTest.close()
}
@Test
fun loggingPrefs_correctDefaultValue() {
assertThat(mSystemUnderTest.loggingPrefs["pref_allowRotation"]!!.defaultValue).isFalse()
assertThat(mSystemUnderTest.loggingPrefs["pref_add_icon_to_home"]!!.defaultValue).isTrue()
assertThat(mSystemUnderTest.loggingPrefs["pref_overview_action_suggestions"]!!.defaultValue)
.isTrue()
assertThat(mSystemUnderTest.loggingPrefs["pref_smartspace_home_screen"]!!.defaultValue)
.isTrue()
assertThat(mSystemUnderTest.loggingPrefs["pref_enable_minus_one"]!!.defaultValue).isTrue()
}
@Test
fun logSnapshot_defaultValue() {
mSystemUnderTest.logSnapshot(mInstanceId)
verify(mMockLogger, atLeastOnce()).log(mEventCaptor.capture())
val capturedEvents = mEventCaptor.allValues
assertThat(capturedEvents.isNotEmpty()).isTrue()
verifyDefaultEvent(capturedEvents)
// pref_allowRotation false
assertThat(capturedEvents.any { it.id == 616 }).isTrue()
}
@Test
fun logSnapshot_updateValue() {
LauncherPrefs.get(mContext)
.put(
item =
backedUpItem(
sharedPrefKey = "pref_allowRotation",
defaultValue = false,
),
value = true
)
mSystemUnderTest.logSnapshot(mInstanceId)
verify(mMockLogger, atLeastOnce()).log(mEventCaptor.capture())
val capturedEvents = mEventCaptor.allValues
assertThat(capturedEvents.isNotEmpty()).isTrue()
verifyDefaultEvent(capturedEvents)
// pref_allowRotation true
assertThat(capturedEvents.any { it.id == 615 }).isTrue()
}
private fun verifyDefaultEvent(capturedEvents: MutableList<StatsLogManager.EventEnum>) {
// LAUNCHER_NOTIFICATION_DOT_ENABLED
assertThat(capturedEvents.any { it.id == 611 }).isTrue()
// LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON
assertThat(capturedEvents.any { it.id == 625 }).isTrue()
// LAUNCHER_THEMED_ICON_DISABLED
assertThat(capturedEvents.any { it.id == 837 }).isTrue()
// pref_add_icon_to_home true
assertThat(capturedEvents.any { it.id == 613 }).isTrue()
// pref_overview_action_suggestions true
assertThat(capturedEvents.any { it.id == 619 }).isTrue()
// pref_smartspace_home_screen true
assertThat(capturedEvents.any { it.id == 621 }).isTrue()
// pref_enable_minus_one true
assertThat(capturedEvents.any { it.id == 617 }).isTrue()
}
}
@@ -32,6 +32,7 @@ import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.LiveTile
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Snapshot
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
import com.android.quickstep.task.viewmodel.TaskContainerData
import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
import com.android.quickstep.task.viewmodel.TaskViewData
import com.android.quickstep.views.TaskViewType
import com.android.systemui.shared.recents.model.Task
@@ -59,7 +59,7 @@ class TaskOverlayViewModelTest {
private val tasksRepository = FakeTasksRepository()
private val mGetThumbnailPositionUseCase = mock<GetThumbnailPositionUseCase>()
private val systemUnderTest =
TaskOverlayViewModel(task, recentsViewData, tasksRepository, mGetThumbnailPositionUseCase)
TaskOverlayViewModel(task, recentsViewData, mGetThumbnailPositionUseCase, tasksRepository)
@Test
fun initialStateIsDisabled() = runTest {
@@ -16,6 +16,8 @@
package com.android.quickstep;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.TestCase.assertNull;
import static org.junit.Assert.assertEquals;
@@ -69,14 +71,14 @@ public class RecentTasksListTest {
}
@Test
public void onRecentTasksChanged_doesNotFetchTasks() {
public void onRecentTasksChanged_doesNotFetchTasks() throws Exception {
mRecentTasksList.onRecentTasksChanged();
verify(mockSystemUiProxy, times(0))
.getRecentTasks(anyInt(), anyInt());
}
@Test
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() throws Exception {
GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(
new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo(), null);
when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
@@ -91,7 +93,19 @@ public class RecentTasksListTest {
}
@Test
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() {
public void loadTasksInBackground_GetRecentTasksException() throws Exception {
when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenThrow(new SystemUiProxy.GetRecentTasksException("task load failed"));
RecentTasksList.TaskLoadResult taskList = mRecentTasksList.loadTasksInBackground(
Integer.MAX_VALUE, -1, false);
assertThat(taskList.mRequestId).isEqualTo(-1);
assertThat(taskList).isEmpty();
}
@Test
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() throws Exception {
String taskDescription = "Wheeee!";
ActivityManager.RecentTaskInfo task1 = new ActivityManager.RecentTaskInfo();
task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
@@ -111,7 +125,7 @@ public class RecentTasksListTest {
}
@Test
public void loadTasksInBackground_freeformTask_createsDesktopTask() {
public void loadTasksInBackground_freeformTask_createsDesktopTask() throws Exception {
ActivityManager.RecentTaskInfo[] tasks = {
createRecentTaskInfo(1 /* taskId */),
createRecentTaskInfo(4 /* taskId */),
@@ -134,7 +148,8 @@ public class RecentTasksListTest {
}
@Test
public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_doesNotCreateDesktopTask() {
public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_doesNotCreateDesktopTask()
throws Exception {
ActivityManager.RecentTaskInfo[] tasks = {
createRecentTaskInfo(1 /* taskId */),
createRecentTaskInfo(4 /* taskId */),
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="6" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="24" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="12" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="17" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="22" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="10" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="4" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="6" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="98" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="6" />
</selector>
+2 -3
View File
@@ -12,7 +12,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:color="?androidprv:attr/materialColorSurfaceContainer"/>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/materialColorSurfaceContainer"/>
</selector>
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="98" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="98" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="94" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="92" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="90" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="96" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="100" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="87" />
</selector>
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="6" />
</selector>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="87" />
</selector>
+2 -3
View File
@@ -13,7 +13,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:color="?androidprv:attr/materialColorSurfaceContainer"/>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/materialColorSurfaceContainer"/>
</selector>
+3 -4
View File
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:alpha="1"
android:color="?androidprv:attr/materialColorOnSurface"
android:color="?attr/materialColorOnSurface"
android:state_enabled="true" />
<item
android:alpha="?android:disabledAlpha"
android:color="?androidprv:attr/materialColorOnSurface"
android:color="?attr/materialColorOnSurface"
android:state_enabled="false" />
</selector>
+2 -3
View File
@@ -13,7 +13,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:color="?androidprv:attr/materialColorSurfaceContainer"/>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/materialColorSurfaceContainer"/>
</selector>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="@color/material_color_surface_container_highest" />
<solid android:color="?attr/materialColorSurfaceContainerHighest" />
<corners
android:topLeftRadius="?android:attr/dialogCornerRadius"
android:topRightRadius="?android:attr/dialogCornerRadius" />
+2 -2
View File
@@ -30,7 +30,7 @@
android:state_selected="false">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="@color/material_color_surface_bright" />
<solid android:color="?attr/materialColorSurfaceBright" />
</shape>
</item>
@@ -39,7 +39,7 @@
android:state_selected="true">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="@color/material_color_primary" />
<solid android:color="?attr/materialColorPrimary" />
</shape>
</item>
</selector>
@@ -15,8 +15,7 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle" >
<solid android:color="?androidprv:attr/materialColorOutlineVariant"/>
<solid android:color="?attr/materialColorOutlineVariant"/>
<corners android:radius="@dimen/bottom_sheet_handle_corner_radius" />
</shape>
@@ -25,7 +25,7 @@
android:topRightRadius="12dp"
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp" />
<solid android:color="@color/material_color_surface_container_highest"/>
<solid android:color="?attr/materialColorSurfaceContainerHighest"/>
<stroke
android:width="2dp"
android:color="@color/button_bg"/>
+1 -1
View File
@@ -20,6 +20,6 @@
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@color/material_color_on_surface"
android:fillColor="?attr/materialColorOnSurface"
android:pathData="M256,760L200,704L424,480L200,256L256,200L480,424L704,200L760,256L536,480L760,704L704,760L480,536L256,760Z"/>
</vector>
@@ -13,14 +13,13 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:viewportWidth="48"
android:viewportHeight="48"
android:width="48dp"
android:height="48dp">
<path
android:pathData="M48 24A24 24 0 0 1 0 24A24 24 0 0 1 48 24Z"
android:fillColor="?androidprv:attr/materialColorSurfaceContainerLowest" />
android:fillColor="?attr/materialColorSurfaceContainerLowest" />
<path
android:pathData="M24.0021 10.6641L13.3354 14.6641V22.7841C13.3354 29.5174 17.8821 35.7974 24.0021 37.3307C30.1221 35.7974 34.6688 29.5174 34.6688 22.7841V14.6641L24.0021 10.6641ZM32.0021 22.7841C32.0021 28.1174 28.6021 33.0507 24.0021 34.5574C19.4021 33.0507 16.0021 28.1307 16.0021 22.7841V16.5174L24.0021 13.5174L32.0021 16.5174V22.7841Z"
android:fillType="evenOdd"
+2 -3
View File
@@ -15,14 +15,13 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:autoMirrored="true">
<gradient
android:type="linear"
android:angle="0"
android:startColor="#00000000"
android:centerX="0.25"
android:centerColor="?androidprv:attr/materialColorSurfaceBright"
android:endColor="?androidprv:attr/materialColorSurfaceBright" />
android:centerColor="?attr/materialColorSurfaceBright"
android:endColor="?attr/materialColorSurfaceBright" />
<corners android:radius="@dimen/dialogCornerRadius" />
</shape>
@@ -23,9 +23,9 @@
android:pathData="M30 0H30A30 30 0 0 1 60 30V30A30 30 0 0 1 30 60H30A30 30 0 0 1 0 30V30A30 30 0 0 1 30 0Z" />
<path
android:pathData="M30 0H30A30 30 0 0 1 60 30V30A30 30 0 0 1 30 60H30A30 30 0 0 1 0 30V30A30 30 0 0 1 30 0Z"
android:fillColor="@color/material_color_surface_container_lowest" />
android:fillColor="?attr/materialColorSurfaceContainerLowest" />
<path
android:pathData="M29 31h-6v-2h6v-6h2v6h6v2h-6v6h-2v-6Z"
android:fillColor="@color/material_color_on_surface" />
android:fillColor="?attr/materialColorOnSurface" />
</group>
</vector>
+3 -4
View File
@@ -7,7 +7,7 @@
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ Unless required by applicable law or agreed to in writing, soft]ware
~ 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
@@ -16,13 +16,12 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<solid android:color="@color/material_color_surface_container_low" />
<solid android:color="?attr/materialColorSurfaceContainerLow" />
<corners android:radius="@dimen/rounded_button_radius" />
<stroke
android:width="1dp"
android:color="@color/material_color_surface_container_low" />
android:color="?attr/materialColorSurfaceContainerLow" />
<padding
android:left="@dimen/rounded_button_padding"
android:right="@dimen/rounded_button_padding" />
+1 -1
View File
@@ -17,7 +17,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/material_color_surface_container_highest" />
<solid android:color="?attr/materialColorSurfaceContainerHighest" />
<corners android:radius="@dimen/work_edu_card_radius" />
</shape>
+2 -2
View File
@@ -61,7 +61,7 @@
android:layout_marginBottom="@dimen/ps_lock_icon_margin_bottom"
android:importantForAccessibility="no"
android:src="@drawable/ic_lock"
app:tint="@color/material_color_primary_fixed_dim"
app:tint="?attr/materialColorPrimaryFixedDim"
android:scaleType="center"/>
<TextView
android:id="@+id/lock_text"
@@ -69,7 +69,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/ps_lock_icon_text_margin_start_expanded"
android:layout_marginEnd="@dimen/ps_lock_icon_text_margin_end_expanded"
android:textColor="@color/material_color_on_primary_fixed"
android:textColor="?attr/materialColorOnPrimaryFixed"
android:textSize="14sp"
android:text="@string/ps_container_lock_title"
android:maxLines="1"
-35
View File
@@ -57,39 +57,4 @@
@android:color/system_accent1_200</color>
<color name="work_fab_icon_color">
@android:color/system_accent1_900</color>
<color name="material_color_on_secondary_fixed_variant">@android:color/system_accent2_700</color>
<color name="material_color_on_tertiary_fixed_variant">@android:color/system_accent3_700</color>
<color name="material_color_on_primary_fixed_variant">@android:color/system_accent1_700</color>
<color name="material_color_on_secondary_container">@android:color/system_accent2_100</color>
<color name="material_color_on_tertiary_container">@android:color/system_accent3_100</color>
<color name="material_color_on_primary_container">@android:color/system_accent1_100</color>
<color name="material_color_secondary_fixed_dim">@android:color/system_accent2_200</color>
<color name="material_color_on_error_container">#FFDAD5</color>
<color name="material_color_on_secondary_fixed">@android:color/system_accent2_900</color>
<color name="material_color_on_surface_inverse">@android:color/system_neutral1_900</color>
<color name="material_color_tertiary_fixed_dim">@android:color/system_accent3_200</color>
<color name="material_color_on_tertiary_fixed">@android:color/system_accent3_900</color>
<color name="material_color_primary_fixed_dim">@android:color/system_accent1_200</color>
<color name="material_color_secondary_container">@android:color/system_accent2_700</color>
<color name="material_color_error_container">#930001</color>
<color name="material_color_on_primary_fixed">@android:color/system_accent1_900</color>
<color name="material_color_primary_inverse">@android:color/system_accent1_600</color>
<color name="material_color_secondary_fixed">@android:color/system_accent2_100</color>
<color name="material_color_tertiary_container">@android:color/system_accent3_700</color>
<color name="material_color_tertiary_fixed">@android:color/system_accent3_100</color>
<color name="material_color_primary_container">@android:color/system_accent1_700</color>
<color name="material_color_on_background">@android:color/system_neutral1_800</color>
<color name="material_color_primary_fixed">@android:color/system_accent1_100</color>
<color name="material_color_on_secondary">@android:color/system_accent2_800</color>
<color name="material_color_on_tertiary">@android:color/system_accent3_800</color>
<color name="material_color_on_error">#690001</color>
<color name="material_color_on_surface_variant">@android:color/system_neutral2_200</color>
<color name="material_color_outline">@android:color/system_neutral2_400</color>
<color name="material_color_outline_variant">@android:color/system_neutral2_700</color>
<color name="material_color_on_primary">@android:color/system_accent1_800</color>
<color name="material_color_on_surface">@android:color/system_neutral1_100</color>
<color name="material_color_primary">@android:color/system_accent1_200</color>
<color name="material_color_secondary">@android:color/system_accent2_200</color>
<color name="material_color_tertiary">@android:color/system_accent3_200</color>
</resources>
-64
View File
@@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2023, 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.
*/
-->
<resources>
<color name="material_color_on_secondary_fixed_variant">#3F4759</color>
<color name="material_color_on_tertiary_fixed_variant">#583E5B</color>
<color name="material_color_surface_container_lowest">#0D0E11</color>
<color name="material_color_on_primary_fixed_variant">#2B4678</color>
<color name="material_color_on_secondary_container">#DBE2F9</color>
<color name="material_color_on_tertiary_container">#FBD7FC</color>
<color name="material_color_surface_container_low">#1B1B1F</color>
<color name="material_color_on_primary_container">#D8E2FF</color>
<color name="material_color_secondary_fixed_dim">#BFC6DC</color>
<color name="material_color_on_error_container">#FFDAD5</color>
<color name="material_color_on_secondary_fixed">#141B2C</color>
<color name="material_color_on_surface_inverse">#1B1B1F</color>
<color name="material_color_tertiary_fixed_dim">#DEBCDF</color>
<color name="material_color_on_tertiary_fixed">#29132D</color>
<color name="material_color_primary_fixed_dim">#ADC6FF</color>
<color name="material_color_secondary_container">#3F4759</color>
<color name="material_color_error_container">#930001</color>
<color name="material_color_on_primary_fixed">#001A41</color>
<color name="material_color_primary_inverse">#445E91</color>
<color name="material_color_secondary_fixed">#DBE2F9</color>
<color name="material_color_surface_inverse">#FAF9FD</color>
<color name="material_color_surface_variant">#44474F</color>
<color name="material_color_tertiary_container">#583E5B</color>
<color name="material_color_tertiary_fixed">#FBD7FC</color>
<color name="material_color_primary_container">#2B4678</color>
<color name="material_color_on_background">#E3E2E6</color>
<color name="material_color_primary_fixed">#D8E2FF</color>
<color name="material_color_on_secondary">#293041</color>
<color name="material_color_on_tertiary">#402843</color>
<color name="material_color_surface_dim">#121316</color>
<color name="material_color_surface_bright">#38393C</color>
<color name="material_color_on_error">#690001</color>
<color name="material_color_surface">#121316</color>
<color name="material_color_surface_container_high">#292A2D</color>
<color name="material_color_surface_container_highest">#343538</color>
<color name="material_color_on_surface_variant">#C4C6D0</color>
<color name="material_color_outline">#72747D</color>
<color name="material_color_outline_variant">#444746</color>
<color name="material_color_on_primary">#102F60</color>
<color name="material_color_on_surface">#E3E2E6</color>
<color name="material_color_surface_container">#1F1F23</color>
<color name="material_color_primary">#ADC6FF</color>
<color name="material_color_secondary">#BFC6DC</color>
<color name="material_color_tertiary">#DEBCDF</color>
</resources>
+49
View File
@@ -26,7 +26,56 @@
<item name="android:backgroundDimEnabled">true</item>
</style>
<style name="DynamicColorsBaseLauncherTheme" parent="@style/BaseLauncherTheme">
<item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
<item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
<item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
<item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
<item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
<item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
<item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
<item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
<item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
<item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
<item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
<item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
<item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
<item name="materialColorOnError">@color/system_on_error_dark</item>
<item name="materialColorSurface">@color/system_surface_dark</item>
<item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
<item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
<item name="materialColorPrimary">@color/system_primary_dark</item>
<item name="materialColorSecondary">@color/system_secondary_dark</item>
<item name="materialColorTertiary">@color/system_tertiary_dark</item>
<item name="materialColorError">@color/system_error_dark</item>
</style>
<style name="WidgetPickerActivityTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
+1
View File
@@ -29,5 +29,6 @@
<item name="android:windowLayoutInDisplayCutoutMode">always</item>
<item name="android:enforceStatusBarContrast">false</item>
<item name="android:enforceNavigationBarContrast">false</item>
<item name="materialColorOnPrimaryFixed">#FFFFFFFF</item>
</style>
</resources>

Some files were not shown because too many files have changed in this diff Show More