Merge "Disable transition debug logs" into main
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a28dc49..17ed908 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1366,7 +1366,7 @@
}
@FlaggedApi("android.credentials.flags.configurable_selector_ui_enabled") public class IntentFactory {
- method @NonNull public static android.content.Intent createCancelUiIntent(@NonNull android.os.IBinder, boolean, @NonNull String);
+ method @NonNull public static android.content.Intent createCancelUiIntent(@NonNull android.content.Context, @NonNull android.os.IBinder, boolean, @NonNull String);
method @NonNull public static android.content.Intent createCredentialSelectorIntent(@NonNull android.content.Context, @NonNull android.credentials.selection.RequestInfo, @NonNull java.util.ArrayList<android.credentials.selection.ProviderData>, @NonNull java.util.ArrayList<android.credentials.selection.DisabledProviderData>, @NonNull android.os.ResultReceiver);
}
diff --git a/core/java/android/credentials/selection/IntentFactory.java b/core/java/android/credentials/selection/IntentFactory.java
index 4b0fa6d..79fba9b 100644
--- a/core/java/android/credentials/selection/IntentFactory.java
+++ b/core/java/android/credentials/selection/IntentFactory.java
@@ -80,17 +80,7 @@
ArrayList<DisabledProviderData> disabledProviderDataList,
@NonNull ResultReceiver resultReceiver) {
Intent intent = new Intent();
- ComponentName componentName =
- ComponentName.unflattenFromString(
- Resources.getSystem()
- .getString(
- com.android.internal.R.string
- .config_credentialManagerDialogComponent));
- ComponentName oemOverrideComponentName = getOemOverrideComponentName(context);
- if (oemOverrideComponentName != null) {
- componentName = oemOverrideComponentName;
- }
- intent.setComponent(componentName);
+ setCredentialSelectorUiComponentName(context, intent);
intent.putParcelableArrayListExtra(
ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList);
intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo);
@@ -100,6 +90,24 @@
return intent;
}
+ private static void setCredentialSelectorUiComponentName(@NonNull Context context,
+ @NonNull Intent intent) {
+ if (configurableSelectorUiEnabled()) {
+ ComponentName componentName = getOemOverrideComponentName(context);
+ if (componentName == null) {
+ componentName = ComponentName.unflattenFromString(Resources.getSystem().getString(
+ com.android.internal.R.string
+ .config_fallbackCredentialManagerDialogComponent));
+ }
+ intent.setComponent(componentName);
+ } else {
+ ComponentName componentName = ComponentName.unflattenFromString(Resources.getSystem()
+ .getString(com.android.internal.R.string
+ .config_fallbackCredentialManagerDialogComponent));
+ intent.setComponent(componentName);
+ }
+ }
+
/**
* Returns null if there is not an enabled and valid oem override component. It means the
* default platform UI component name should be used instead.
@@ -107,44 +115,39 @@
@Nullable
private static ComponentName getOemOverrideComponentName(@NonNull Context context) {
ComponentName result = null;
- if (configurableSelectorUiEnabled()) {
- if (Resources.getSystem().getBoolean(
- com.android.internal.R.bool.config_enableOemCredentialManagerDialogComponent)) {
- String oemComponentString =
- Resources.getSystem()
- .getString(
- com.android.internal.R.string
- .config_oemCredentialManagerDialogComponent);
- if (!TextUtils.isEmpty(oemComponentString)) {
- ComponentName oemComponentName = ComponentName.unflattenFromString(
- oemComponentString);
- if (oemComponentName != null) {
- try {
- ActivityInfo info = context.getPackageManager().getActivityInfo(
- oemComponentName,
- PackageManager.ComponentInfoFlags.of(
- PackageManager.MATCH_SYSTEM_ONLY));
- if (info.enabled && info.exported) {
- Slog.i(TAG,
- "Found enabled oem CredMan UI component."
- + oemComponentString);
- result = oemComponentName;
- } else {
- Slog.i(TAG,
- "Found enabled oem CredMan UI component but it was not "
- + "enabled.");
- }
- } catch (PackageManager.NameNotFoundException e) {
- Slog.i(TAG, "Unable to find oem CredMan UI component: "
- + oemComponentString + ".");
- }
+ String oemComponentString =
+ Resources.getSystem()
+ .getString(
+ com.android.internal.R.string
+ .config_oemCredentialManagerDialogComponent);
+ if (!TextUtils.isEmpty(oemComponentString)) {
+ ComponentName oemComponentName = ComponentName.unflattenFromString(
+ oemComponentString);
+ if (oemComponentName != null) {
+ try {
+ ActivityInfo info = context.getPackageManager().getActivityInfo(
+ oemComponentName,
+ PackageManager.ComponentInfoFlags.of(
+ PackageManager.MATCH_SYSTEM_ONLY));
+ if (info.enabled && info.exported) {
+ Slog.i(TAG,
+ "Found enabled oem CredMan UI component."
+ + oemComponentString);
+ result = oemComponentName;
} else {
- Slog.i(TAG, "Invalid OEM ComponentName format.");
+ Slog.i(TAG,
+ "Found enabled oem CredMan UI component but it was not "
+ + "enabled.");
}
- } else {
- Slog.i(TAG, "Invalid empty OEM component name.");
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.i(TAG, "Unable to find oem CredMan UI component: "
+ + oemComponentString + ".");
}
+ } else {
+ Slog.i(TAG, "Invalid OEM ComponentName format.");
}
+ } else {
+ Slog.i(TAG, "Invalid empty OEM component name.");
}
return result;
}
@@ -186,16 +189,11 @@
* Creates an Intent that cancels any UI matching the given request token id.
*/
@NonNull
- public static Intent createCancelUiIntent(@NonNull IBinder requestToken,
- boolean shouldShowCancellationUi, @NonNull String appPackageName) {
+ public static Intent createCancelUiIntent(@NonNull Context context,
+ @NonNull IBinder requestToken, boolean shouldShowCancellationUi,
+ @NonNull String appPackageName) {
Intent intent = new Intent();
- ComponentName componentName =
- ComponentName.unflattenFromString(
- Resources.getSystem()
- .getString(
- com.android.internal.R.string
- .config_credentialManagerDialogComponent));
- intent.setComponent(componentName);
+ setCredentialSelectorUiComponentName(context, intent);
intent.putExtra(CancelSelectionRequest.EXTRA_CANCEL_UI_REQUEST,
new CancelSelectionRequest(new RequestToken(requestToken), shouldShowCancellationUi,
appPackageName));
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 51585af..eea6464 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11576,6 +11576,15 @@
"extra_low_power_warning_acknowledged";
/**
+ * Whether the emergency thermal alert would be disabled
+ * (0: default) or not (1).
+ *
+ * @hide
+ */
+ public static final String EMERGENCY_THERMAL_ALERT_DISABLED =
+ "emergency_thermal_alert_disabled";
+
+ /**
* 0 (default) Auto battery saver suggestion has not been suppressed. 1) it has been
* suppressed.
* @hide
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8edf42a..90f27311 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3348,26 +3348,23 @@
<string name="config_carrierAppInstallDialogComponent" translatable="false"
>com.android.simappdialog/com.android.simappdialog.InstallCarrierAppActivity</string>
- <!-- Name of the default framework dialog that is used to get or save an app credential.
+ <!-- Name of the fallback CredentialManager dialog that is used to get or save an app
+ credential.
- This UI should be always launch-able and is used as a fallback when an oem replacement activity
- (defined at config_oemCredentialManagerDialogComponent) is undefined / not found. -->
- <string name="config_credentialManagerDialogComponent" translatable="false"
+ If empty, no fallback will be used. IMPORTANT: In that case the OEM dialog value specified in
+ config_oemCredentialManagerDialogComponent must always launch-able. Otherwise, the
+ CredentialManager API contract is broken.
+
+ If specified, this UI should be always launch-able. It will be used as a fallback when the OEM
+ dialog value specified in config_oemCredentialManagerDialogComponent) is undefined / not
+ found. -->
+ <string name="config_fallbackCredentialManagerDialogComponent" translatable="false"
>com.android.credentialmanager/com.android.credentialmanager.CredentialSelectorActivity</string>
- <!-- Whether to allow the credential selector activity to be replaced by an activity at
- run-time (restricted to the privileged activity specified by
- config_credentialSelectorActivityName).
-
- When disabled, the fallback activity defined at
- config_credentialManagerDialogComponent will be used instead. -->
- <bool name="config_enableOemCredentialManagerDialogComponent" translatable="false">true</bool>
<!-- Fully qualified activity name providing the credential selector UI, that serves the
- CredentialManager APIs.
+ CredentialManager APIs. Must be a system app component.
- Used only when config_enableOemCredentialManagerDialogComponent is true.
-
- If the activity specified cannot be found or launched, then the fallback activity defined at
- config_credentialManagerDialogComponent will be used instead. -->
+ If empty, or if this activity specified cannot be found or launched, then the fallback activity
+ defined at config_fallbackCredentialManagerDialogComponent will be used instead. -->
<string name="config_oemCredentialManagerDialogComponent" translatable="false"></string>
<!-- Name of the broadcast receiver that is used to receive provider change events -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a180467..a025c8d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2297,8 +2297,7 @@
<java-symbol type="string" name="config_customVpnAlwaysOnDisconnectedDialogComponent" />
<java-symbol type="string" name="config_platformVpnConfirmDialogComponent" />
<java-symbol type="string" name="config_carrierAppInstallDialogComponent" />
- <java-symbol type="string" name="config_credentialManagerDialogComponent" />
- <java-symbol type="bool" name="config_enableOemCredentialManagerDialogComponent" />
+ <java-symbol type="string" name="config_fallbackCredentialManagerDialogComponent" />
<java-symbol type="string" name="config_oemCredentialManagerDialogComponent" />
<java-symbol type="string" name="config_credentialManagerReceiverComponent" />
<java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 74967ef0..7dd3961 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -510,10 +510,6 @@
split select if dragged until the touch input is within the range. -->
<dimen name="desktop_mode_transition_area_width">32dp</dimen>
- <!-- The height of the area at the top of the screen where a freeform task will transition to
- fullscreen if dragged until the top bound of the task is within the area. -->
- <dimen name="desktop_mode_transition_area_height">16dp</dimen>
-
<!-- The width of the area where a desktop task will transition to fullscreen. -->
<dimen name="desktop_mode_fullscreen_from_desktop_width">80dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 7091c4b..fb0ed15 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -98,6 +98,7 @@
* Based on the coordinates of the current drag event, determine which indicator type we should
* display, including no visible indicator.
*/
+ @NonNull
IndicatorType updateIndicatorType(PointF inputCoordinates, int windowingMode) {
final DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
// If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
@@ -136,18 +137,18 @@
Region calculateFullscreenRegion(DisplayLayout layout,
@WindowConfiguration.WindowingMode int windowingMode, int captionHeight) {
final Region region = new Region();
- int edgeTransitionHeight = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_transition_area_height);
+ int transitionHeight = windowingMode == WINDOWING_MODE_FREEFORM
+ ? 2 * layout.stableInsets().top
+ : mContext.getResources().getDimensionPixelSize(
+ com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height);
// A thin, short Rect at the top of the screen.
if (windowingMode == WINDOWING_MODE_FREEFORM) {
int fromFreeformWidth = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_width);
- int fromFreeformHeight = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height);
region.union(new Rect((layout.width() / 2) - (fromFreeformWidth / 2),
-captionHeight,
(layout.width() / 2) + (fromFreeformWidth / 2),
- fromFreeformHeight));
+ transitionHeight));
}
// A screen-wide, shorter Rect if the task is in fullscreen or split.
if (windowingMode == WINDOWING_MODE_FULLSCREEN
@@ -155,7 +156,7 @@
region.union(new Rect(0,
-captionHeight,
layout.width(),
- edgeTransitionHeight));
+ transitionHeight));
}
return region;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index d1328ca..654409f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -140,7 +140,7 @@
private val transitionAreaHeight
get() = context.resources.getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_transition_area_height
+ com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height
)
private val transitionAreaWidth
@@ -565,30 +565,7 @@
* @param position the portion of the screen (RIGHT or LEFT) we want to snap the task to.
*/
fun snapToHalfScreen(taskInfo: RunningTaskInfo, position: SnapPosition) {
- val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
-
- val stableBounds = Rect()
- displayLayout.getStableBounds(stableBounds)
-
- val destinationWidth = stableBounds.width() / 2
- val destinationBounds = when (position) {
- SnapPosition.LEFT -> {
- Rect(
- stableBounds.left,
- stableBounds.top,
- stableBounds.left + destinationWidth,
- stableBounds.bottom
- )
- }
- SnapPosition.RIGHT -> {
- Rect(
- stableBounds.right - destinationWidth,
- stableBounds.top,
- stableBounds.right,
- stableBounds.bottom
- )
- }
- }
+ val destinationBounds = getSnapBounds(taskInfo, position)
if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) return
@@ -609,8 +586,35 @@
outBounds.set(0, 0, desiredWidth, desiredHeight)
// Center the task in screen bounds
outBounds.offset(
- screenBounds.centerX() - outBounds.centerX(),
- screenBounds.centerY() - outBounds.centerY())
+ screenBounds.centerX() - outBounds.centerX(),
+ screenBounds.centerY() - outBounds.centerY())
+ }
+
+ private fun getSnapBounds(taskInfo: RunningTaskInfo, position: SnapPosition): Rect {
+ val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return Rect()
+
+ val stableBounds = Rect()
+ displayLayout.getStableBounds(stableBounds)
+
+ val destinationWidth = stableBounds.width() / 2
+ return when (position) {
+ SnapPosition.LEFT -> {
+ Rect(
+ stableBounds.left,
+ stableBounds.top,
+ stableBounds.left + destinationWidth,
+ stableBounds.bottom
+ )
+ }
+ SnapPosition.RIGHT -> {
+ Rect(
+ stableBounds.right - destinationWidth,
+ stableBounds.top,
+ stableBounds.right,
+ stableBounds.bottom
+ )
+ }
+ }
}
/**
@@ -646,7 +650,7 @@
?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
}
- private fun releaseVisualIndicator() {
+ fun releaseVisualIndicator() {
val t = SurfaceControl.Transaction()
visualIndicator?.releaseVisualIndicator(t)
visualIndicator = null
@@ -927,16 +931,13 @@
taskSurface: SurfaceControl,
inputX: Float,
taskTop: Float
- ) {
+ ): DesktopModeVisualIndicator.IndicatorType {
// If the visual indicator does not exist, create it.
- if (visualIndicator == null) {
- visualIndicator = DesktopModeVisualIndicator(
- syncQueue, taskInfo, displayController, context, taskSurface,
- rootTaskDisplayAreaOrganizer)
- }
- // Then, update the indicator type.
- val indicator = visualIndicator ?: return
- indicator.updateIndicatorType(PointF(inputX, taskTop), taskInfo.windowingMode)
+ val indicator = visualIndicator ?: DesktopModeVisualIndicator(
+ syncQueue, taskInfo, displayController, context, taskSurface,
+ rootTaskDisplayAreaOrganizer)
+ if (visualIndicator == null) visualIndicator = indicator
+ return indicator.updateIndicatorType(PointF(inputX, taskTop), taskInfo.windowingMode)
}
/**
@@ -956,20 +957,28 @@
if (taskInfo.configuration.windowConfiguration.windowingMode != WINDOWING_MODE_FREEFORM) {
return
}
- if (taskBounds.top <= transitionAreaHeight) {
- moveToFullscreenWithAnimation(taskInfo, position)
- return
- }
- if (inputCoordinate.x <= transitionAreaWidth) {
- releaseVisualIndicator()
- snapToHalfScreen(taskInfo, SnapPosition.LEFT)
- return
- }
- if (inputCoordinate.x >= (displayController.getDisplayLayout(taskInfo.displayId)?.width()
- ?.minus(transitionAreaWidth) ?: return)) {
- releaseVisualIndicator()
- snapToHalfScreen(taskInfo, SnapPosition.RIGHT)
- return
+
+ val indicator = visualIndicator ?: return
+ val indicatorType = indicator.updateIndicatorType(
+ PointF(inputCoordinate.x, taskBounds.top.toFloat()),
+ taskInfo.windowingMode
+ )
+ when (indicatorType) {
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+ moveToFullscreenWithAnimation(taskInfo, position)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ releaseVisualIndicator()
+ snapToHalfScreen(taskInfo, SnapPosition.LEFT)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ releaseVisualIndicator()
+ snapToHalfScreen(taskInfo, SnapPosition.RIGHT)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR,
+ DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR -> {
+ releaseVisualIndicator()
+ }
}
// A freeform drag-move ended, remove the indicator immediately.
releaseVisualIndicator()
@@ -982,14 +991,28 @@
* @param y height of drag, to be checked against status bar height.
*/
fun onDragPositioningEndThroughStatusBar(
+ inputCoordinates: PointF,
taskInfo: RunningTaskInfo,
freeformBounds: Rect
) {
- finalizeDragToDesktop(taskInfo, freeformBounds)
- }
-
- private fun getStatusBarHeight(taskInfo: RunningTaskInfo): Int {
- return displayController.getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
+ val indicator = visualIndicator ?: return
+ val indicatorType = indicator
+ .updateIndicatorType(inputCoordinates, taskInfo.windowingMode)
+ when (indicatorType) {
+ DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR -> {
+ finalizeDragToDesktop(taskInfo, freeformBounds)
+ }
+ DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR,
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+ cancelDragToDesktop(taskInfo)
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ finalizeDragToDesktop(taskInfo, getSnapBounds(taskInfo, SnapPosition.LEFT))
+ }
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ finalizeDragToDesktop(taskInfo, getSnapBounds(taskInfo, SnapPosition.RIGHT))
+ }
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index fa3d8a6..f4ccd68 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -30,6 +30,10 @@
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION;
import static com.android.wm.shell.windowdecor.MoveToDesktopAnimator.DRAG_FREEFORM_SCALE;
@@ -81,6 +85,7 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
+import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
@@ -119,9 +124,8 @@
private final Choreographer mMainChoreographer;
private final DisplayController mDisplayController;
private final SyncTransactionQueue mSyncQueue;
- private final Optional<DesktopTasksController> mDesktopTasksController;
+ private final DesktopTasksController mDesktopTasksController;
private final InputManager mInputManager;
-
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -129,8 +133,7 @@
private final ExclusionRegionListener mExclusionRegionListener =
new ExclusionRegionListenerImpl();
- private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId =
- new SparseArray<>();
+ private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId;
private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl();
private final InputMonitorFactory mInputMonitorFactory;
private TaskOperations mTaskOperations;
@@ -197,7 +200,8 @@
new DesktopModeWindowDecoration.Factory(),
new InputMonitorFactory(),
SurfaceControl.Transaction::new,
- rootTaskDisplayAreaOrganizer);
+ rootTaskDisplayAreaOrganizer,
+ new SparseArray<>());
}
@VisibleForTesting
@@ -219,7 +223,8 @@
DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory,
InputMonitorFactory inputMonitorFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -231,7 +236,7 @@
mDisplayInsetsController = displayInsetsController;
mSyncQueue = syncQueue;
mTransitions = transitions;
- mDesktopTasksController = desktopTasksController;
+ mDesktopTasksController = desktopTasksController.get();
mShellCommandHandler = shellCommandHandler;
mWindowManager = windowManager;
mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory;
@@ -239,6 +244,7 @@
mTransactionFactory = transactionFactory;
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
mInputManager = mContext.getSystemService(InputManager.class);
+ mWindowDecorByTaskId = windowDecorByTaskId;
shellInit.addInitCallback(this::onInit, this);
}
@@ -248,8 +254,8 @@
mShellCommandHandler.addDumpCallback(this::dump, this);
mDisplayInsetsController.addInsetsChangedListener(mContext.getDisplayId(),
new DesktopModeOnInsetsChangedListener());
- mDesktopTasksController.ifPresent(c -> c.setOnTaskResizeAnimationListener(
- new DeskopModeOnTaskResizeAnimationListener()));
+ mDesktopTasksController.setOnTaskResizeAnimationListener(
+ new DeskopModeOnTaskResizeAnimationListener());
try {
mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener,
mContext.getDisplayId());
@@ -273,7 +279,7 @@
DesktopModeWindowDecoration decor = mWindowDecorByTaskId.get(taskId);
if (decor != null && DesktopModeStatus.isEnabled()
&& decor.mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
- mDesktopTasksController.ifPresent(c -> c.moveToSplit(decor.mTaskInfo));
+ mDesktopTasksController.moveToSplit(decor.mTaskInfo);
}
}
}
@@ -340,8 +346,7 @@
@Override
public void destroyWindowDecoration(RunningTaskInfo taskInfo) {
- final DesktopModeWindowDecoration decoration =
- mWindowDecorByTaskId.removeReturnOld(taskInfo.taskId);
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
if (decoration == null) return;
decoration.close();
@@ -349,6 +354,10 @@
if (mEventReceiversByDisplay.contains(displayId)) {
removeTaskFromEventReceiver(displayId);
}
+ // Remove the decoration from the cache last because WindowDecoration#close could still
+ // issue CANCEL MotionEvents to touch listeners before its view host is released.
+ // See b/327664694.
+ mWindowDecorByTaskId.remove(taskInfo.taskId);
}
private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
@@ -414,13 +423,11 @@
decoration.closeHandleMenu();
}
} else if (id == R.id.desktop_button) {
- if (mDesktopTasksController.isPresent()) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- // App sometimes draws before the insets from WindowDecoration#relayout have
- // been added, so they must be added here
- mWindowDecorByTaskId.get(mTaskId).addCaptionInset(wct);
- mDesktopTasksController.get().moveToDesktop(mTaskId, wct);
- }
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ // App sometimes draws before the insets from WindowDecoration#relayout have
+ // been added, so they must be added here
+ mWindowDecorByTaskId.get(mTaskId).addCaptionInset(wct);
+ mDesktopTasksController.moveToDesktop(mTaskId, wct);
decoration.closeHandleMenu();
} else if (id == R.id.fullscreen_button) {
decoration.closeHandleMenu();
@@ -428,42 +435,37 @@
mSplitScreenController.moveTaskToFullscreen(mTaskId,
SplitScreenController.EXIT_REASON_DESKTOP_MODE);
} else {
- mDesktopTasksController.ifPresent(c ->
- c.moveToFullscreen(mTaskId));
+ mDesktopTasksController.moveToFullscreen(mTaskId);
}
} else if (id == R.id.split_screen_button) {
decoration.closeHandleMenu();
- mDesktopTasksController.ifPresent(c -> {
- c.requestSplit(decoration.mTaskInfo);
- });
+ mDesktopTasksController.requestSplit(decoration.mTaskInfo);
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
} else if (id == R.id.select_button) {
if (DesktopModeStatus.IS_DISPLAY_CHANGE_ENABLED) {
// TODO(b/278084491): dev option to enable display switching
// remove when select is implemented
- mDesktopTasksController.ifPresent(c -> c.moveToNextDisplay(mTaskId));
+ mDesktopTasksController.moveToNextDisplay(mTaskId);
}
} else if (id == R.id.maximize_window) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
- mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize(taskInfo));
+ mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
} else if (id == R.id.maximize_menu_maximize_button) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize(taskInfo));
+ mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
} else if (id == R.id.maximize_menu_snap_left_button) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.ifPresent(c -> c.snapToHalfScreen(
- taskInfo, SnapPosition.LEFT));
+ mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.LEFT);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
} else if (id == R.id.maximize_menu_snap_right_button) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.ifPresent(c -> c.snapToHalfScreen(
- taskInfo, SnapPosition.RIGHT));
+ mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.RIGHT);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
}
@@ -572,7 +574,7 @@
private void moveTaskToFront(RunningTaskInfo taskInfo) {
if (!taskInfo.isFocused) {
- mDesktopTasksController.ifPresent(c -> c.moveTaskToFront(taskInfo));
+ mDesktopTasksController.moveTaskToFront(taskInfo);
}
}
@@ -616,10 +618,10 @@
final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
final Rect newTaskBounds = mDragPositioningCallback.onDragPositioningMove(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
- mDesktopTasksController.ifPresent(c -> c.onDragPositioningMove(taskInfo,
+ mDesktopTasksController.onDragPositioningMove(taskInfo,
decoration.mTaskSurface,
e.getRawX(dragPointerIdx),
- newTaskBounds));
+ newTaskBounds);
mIsDragging = true;
return true;
}
@@ -641,10 +643,9 @@
(int) (e.getRawY(dragPointerIdx) - e.getY(dragPointerIdx)));
final Rect newTaskBounds = mDragPositioningCallback.onDragPositioningEnd(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
- mDesktopTasksController.ifPresent(c -> c.onDragPositioningEnd(taskInfo,
- position,
+ mDesktopTasksController.onDragPositioningEnd(taskInfo, position,
new PointF(e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)),
- newTaskBounds));
+ newTaskBounds);
if (touchingButton && !mHasLongClicked) {
// We need the input event to not be consumed here to end the ripple
// effect on the touched button. We will reset drag state in the ensuing
@@ -672,10 +673,8 @@
&& action != MotionEvent.ACTION_CANCEL)) {
return false;
}
- mDesktopTasksController.ifPresent(c -> {
- final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
- c.toggleDesktopTaskSize(decoration.mTaskInfo);
- });
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
+ mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
return true;
}
}
@@ -839,20 +838,29 @@
return;
}
if (mTransitionDragActive) {
+ final DesktopModeVisualIndicator.IndicatorType indicatorType =
+ mDesktopTasksController.updateVisualIndicator(relevantDecor.mTaskInfo,
+ relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
mTransitionDragActive = false;
- final int statusBarHeight = getStatusBarHeight(
- relevantDecor.mTaskInfo.displayId);
- if (ev.getRawY() > 2 * statusBarHeight) {
+ if (indicatorType == TO_DESKTOP_INDICATOR
+ || indicatorType == TO_SPLIT_LEFT_INDICATOR
+ || indicatorType == TO_SPLIT_RIGHT_INDICATOR) {
if (DesktopModeStatus.isEnabled()) {
animateToDesktop(relevantDecor, ev);
}
mMoveToDesktopAnimator = null;
return;
} else if (mMoveToDesktopAnimator != null) {
- mDesktopTasksController.ifPresent(
- c -> c.cancelDragToDesktop(relevantDecor.mTaskInfo));
+ mDesktopTasksController.onDragPositioningEndThroughStatusBar(
+ new PointF(ev.getRawX(), ev.getRawY()),
+ relevantDecor.mTaskInfo,
+ calculateFreeformBounds(ev.getDisplayId(), DRAG_FREEFORM_SCALE));
mMoveToDesktopAnimator = null;
return;
+ } else {
+ // In cases where we create an indicator but do not start the
+ // move-to-desktop animation, we need to dismiss it.
+ mDesktopTasksController.releaseVisualIndicator();
}
}
relevantDecor.checkClickEvent(ev);
@@ -864,20 +872,17 @@
return;
}
if (mTransitionDragActive) {
- mDesktopTasksController.ifPresent(
- c -> c.updateVisualIndicator(
+ final DesktopModeVisualIndicator.IndicatorType indicatorType =
+ mDesktopTasksController.updateVisualIndicator(
relevantDecor.mTaskInfo,
- relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY()));
- final int statusBarHeight = getStatusBarHeight(
- relevantDecor.mTaskInfo.displayId);
- if (ev.getRawY() > statusBarHeight) {
+ relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
+ if (indicatorType != TO_FULLSCREEN_INDICATOR) {
if (mMoveToDesktopAnimator == null) {
mMoveToDesktopAnimator = new MoveToDesktopAnimator(
mContext, mDragToDesktopAnimationStartBounds,
relevantDecor.mTaskInfo, relevantDecor.mTaskSurface);
- mDesktopTasksController.ifPresent(
- c -> c.startDragToDesktop(relevantDecor.mTaskInfo,
- mMoveToDesktopAnimator));
+ mDesktopTasksController.startDragToDesktop(relevantDecor.mTaskInfo,
+ mMoveToDesktopAnimator);
}
}
if (mMoveToDesktopAnimator != null) {
@@ -923,6 +928,8 @@
* Animates a window to the center, grows to freeform size, and transitions to Desktop Mode.
* @param relevantDecor the window decor of the task to be animated
* @param ev the motion event that triggers the animation
+ * TODO(b/315527000): This animation needs to be adjusted to allow snap left/right cases.
+ * Currently fullscreen -> split snap still animates to center screen before readjusting.
*/
private void centerAndMoveToDesktopWithAnimation(DesktopModeWindowDecoration relevantDecor,
MotionEvent ev) {
@@ -946,13 +953,12 @@
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mDesktopTasksController.ifPresent(
- c -> {
- c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo,
- calculateFreeformBounds(ev.getDisplayId(),
- DesktopTasksController
- .DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
- });
+ mDesktopTasksController.onDragPositioningEndThroughStatusBar(
+ new PointF(ev.getRawX(), ev.getRawY()),
+ relevantDecor.mTaskInfo,
+ calculateFreeformBounds(ev.getDisplayId(),
+ DesktopTasksController
+ .DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
}
});
animator.start();
@@ -1082,7 +1088,7 @@
final DragPositioningCallback dragPositioningCallback;
final int transitionAreaHeight = mContext.getResources().getDimensionPixelSize(
- R.dimen.desktop_mode_transition_area_height);
+ R.dimen.desktop_mode_fullscreen_from_desktop_height);
if (!DesktopModeStatus.isVeiledResizeEnabled()) {
dragPositioningCallback = new FluidResizeTaskPositioner(
mTaskOrganizer, mTransitions, windowDecoration, mDisplayController,
@@ -1181,12 +1187,12 @@
@Override
public void onExclusionRegionChanged(int taskId, Region region) {
- mDesktopTasksController.ifPresent(d -> d.onExclusionRegionChanged(taskId, region));
+ mDesktopTasksController.onExclusionRegionChanged(taskId, region);
}
@Override
public void onExclusionRegionDismissed(int taskId) {
- mDesktopTasksController.ifPresent(d -> d.removeExclusionRegionForTask(taskId));
+ mDesktopTasksController.removeExclusionRegionForTask(taskId);
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index f8ce4ee..9703dce 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -56,18 +56,16 @@
context, taskSurface, taskDisplayAreaOrganizer)
whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
+ whenever(displayLayout.stableInsets()).thenReturn(STABLE_INSETS)
}
@Test
fun testFullscreenRegionCalculation() {
val transitionHeight = context.resources.getDimensionPixelSize(
- R.dimen.desktop_mode_transition_area_height)
+ R.dimen.desktop_mode_fullscreen_from_desktop_height)
val fromFreeformWidth = mContext.resources.getDimensionPixelSize(
R.dimen.desktop_mode_fullscreen_from_desktop_width
)
- val fromFreeformHeight = mContext.resources.getDimensionPixelSize(
- R.dimen.desktop_mode_fullscreen_from_desktop_height
- )
var testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
WINDOWING_MODE_FULLSCREEN, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, transitionHeight))
@@ -77,7 +75,7 @@
DISPLAY_BOUNDS.width() / 2 - fromFreeformWidth / 2,
-50,
DISPLAY_BOUNDS.width() / 2 + fromFreeformWidth / 2,
- fromFreeformHeight))
+ 2 * STABLE_INSETS.top))
testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
WINDOWING_MODE_MULTI_WINDOW, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, transitionHeight))
@@ -135,5 +133,12 @@
private const val TRANSITION_AREA_WIDTH = 32
private const val CAPTION_HEIGHT = 50
private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
+ private const val NAVBAR_HEIGHT = 50
+ private val STABLE_INSETS = Rect(
+ DISPLAY_BOUNDS.left,
+ DISPLAY_BOUNDS.top + CAPTION_HEIGHT,
+ DISPLAY_BOUNDS.right,
+ DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
+ )
}
}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 917fd71..9bb5482 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -29,6 +29,7 @@
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import android.util.SparseArray
import android.view.Choreographer
import android.view.Display.DEFAULT_DISPLAY
import android.view.IWindowManager
@@ -72,6 +73,8 @@
import org.mockito.kotlin.whenever
import java.util.Optional
import java.util.function.Supplier
+import org.mockito.Mockito
+import org.mockito.kotlin.spy
/** Tests of [DesktopModeWindowDecorViewModel] */
@@ -102,6 +105,7 @@
private val transactionFactory = Supplier<SurfaceControl.Transaction> {
SurfaceControl.Transaction()
}
+ private val windowDecorByTaskIdSpy = spy(SparseArray<DesktopModeWindowDecoration>())
private lateinit var shellInit: ShellInit
private lateinit var desktopModeOnInsetsChangedListener: DesktopModeOnInsetsChangedListener
@@ -110,6 +114,7 @@
@Before
fun setUp() {
shellInit = ShellInit(mockShellExecutor)
+ windowDecorByTaskIdSpy.clear()
desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel(
mContext,
mockShellExecutor,
@@ -128,7 +133,8 @@
mockDesktopModeWindowDecorFactory,
mockInputMonitorFactory,
transactionFactory,
- mockRootTaskDisplayAreaOrganizer
+ mockRootTaskDisplayAreaOrganizer,
+ windowDecorByTaskIdSpy
)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -332,6 +338,19 @@
verify(decoration, times(1)).relayout(task)
}
+ @Test
+ fun testDestroyWindowDecoration_closesBeforeCleanup() {
+ val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM)
+ val decoration = setUpMockDecorationForTask(task)
+ val inOrder = Mockito.inOrder(decoration, windowDecorByTaskIdSpy)
+
+ onTaskOpening(task)
+ desktopModeWindowDecorViewModel.destroyWindowDecoration(task)
+
+ inOrder.verify(decoration).close()
+ inOrder.verify(windowDecorByTaskIdSpy).remove(task.taskId)
+ }
+
private fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
desktopModeWindowDecorViewModel.onTaskOpening(
task,
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 2fa1c6e..a490b6f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -154,6 +154,7 @@
Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT,
Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
Settings.Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED,
+ Settings.Secure.EMERGENCY_THERMAL_ALERT_DISABLED,
Settings.Secure.HUSH_GESTURE_USED,
Settings.Secure.IN_CALL_NOTIFICATION_ENABLED,
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 2535fdb..4cdf98cb 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -235,6 +235,7 @@
VALIDATORS.put(Secure.MANUAL_RINGER_TOGGLE_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.LOW_POWER_WARNING_ACKNOWLEDGED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.EMERGENCY_THERMAL_ALERT_DISABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.IN_CALL_NOTIFICATION_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR);
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index 68c8dd9..d8d2985 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -19,11 +19,11 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/half_shelf_dialog"
android:orientation="vertical"
- android:layout_width="wrap_content"
+ android:layout_width="@dimen/large_dialog_width"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
- android:paddingStart="4dp"
- android:paddingEnd="4dp">
+ android:paddingLeft="@dimen/dialog_side_padding"
+ android:paddingRight="@dimen/dialog_side_padding">
<LinearLayout
android:id="@+id/half_shelf"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index 31e8093..bd19c80 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -180,7 +180,7 @@
}
private val isUnlocked: Flow<Boolean> =
- deviceEntryInteractor.isUnlocked.flatMapLatest { isUnlocked ->
+ keyguardInteractor.isKeyguardDismissible.flatMapLatest { isUnlocked ->
if (!isUnlocked) {
flowOf(false)
} else {
@@ -197,7 +197,7 @@
val iconType: Flow<DeviceEntryIconView.IconType> =
combine(
deviceEntryUdfpsInteractor.isListeningForUdfps,
- keyguardInteractor.isKeyguardDismissible,
+ isUnlocked,
) { isListeningForUdfps, isUnlocked ->
if (isListeningForUdfps) {
DeviceEntryIconView.IconType.FINGERPRINT
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
index 02bd810..4bb0d47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
@@ -27,11 +27,14 @@
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.keyguardRepository
+import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryIconViewModel.Companion.UNLOCKED_DELAY_MS
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.runner.RunWith
@@ -71,7 +74,10 @@
fun isLongPressEnabled_unlocked() =
testScope.runTest {
val isLongPressEnabled by collectLastValue(underTest.isLongPressEnabled)
+ fingerprintPropertyRepository.supportsUdfps()
keyguardRepository.setKeyguardDismissible(true)
+ advanceTimeBy(UNLOCKED_DELAY_MS * 2) // wait for unlocked delay
+ runCurrent()
assertThat(isLongPressEnabled).isTrue()
}
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 5e9d1cb..8dc15ad 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -163,6 +163,9 @@
}
],
"file_patterns": ["PinnerService\\.java"]
+ },
+ {
+ "name": "FrameworksVpnTests"
}
]
}
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index c06bdf9..b1823b4 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -23,6 +23,13 @@
}
flag {
+ name: "fgs_disable_saw"
+ namespace: "backstage_power"
+ description: "Disable System Alert Window FGS start"
+ bug: "296558535"
+}
+
+flag {
name: "bfgs_managed_network_access"
namespace: "backstage_power"
description: "Restrict network access for certain applications in BFGS process state"
diff --git a/services/core/java/com/android/server/connectivity/TEST_MAPPING b/services/core/java/com/android/server/connectivity/TEST_MAPPING
index 687d4b0..f508319 100644
--- a/services/core/java/com/android/server/connectivity/TEST_MAPPING
+++ b/services/core/java/com/android/server/connectivity/TEST_MAPPING
@@ -7,7 +7,7 @@
"exclude-annotation": "com.android.testutils.SkipPresubmit"
}
],
- "file_patterns": ["Vpn\\.java", "VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
+ "file_patterns": ["VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
}
],
"presubmit-large": [
@@ -26,5 +26,10 @@
],
"file_patterns": ["Vpn\\.java", "VpnIkeV2Utils\\.java", "VpnProfileStore\\.java"]
}
+ ],
+ "postsubmit":[
+ {
+ "name":"FrameworksVpnTests"
+ }
]
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
new file mode 100644
index 0000000..10b5eff
--- /dev/null
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.server.flags"
+
+flag {
+ namespace: "wear_frameworks"
+ name: "enable_odp_feature_guard"
+ description: "Enable guard based on system feature to prevent OnDevicePersonalization service from starting on form factors."
+ bug: "322249125"
+}
\ No newline at end of file
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index 027337f..f5e1e41 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -113,8 +113,8 @@
/** Creates intent that is ot be invoked to cancel an in-progress UI session. */
public Intent createCancelIntent(IBinder requestId, String packageName) {
- return IntentFactory.createCancelUiIntent(requestId, /*shouldShowCancellationUi=*/ true,
- packageName);
+ return IntentFactory.createCancelUiIntent(mContext, requestId,
+ /*shouldShowCancellationUi=*/ true, packageName);
}
/**
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e19f08c..9d95c5b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2774,9 +2774,12 @@
t.traceEnd();
// OnDevicePersonalizationSystemService
- t.traceBegin("StartOnDevicePersonalizationSystemService");
- mSystemServiceManager.startService(ON_DEVICE_PERSONALIZATION_SYSTEM_SERVICE_CLASS);
- t.traceEnd();
+ if (!com.android.server.flags.Flags.enableOdpFeatureGuard()
+ || SystemProperties.getBoolean("ro.system_settings.service.odp_enabled", true)) {
+ t.traceBegin("StartOnDevicePersonalizationSystemService");
+ mSystemServiceManager.startService(ON_DEVICE_PERSONALIZATION_SYSTEM_SERVICE_CLASS);
+ t.traceEnd();
+ }
// Profiling
if (android.server.Flags.telemetryApisService()) {
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 9792cdd..048b1b2 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1434,11 +1434,14 @@
}
/**
- * This API will return all {@link PhoneAccount}s registered via
- * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}. If a {@link PhoneAccount} appears
- * to be missing from the list, Telecom has either unregistered the {@link PhoneAccount}
- * or the caller registered the {@link PhoneAccount} under a different user and does not
- * have the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission.
+ * This API will return all {@link PhoneAccount}s the caller registered via
+ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}. If a {@link PhoneAccount} appears
+ * to be missing from the list, Telecom has either unregistered the {@link PhoneAccount} (for
+ * cleanup purposes) or the caller registered the {@link PhoneAccount} under a different user
+ * and does not have the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission.
+ * <b>Note:</b> This API will only return {@link PhoneAccount}s registered by the same app. For
+ * system Dialers that need all the {@link PhoneAccount}s registered by every application, see
+ * {@link TelecomManager#getAllPhoneAccounts()}.
*
* @return all the {@link PhoneAccount}s registered by the caller.
*/
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index b054a57..b4e2758 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -15,12 +15,7 @@
//
package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
toolSources = [
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
deleted file mode 100644
index 15ae2ba..0000000
--- a/tools/aapt2/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-include $(CLEAR_VARS)
-aapt2_results := ./out/soong/.intermediates/frameworks/base/tools/aapt2/aapt2_results
-$(call declare-1p-target,$(aapt2_results))
-aapt2_results :=