Loading quickstep/src/com/android/quickstep/TaskShortcutFactory.java +6 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.view.Surface.ROTATION_0; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.window.flags.Flags.enableDesktopWindowingMode; import android.app.ActivityOptions; Loading Loading @@ -107,10 +108,14 @@ public interface TaskShortcutFactory { public List<SystemShortcut> getShortcuts(RecentsViewContainer container, TaskContainer taskContainer) { TaskView taskView = taskContainer.getTaskView(); int actionId = taskContainer.getStagePosition() == STAGE_POSITION_BOTTOM_OR_RIGHT ? R.id.action_app_info_bottom_right : R.id.action_app_info_top_left; AppInfo.SplitAccessibilityInfo accessibilityInfo = new AppInfo.SplitAccessibilityInfo(taskView.containsMultipleTasks(), TaskUtils.getTitle(taskView.getContext(), taskContainer.getTask()), taskContainer.getA11yNodeId() actionId ); return Collections.singletonList(new AppInfo(container, taskContainer.getItemInfo(), taskView, accessibilityInfo)); Loading quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java +38 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.launcher3.util.Executors.ORDERED_BG_EXECUTOR; import android.app.ActivityOptions; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.pm.LauncherApps.AppUsageLimit; Loading @@ -38,6 +39,7 @@ import android.util.Pair; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.TextView; Loading @@ -49,6 +51,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; import com.android.quickstep.TaskUtils; import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.systemui.shared.recents.model.Task; Loading @@ -68,13 +71,15 @@ public final class DigitalWellBeingToast { private static final int SPLIT_GRID_BANNER_LARGE = 1; /** Used for grid task view, only showing icon */ private static final int SPLIT_GRID_BANNER_SMALL = 2; @IntDef(value = { SPLIT_BANNER_FULLSCREEN, SPLIT_GRID_BANNER_LARGE, SPLIT_GRID_BANNER_SMALL, }) @Retention(RetentionPolicy.SOURCE) @interface SplitBannerConfig{} @interface SplitBannerConfig { } static final Intent OPEN_APP_USAGE_SETTINGS_TEMPLATE = new Intent(ACTION_APP_USAGE_SETTINGS); static final int MINUTE_MS = 60000; Loading Loading @@ -398,4 +403,36 @@ public final class DigitalWellBeingToast { mBanner.setVisibility(visibility); } private int getAccessibilityActionId() { return (mSplitBounds != null && mSplitBounds.rightBottomTaskId == mTask.key.id) ? R.id.action_digital_wellbeing_bottom_right : R.id.action_digital_wellbeing_top_left; } @Nullable public AccessibilityNodeInfo.AccessibilityAction getDWBAccessibilityAction() { if (!hasLimit()) { return null; } Context context = mContainer.asContext(); String label = (mTaskView.containsMultipleTasks()) ? context.getString( R.string.split_app_usage_settings, TaskUtils.getTitle(context, mTask) ) : context.getString(R.string.accessibility_app_usage_settings); return new AccessibilityNodeInfo.AccessibilityAction(getAccessibilityActionId(), label); } public boolean handleAccessibilityAction(int action) { if (getAccessibilityActionId() == action) { openAppUsageSettings(mTaskView); return true; } else { return false; } } } quickstep/src/com/android/quickstep/views/TaskView.kt +51 −22 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.view.View.OnClickListener import android.view.ViewGroup import android.view.ViewStub import android.view.accessibility.AccessibilityNodeInfo import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.FrameLayout import android.widget.Toast import androidx.annotation.IntDef Loading Loading @@ -67,7 +68,6 @@ import com.android.launcher3.util.Executors import com.android.launcher3.util.RunnableList import com.android.launcher3.util.SafeCloseable import com.android.launcher3.util.SplitConfigurationOptions import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption import com.android.launcher3.util.SplitConfigurationOptions.StagePosition Loading Loading @@ -133,19 +133,26 @@ constructor( 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() val thumbnailViews: Array<TaskThumbnailViewDeprecated> get() = taskContainers.map { it.thumbnailViewDeprecated }.toTypedArray() val isGridTask: Boolean /** Returns whether the task is part of overview grid and not being focused. */ get() = container.deviceProfile.isTablet && !isFocusedTask val isRunningTask: Boolean get() = this === recentsView?.runningTaskView val isFocusedTask: Boolean get() = this === recentsView?.focusedTaskView val taskCornerRadius: Float get() = currentFullscreenParams.cornerRadius val recentsView: RecentsView<*, *>? get() = parent as? RecentsView<*, *> val pagedOrientationHandler: RecentsPagedOrientationHandler get() = orientedState.orientationHandler Loading @@ -153,10 +160,12 @@ constructor( val firstTask: Task /** Returns the first task bound to this TaskView. */ get() = taskContainers[0].task @get:Deprecated("Use [taskContainers] instead.") val firstThumbnailViewDeprecated: TaskThumbnailViewDeprecated /** Returns the first thumbnailView of the TaskView. */ get() = taskContainers[0].thumbnailViewDeprecated @get:Deprecated("Use [taskContainers] instead.") val firstItemInfo: ItemInfo get() = taskContainers[0].itemInfo Loading @@ -173,6 +182,7 @@ constructor( * not change according to a temporary state. */ get() = Utilities.mapRange(gridProgress, nonGridScale, 1f) protected val persistentTranslationX: Float /** * Returns addition of translationX that is persistent (e.g. fullscreen and grid), and does Loading @@ -182,42 +192,50 @@ constructor( (getNonGridTrans(nonGridTranslationX) + getGridTrans(this.gridTranslationX) + getNonGridTrans(nonGridPivotTranslationX)) protected val persistentTranslationY: Float /** * Returns addition of translationY that is persistent (e.g. fullscreen and grid), and does * not change according to a temporary state (e.g. task offset). */ get() = boxTranslationY + getGridTrans(gridTranslationY) protected val primarySplitTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getPrimaryValue( SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y ) protected val secondarySplitTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue( SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y ) protected val primaryDismissTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getPrimaryValue(DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y) protected val secondaryDismissTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue(DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y) protected val primaryTaskOffsetTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getPrimaryValue( TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y ) protected val secondaryTaskOffsetTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue( TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y ) protected val taskResistanceTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue( Loading @@ -234,6 +252,7 @@ constructor( /** Returns a list of all TaskContainers in the TaskView. */ lateinit var taskContainers: List<TaskContainer> protected set lateinit var orientedState: RecentsOrientedState var taskViewId = UNBOUND_TASK_VIEW_ID Loading Loading @@ -264,46 +283,55 @@ constructor( field = value onModalnessUpdated(field) } protected var taskThumbnailSplashAlpha = 0f set(value) { field = value applyThumbnailSplashAlpha() } protected var nonGridScale = 1f set(value) { field = value applyScale() } private var dismissScale = 1f set(value) { field = value applyScale() } private var dismissTranslationX = 0f set(value) { field = value applyTranslationX() } private var dismissTranslationY = 0f set(value) { field = value applyTranslationY() } private var taskOffsetTranslationX = 0f set(value) { field = value applyTranslationX() } private var taskOffsetTranslationY = 0f set(value) { field = value applyTranslationY() } private var taskResistanceTranslationX = 0f set(value) { field = value applyTranslationX() } private var taskResistanceTranslationY = 0f set(value) { field = value Loading @@ -321,6 +349,7 @@ constructor( field = value applyTranslationX() } var gridTranslationY = 0f protected set(value) { field = value Loading @@ -339,6 +368,7 @@ constructor( field = value applyTranslationX() } protected var nonGridPivotTranslationX = 0f set(value) { field = value Loading @@ -350,16 +380,19 @@ constructor( field = value applyTranslationY() } private var splitSelectTranslationX = 0f set(value) { field = value applyTranslationX() } protected var stableAlpha = 1f set(value) { field = value alpha = stableAlpha } protected var shouldShowScreenshot = false get() = !isRunningTask || field /** Enable or disable showing border on hover and focus change */ Loading @@ -375,6 +408,7 @@ constructor( hoverBorderAnimator?.setBorderVisibility(visible = field && isHovered, animated = true) focusBorderAnimator?.setBorderVisibility(visible = field && isFocused, animated = true) } protected var iconScaleAnimStartProgress = 0f private var focusTransitionProgress = 1f Loading Loading @@ -522,11 +556,12 @@ constructor( super.onInitializeAccessibilityNodeInfo(info) with(info) { addAction( AccessibilityNodeInfo.AccessibilityAction( R.string.accessibility_close, AccessibilityAction( R.id.action_close, context.getText(R.string.accessibility_close) ) ) taskContainers.forEach { TraceHelper.allowIpcs("TV.a11yInfo") { TaskOverlayFactory.getEnabledShortcuts(this@TaskView, it).forEach { shortcut -> Loading @@ -534,15 +569,12 @@ constructor( } } } // TODO(b/341672022): handle multiple digitalWellBeingToast accessibility actions if (taskContainers[0].digitalWellBeingToast?.hasLimit() == true) { addAction( AccessibilityNodeInfo.AccessibilityAction( R.string.accessibility_app_usage_settings, context.getText(R.string.accessibility_app_usage_settings) ) ) // Add DWB accessibility action at the end of the list taskContainers.forEach { it.digitalWellBeingToast?.getDWBAccessibilityAction()?.let(::addAction) } recentsView?.let { collectionItemInfo = AccessibilityNodeInfo.CollectionItemInfo.obtain( Loading @@ -557,16 +589,17 @@ constructor( } override fun performAccessibilityAction(action: Int, arguments: Bundle?): Boolean { if (action == R.string.accessibility_close) { // TODO(b/343708271): Add support for multiple tasks per action. if (action == R.id.action_close) { recentsView?.dismissTask(this, true /*animateTaskView*/, true /*removeTask*/) return true } if (action == R.string.accessibility_app_usage_settings) { // TODO(b/341672022): handle multiple digitalWellBeingToast accessibility actions taskContainers[0].digitalWellBeingToast?.openAppUsageSettings(this) taskContainers.forEach { if (it.digitalWellBeingToast?.handleAccessibilityAction(action) == true) { return true } taskContainers.forEach { TaskOverlayFactory.getEnabledShortcuts(this, it).forEach { shortcut -> if (shortcut.hasHandlerForAction(action)) { shortcut.onClick(this) Loading @@ -574,6 +607,7 @@ constructor( } } } return super.performAccessibilityAction(action, arguments) } Loading Loading @@ -1555,11 +1589,6 @@ constructor( ) { val overlay: TaskOverlay<*> = taskOverlayFactory.createOverlay(this) @IdRes val a11yNodeId: Int = if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) R.id.split_bottomRight_appInfo else R.id.split_topLeft_appInfo val snapshotView: View get() = thumbnailView ?: thumbnailViewDeprecated Loading res/values/id.xml +6 −3 Original line number Diff line number Diff line Loading @@ -19,9 +19,6 @@ <item type="id" name="view_type_widgets_space" /> <item type="id" name="view_type_widgets_list" /> <item type="id" name="view_type_widgets_header" /> <!-- Used for A11y actions in staged split to identify each task uniquely --> <item type="id" name="split_topLeft_appInfo" /> <item type="id" name="split_bottomRight_appInfo" /> <!-- Accessibility actions --> <item type="id" name="action_remove" /> Loading @@ -37,6 +34,12 @@ <item type="id" name="action_remote_action_shortcut" /> <item type="id" name="action_dismiss_prediction" /> <item type="id" name="action_pin_prediction"/> <item type="id" name="action_close"/> <!-- Used for A11y actions in staged split to identify each task uniquely --> <item type="id" name="action_app_info_top_left" /> <item type="id" name="action_app_info_bottom_right" /> <item type="id" name="action_digital_wellbeing_top_left" /> <item type="id" name="action_digital_wellbeing_bottom_right" /> <!-- QSB IDs. DO not change --> <item type="id" name="search_container_workspace" /> Loading res/values/strings.xml +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ <!-- Title for an option to enter split screen mode for a given app --> <string name="recent_task_option_split_screen">Split screen</string> <string name="split_app_info_accessibility">App info for %1$s</string> <string name="split_app_usage_settings">Usage settings for %1$s</string> <!-- App pairs --> <string name="save_app_pair">Save app pair</string> Loading Loading
quickstep/src/com/android/quickstep/TaskShortcutFactory.java +6 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.view.Surface.ROTATION_0; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.window.flags.Flags.enableDesktopWindowingMode; import android.app.ActivityOptions; Loading Loading @@ -107,10 +108,14 @@ public interface TaskShortcutFactory { public List<SystemShortcut> getShortcuts(RecentsViewContainer container, TaskContainer taskContainer) { TaskView taskView = taskContainer.getTaskView(); int actionId = taskContainer.getStagePosition() == STAGE_POSITION_BOTTOM_OR_RIGHT ? R.id.action_app_info_bottom_right : R.id.action_app_info_top_left; AppInfo.SplitAccessibilityInfo accessibilityInfo = new AppInfo.SplitAccessibilityInfo(taskView.containsMultipleTasks(), TaskUtils.getTitle(taskView.getContext(), taskContainer.getTask()), taskContainer.getA11yNodeId() actionId ); return Collections.singletonList(new AppInfo(container, taskContainer.getItemInfo(), taskView, accessibilityInfo)); Loading
quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java +38 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.launcher3.util.Executors.ORDERED_BG_EXECUTOR; import android.app.ActivityOptions; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.pm.LauncherApps.AppUsageLimit; Loading @@ -38,6 +39,7 @@ import android.util.Pair; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.TextView; Loading @@ -49,6 +51,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; import com.android.quickstep.TaskUtils; import com.android.quickstep.orientation.RecentsPagedOrientationHandler; import com.android.systemui.shared.recents.model.Task; Loading @@ -68,13 +71,15 @@ public final class DigitalWellBeingToast { private static final int SPLIT_GRID_BANNER_LARGE = 1; /** Used for grid task view, only showing icon */ private static final int SPLIT_GRID_BANNER_SMALL = 2; @IntDef(value = { SPLIT_BANNER_FULLSCREEN, SPLIT_GRID_BANNER_LARGE, SPLIT_GRID_BANNER_SMALL, }) @Retention(RetentionPolicy.SOURCE) @interface SplitBannerConfig{} @interface SplitBannerConfig { } static final Intent OPEN_APP_USAGE_SETTINGS_TEMPLATE = new Intent(ACTION_APP_USAGE_SETTINGS); static final int MINUTE_MS = 60000; Loading Loading @@ -398,4 +403,36 @@ public final class DigitalWellBeingToast { mBanner.setVisibility(visibility); } private int getAccessibilityActionId() { return (mSplitBounds != null && mSplitBounds.rightBottomTaskId == mTask.key.id) ? R.id.action_digital_wellbeing_bottom_right : R.id.action_digital_wellbeing_top_left; } @Nullable public AccessibilityNodeInfo.AccessibilityAction getDWBAccessibilityAction() { if (!hasLimit()) { return null; } Context context = mContainer.asContext(); String label = (mTaskView.containsMultipleTasks()) ? context.getString( R.string.split_app_usage_settings, TaskUtils.getTitle(context, mTask) ) : context.getString(R.string.accessibility_app_usage_settings); return new AccessibilityNodeInfo.AccessibilityAction(getAccessibilityActionId(), label); } public boolean handleAccessibilityAction(int action) { if (getAccessibilityActionId() == action) { openAppUsageSettings(mTaskView); return true; } else { return false; } } }
quickstep/src/com/android/quickstep/views/TaskView.kt +51 −22 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.view.View.OnClickListener import android.view.ViewGroup import android.view.ViewStub import android.view.accessibility.AccessibilityNodeInfo import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.FrameLayout import android.widget.Toast import androidx.annotation.IntDef Loading Loading @@ -67,7 +68,6 @@ import com.android.launcher3.util.Executors import com.android.launcher3.util.RunnableList import com.android.launcher3.util.SafeCloseable import com.android.launcher3.util.SplitConfigurationOptions import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption import com.android.launcher3.util.SplitConfigurationOptions.StagePosition Loading Loading @@ -133,19 +133,26 @@ constructor( 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() val thumbnailViews: Array<TaskThumbnailViewDeprecated> get() = taskContainers.map { it.thumbnailViewDeprecated }.toTypedArray() val isGridTask: Boolean /** Returns whether the task is part of overview grid and not being focused. */ get() = container.deviceProfile.isTablet && !isFocusedTask val isRunningTask: Boolean get() = this === recentsView?.runningTaskView val isFocusedTask: Boolean get() = this === recentsView?.focusedTaskView val taskCornerRadius: Float get() = currentFullscreenParams.cornerRadius val recentsView: RecentsView<*, *>? get() = parent as? RecentsView<*, *> val pagedOrientationHandler: RecentsPagedOrientationHandler get() = orientedState.orientationHandler Loading @@ -153,10 +160,12 @@ constructor( val firstTask: Task /** Returns the first task bound to this TaskView. */ get() = taskContainers[0].task @get:Deprecated("Use [taskContainers] instead.") val firstThumbnailViewDeprecated: TaskThumbnailViewDeprecated /** Returns the first thumbnailView of the TaskView. */ get() = taskContainers[0].thumbnailViewDeprecated @get:Deprecated("Use [taskContainers] instead.") val firstItemInfo: ItemInfo get() = taskContainers[0].itemInfo Loading @@ -173,6 +182,7 @@ constructor( * not change according to a temporary state. */ get() = Utilities.mapRange(gridProgress, nonGridScale, 1f) protected val persistentTranslationX: Float /** * Returns addition of translationX that is persistent (e.g. fullscreen and grid), and does Loading @@ -182,42 +192,50 @@ constructor( (getNonGridTrans(nonGridTranslationX) + getGridTrans(this.gridTranslationX) + getNonGridTrans(nonGridPivotTranslationX)) protected val persistentTranslationY: Float /** * Returns addition of translationY that is persistent (e.g. fullscreen and grid), and does * not change according to a temporary state (e.g. task offset). */ get() = boxTranslationY + getGridTrans(gridTranslationY) protected val primarySplitTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getPrimaryValue( SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y ) protected val secondarySplitTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue( SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y ) protected val primaryDismissTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getPrimaryValue(DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y) protected val secondaryDismissTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue(DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y) protected val primaryTaskOffsetTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getPrimaryValue( TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y ) protected val secondaryTaskOffsetTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue( TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y ) protected val taskResistanceTranslationProperty: FloatProperty<TaskView> get() = pagedOrientationHandler.getSecondaryValue( Loading @@ -234,6 +252,7 @@ constructor( /** Returns a list of all TaskContainers in the TaskView. */ lateinit var taskContainers: List<TaskContainer> protected set lateinit var orientedState: RecentsOrientedState var taskViewId = UNBOUND_TASK_VIEW_ID Loading Loading @@ -264,46 +283,55 @@ constructor( field = value onModalnessUpdated(field) } protected var taskThumbnailSplashAlpha = 0f set(value) { field = value applyThumbnailSplashAlpha() } protected var nonGridScale = 1f set(value) { field = value applyScale() } private var dismissScale = 1f set(value) { field = value applyScale() } private var dismissTranslationX = 0f set(value) { field = value applyTranslationX() } private var dismissTranslationY = 0f set(value) { field = value applyTranslationY() } private var taskOffsetTranslationX = 0f set(value) { field = value applyTranslationX() } private var taskOffsetTranslationY = 0f set(value) { field = value applyTranslationY() } private var taskResistanceTranslationX = 0f set(value) { field = value applyTranslationX() } private var taskResistanceTranslationY = 0f set(value) { field = value Loading @@ -321,6 +349,7 @@ constructor( field = value applyTranslationX() } var gridTranslationY = 0f protected set(value) { field = value Loading @@ -339,6 +368,7 @@ constructor( field = value applyTranslationX() } protected var nonGridPivotTranslationX = 0f set(value) { field = value Loading @@ -350,16 +380,19 @@ constructor( field = value applyTranslationY() } private var splitSelectTranslationX = 0f set(value) { field = value applyTranslationX() } protected var stableAlpha = 1f set(value) { field = value alpha = stableAlpha } protected var shouldShowScreenshot = false get() = !isRunningTask || field /** Enable or disable showing border on hover and focus change */ Loading @@ -375,6 +408,7 @@ constructor( hoverBorderAnimator?.setBorderVisibility(visible = field && isHovered, animated = true) focusBorderAnimator?.setBorderVisibility(visible = field && isFocused, animated = true) } protected var iconScaleAnimStartProgress = 0f private var focusTransitionProgress = 1f Loading Loading @@ -522,11 +556,12 @@ constructor( super.onInitializeAccessibilityNodeInfo(info) with(info) { addAction( AccessibilityNodeInfo.AccessibilityAction( R.string.accessibility_close, AccessibilityAction( R.id.action_close, context.getText(R.string.accessibility_close) ) ) taskContainers.forEach { TraceHelper.allowIpcs("TV.a11yInfo") { TaskOverlayFactory.getEnabledShortcuts(this@TaskView, it).forEach { shortcut -> Loading @@ -534,15 +569,12 @@ constructor( } } } // TODO(b/341672022): handle multiple digitalWellBeingToast accessibility actions if (taskContainers[0].digitalWellBeingToast?.hasLimit() == true) { addAction( AccessibilityNodeInfo.AccessibilityAction( R.string.accessibility_app_usage_settings, context.getText(R.string.accessibility_app_usage_settings) ) ) // Add DWB accessibility action at the end of the list taskContainers.forEach { it.digitalWellBeingToast?.getDWBAccessibilityAction()?.let(::addAction) } recentsView?.let { collectionItemInfo = AccessibilityNodeInfo.CollectionItemInfo.obtain( Loading @@ -557,16 +589,17 @@ constructor( } override fun performAccessibilityAction(action: Int, arguments: Bundle?): Boolean { if (action == R.string.accessibility_close) { // TODO(b/343708271): Add support for multiple tasks per action. if (action == R.id.action_close) { recentsView?.dismissTask(this, true /*animateTaskView*/, true /*removeTask*/) return true } if (action == R.string.accessibility_app_usage_settings) { // TODO(b/341672022): handle multiple digitalWellBeingToast accessibility actions taskContainers[0].digitalWellBeingToast?.openAppUsageSettings(this) taskContainers.forEach { if (it.digitalWellBeingToast?.handleAccessibilityAction(action) == true) { return true } taskContainers.forEach { TaskOverlayFactory.getEnabledShortcuts(this, it).forEach { shortcut -> if (shortcut.hasHandlerForAction(action)) { shortcut.onClick(this) Loading @@ -574,6 +607,7 @@ constructor( } } } return super.performAccessibilityAction(action, arguments) } Loading Loading @@ -1555,11 +1589,6 @@ constructor( ) { val overlay: TaskOverlay<*> = taskOverlayFactory.createOverlay(this) @IdRes val a11yNodeId: Int = if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) R.id.split_bottomRight_appInfo else R.id.split_topLeft_appInfo val snapshotView: View get() = thumbnailView ?: thumbnailViewDeprecated Loading
res/values/id.xml +6 −3 Original line number Diff line number Diff line Loading @@ -19,9 +19,6 @@ <item type="id" name="view_type_widgets_space" /> <item type="id" name="view_type_widgets_list" /> <item type="id" name="view_type_widgets_header" /> <!-- Used for A11y actions in staged split to identify each task uniquely --> <item type="id" name="split_topLeft_appInfo" /> <item type="id" name="split_bottomRight_appInfo" /> <!-- Accessibility actions --> <item type="id" name="action_remove" /> Loading @@ -37,6 +34,12 @@ <item type="id" name="action_remote_action_shortcut" /> <item type="id" name="action_dismiss_prediction" /> <item type="id" name="action_pin_prediction"/> <item type="id" name="action_close"/> <!-- Used for A11y actions in staged split to identify each task uniquely --> <item type="id" name="action_app_info_top_left" /> <item type="id" name="action_app_info_bottom_right" /> <item type="id" name="action_digital_wellbeing_top_left" /> <item type="id" name="action_digital_wellbeing_bottom_right" /> <!-- QSB IDs. DO not change --> <item type="id" name="search_container_workspace" /> Loading
res/values/strings.xml +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ <!-- Title for an option to enter split screen mode for a given app --> <string name="recent_task_option_split_screen">Split screen</string> <string name="split_app_info_accessibility">App info for %1$s</string> <string name="split_app_usage_settings">Usage settings for %1$s</string> <!-- App pairs --> <string name="save_app_pair">Save app pair</string> Loading