diff options
51 files changed, 463 insertions, 291 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 5c4fa590530b..8a6faa109522 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3247,7 +3247,6 @@ package android.companion.virtual { method @NonNull public java.util.Set<android.content.ComponentName> getBlockedCrossTaskNavigations(); method public int getDefaultActivityPolicy(); method public int getDefaultNavigationPolicy(); - method public int getDefaultRecentsPolicy(); method public int getDevicePolicy(int); method public int getLockState(); method @Nullable public String getName(); @@ -3264,8 +3263,8 @@ package android.companion.virtual { field public static final int NAVIGATION_POLICY_DEFAULT_ALLOWED = 0; // 0x0 field public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1 field public static final int POLICY_TYPE_AUDIO = 1; // 0x1 + field public static final int POLICY_TYPE_RECENTS = 2; // 0x2 field public static final int POLICY_TYPE_SENSORS = 0; // 0x0 - field public static final int RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS = 1; // 0x1 } public static final class VirtualDeviceParams.Builder { @@ -3278,7 +3277,6 @@ package android.companion.virtual { method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAudioRecordingSessionId(int); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@NonNull java.util.Set<android.content.ComponentName>); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedCrossTaskNavigations(@NonNull java.util.Set<android.content.ComponentName>); - method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setDefaultRecentsPolicy(int); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setDevicePolicy(int, int); method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setName(@NonNull String); @@ -10117,7 +10115,7 @@ package android.net.wifi.sharedconnectivity.app { } public static final class NetworkProviderInfo.Builder { - ctor public NetworkProviderInfo.Builder(); + ctor public NetworkProviderInfo.Builder(@NonNull String, @NonNull String); method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo build(); method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setBatteryPercentage(@IntRange(from=0, to=100) int); method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setConnectionStrength(@IntRange(from=0, to=3) int); diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java index 9f3b60148004..3a60a695a294 100644 --- a/core/java/android/companion/virtual/VirtualDeviceParams.java +++ b/core/java/android/companion/virtual/VirtualDeviceParams.java @@ -140,7 +140,8 @@ public final class VirtualDeviceParams implements Parcelable { * a given policy type. * @hide */ - @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO}) + @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO, + POLICY_TYPE_RECENTS}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface PolicyType {} @@ -169,22 +170,21 @@ public final class VirtualDeviceParams implements Parcelable { * <li>{@link #DEVICE_POLICY_CUSTOM}: audio framework will assign device specific session * ids to players and recorders constructed within device context. The session ids are * used to re-route corresponding audio streams to VirtualAudioDevice. - * <ul/> + * </ul> */ public static final int POLICY_TYPE_AUDIO = 1; - /** @hide */ - @IntDef(flag = true, prefix = "RECENTS_POLICY_", - value = {RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS}) - @Retention(RetentionPolicy.SOURCE) - @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) - public @interface RecentsPolicy {} - /** - * If set, activities launched on this virtual device are allowed to appear in the host device - * of the recently launched activities list. + * Tells the activity manager how to handle recents entries for activities run on this device. + * + * <ul> + * <li>{@link #DEVICE_POLICY_DEFAULT}: Activities launched on VirtualDisplays owned by this + * device will appear in the host device recents. + * <li>{@link #DEVICE_POLICY_CUSTOM}: Activities launched on VirtualDisplays owned by this + * * device will not appear in recents. + * </ul> */ - public static final int RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS = 1 << 0; + public static final int POLICY_TYPE_RECENTS = 2; private final int mLockState; @NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts; @@ -201,8 +201,6 @@ public final class VirtualDeviceParams implements Parcelable { @NonNull private final SparseIntArray mDevicePolicies; @NonNull private final List<VirtualSensorConfig> mVirtualSensorConfigs; @Nullable private final IVirtualSensorCallback mVirtualSensorCallback; - @RecentsPolicy - private final int mDefaultRecentsPolicy; private final int mAudioPlaybackSessionId; private final int mAudioRecordingSessionId; @@ -219,7 +217,6 @@ public final class VirtualDeviceParams implements Parcelable { @NonNull SparseIntArray devicePolicies, @NonNull List<VirtualSensorConfig> virtualSensorConfigs, @Nullable IVirtualSensorCallback virtualSensorCallback, - @RecentsPolicy int defaultRecentsPolicy, int audioPlaybackSessionId, int audioRecordingSessionId) { mLockState = lockState; @@ -237,10 +234,8 @@ public final class VirtualDeviceParams implements Parcelable { mDevicePolicies = Objects.requireNonNull(devicePolicies); mVirtualSensorConfigs = Objects.requireNonNull(virtualSensorConfigs); mVirtualSensorCallback = virtualSensorCallback; - mDefaultRecentsPolicy = defaultRecentsPolicy; mAudioPlaybackSessionId = audioPlaybackSessionId; mAudioRecordingSessionId = audioRecordingSessionId; - } @SuppressWarnings("unchecked") @@ -259,7 +254,6 @@ public final class VirtualDeviceParams implements Parcelable { parcel.readTypedList(mVirtualSensorConfigs, VirtualSensorConfig.CREATOR); mVirtualSensorCallback = IVirtualSensorCallback.Stub.asInterface(parcel.readStrongBinder()); - mDefaultRecentsPolicy = parcel.readInt(); mAudioPlaybackSessionId = parcel.readInt(); mAudioRecordingSessionId = parcel.readInt(); } @@ -396,16 +390,6 @@ public final class VirtualDeviceParams implements Parcelable { } /** - * Returns the policy of how to handle activities in recents. - * - * @see RecentsPolicy - */ - @RecentsPolicy - public int getDefaultRecentsPolicy() { - return mDefaultRecentsPolicy; - } - - /** * Returns device-specific audio session id for playback. * * @see Builder#setAudioPlaybackSessionId(int) @@ -443,7 +427,6 @@ public final class VirtualDeviceParams implements Parcelable { dest.writeTypedList(mVirtualSensorConfigs); dest.writeStrongBinder( mVirtualSensorCallback != null ? mVirtualSensorCallback.asBinder() : null); - dest.writeInt(mDefaultRecentsPolicy); dest.writeInt(mAudioPlaybackSessionId); dest.writeInt(mAudioRecordingSessionId); } @@ -478,7 +461,6 @@ public final class VirtualDeviceParams implements Parcelable { && Objects.equals(mBlockedActivities, that.mBlockedActivities) && mDefaultActivityPolicy == that.mDefaultActivityPolicy && Objects.equals(mName, that.mName) - && mDefaultRecentsPolicy == that.mDefaultRecentsPolicy && mAudioPlaybackSessionId == that.mAudioPlaybackSessionId && mAudioRecordingSessionId == that.mAudioRecordingSessionId; } @@ -489,7 +471,7 @@ public final class VirtualDeviceParams implements Parcelable { mLockState, mUsersWithMatchingAccounts, mAllowedCrossTaskNavigations, mBlockedCrossTaskNavigations, mDefaultNavigationPolicy, mAllowedActivities, mBlockedActivities, mDefaultActivityPolicy, mName, mDevicePolicies, - mDefaultRecentsPolicy, mAudioPlaybackSessionId, mAudioRecordingSessionId); + mAudioPlaybackSessionId, mAudioRecordingSessionId); for (int i = 0; i < mDevicePolicies.size(); i++) { hashCode = 31 * hashCode + mDevicePolicies.keyAt(i); hashCode = 31 * hashCode + mDevicePolicies.valueAt(i); @@ -511,7 +493,6 @@ public final class VirtualDeviceParams implements Parcelable { + " mDefaultActivityPolicy=" + mDefaultActivityPolicy + " mName=" + mName + " mDevicePolicies=" + mDevicePolicies - + " mDefaultRecentsPolicy=" + mDefaultRecentsPolicy + " mAudioPlaybackSessionId=" + mAudioPlaybackSessionId + " mAudioRecordingSessionId=" + mAudioRecordingSessionId + ")"; @@ -548,7 +529,6 @@ public final class VirtualDeviceParams implements Parcelable { private boolean mDefaultActivityPolicyConfigured = false; @Nullable private String mName; @NonNull private SparseIntArray mDevicePolicies = new SparseIntArray(); - private int mDefaultRecentsPolicy; private int mAudioPlaybackSessionId = AUDIO_SESSION_ID_GENERATE; private int mAudioRecordingSessionId = AUDIO_SESSION_ID_GENERATE; @@ -821,17 +801,6 @@ public final class VirtualDeviceParams implements Parcelable { } /** - * Sets the policy to indicate how activities are handled in recents. - * - * @param defaultRecentsPolicy A policy specifying how to handle activities in recents. - */ - @NonNull - public Builder setDefaultRecentsPolicy(@RecentsPolicy int defaultRecentsPolicy) { - mDefaultRecentsPolicy = defaultRecentsPolicy; - return this; - } - - /** * Sets audio playback session id specific for this virtual device. * * <p>Audio players constructed within context associated with this virtual device @@ -933,7 +902,6 @@ public final class VirtualDeviceParams implements Parcelable { mDevicePolicies, mVirtualSensorConfigs, mVirtualSensorCallback, - mDefaultRecentsPolicy, mAudioPlaybackSessionId, mAudioRecordingSessionId); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d7cd61567cc7..ef007746a67f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8289,6 +8289,15 @@ public final class Settings { "accessibility_display_inversion_enabled"; /** + * Flag that specifies whether font size has been changed. The flag will + * be set when users change the scaled value of font size for the first time. + * @hide + */ + @Readable + public static final String ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED = + "accessibility_font_scaling_has_been_changed"; + + /** * Setting that specifies whether display color space adjustment is * enabled. * diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 71a3a7b7cc51..807af5b54081 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1650,6 +1650,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mThreadedRenderer = renderer; renderer.setSurfaceControl(mSurfaceControl, mBlastBufferQueue); updateColorModeIfNeeded(attrs.getColorMode()); + updateRenderHdrSdrRatio(); updateForceDarkMode(); mAttachInfo.mHardwareAccelerated = true; mAttachInfo.mHardwareAccelerationRequested = true; @@ -5379,6 +5380,11 @@ public final class ViewRootImpl implements ViewParent, } } + private void updateRenderHdrSdrRatio() { + mRenderHdrSdrRatio = mDisplay.getHdrSdrRatio(); + mUpdateHdrSdrRatioInfo = true; + } + private void updateColorModeIfNeeded(@ActivityInfo.ColorMode int colorMode) { if (mAttachInfo.mThreadedRenderer == null) { return; @@ -5396,8 +5402,7 @@ public final class ViewRootImpl implements ViewParent, float desiredRatio = mAttachInfo.mThreadedRenderer.setColorMode(colorMode); if (desiredRatio != mDesiredHdrSdrRatio) { mDesiredHdrSdrRatio = desiredRatio; - mRenderHdrSdrRatio = mDisplay.getHdrSdrRatio(); - mUpdateHdrSdrRatioInfo = true; + updateRenderHdrSdrRatio(); if (mDesiredHdrSdrRatio < 1.01f) { mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener); @@ -8496,6 +8501,7 @@ public final class ViewRootImpl implements ViewParent, if (mAttachInfo.mThreadedRenderer != null) { mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl, mBlastBufferQueue); } + updateRenderHdrSdrRatio(); if (mPreviousTransformHint != transformHint) { mPreviousTransformHint = transformHint; dispatchTransformHintChanged(transformHint); diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java index b9d3df678a91..8369a303889d 100644 --- a/core/java/com/android/internal/compat/ChangeReporter.java +++ b/core/java/com/android/internal/compat/ChangeReporter.java @@ -42,6 +42,7 @@ import java.util.Set; public final class ChangeReporter { private static final String TAG = "CompatibilityChangeReporter"; private int mSource; + private static final boolean sShouldReport = false; private static final class ChangeReport { long mChangeId; @@ -89,14 +90,16 @@ public final class ChangeReporter { * @param state of the reported change - enabled/disabled/only logged */ public void reportChange(int uid, long changeId, int state) { - if (shouldWriteToStatsLog(uid, changeId, state)) { - FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, - changeId, state, mSource); - } - if (shouldWriteToDebug(uid, changeId, state)) { - debugLog(uid, changeId, state); + if (sShouldReport) { + if (shouldWriteToStatsLog(uid, changeId, state)) { + FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, + changeId, state, mSource); + } + if (shouldWriteToDebug(uid, changeId, state)) { + debugLog(uid, changeId, state); + } + markAsReported(uid, new ChangeReport(changeId, state)); } - markAsReported(uid, new ChangeReport(changeId, state)); } /** diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 8caf12773260..a5d287c3e4b2 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -95,6 +95,8 @@ message SecureSettingsProto { optional SettingProto hearing_aid_media_routing = 48 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto hearing_aid_system_sounds_routing = 49 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto accessibility_magnification_joystick_enabled = 50 [ (android.privacy).dest = DEST_AUTOMATIC ]; + // Settings for font scaling + optional SettingProto accessibility_font_scaling_has_been_changed = 51 [ (android.privacy).dest = DEST_AUTOMATIC ]; } optional Accessibility accessibility = 2; diff --git a/core/res/res/xml/irq_device_map.xml b/core/res/res/xml/irq_device_map.xml index 86a44d6a9fe0..4fae8fb77687 100644 --- a/core/res/res/xml/irq_device_map.xml +++ b/core/res/res/xml/irq_device_map.xml @@ -17,14 +17,15 @@ */ --> <irq-device-map> - <!-- This file maps devices (chips) that can send IRQs to the CPU (and bring it out of sleep) to - logical subsystems in userspace code. Since each Android device has its own uniquely - designed chipset, this mapping is expected to be empty by default and should be overridden - by device specific configs. + <!-- This file maps devices (chips) that can send interrupts to the main processor (and bring it + out of sleep) to logical subsystems in userspace code. Since each Android device has its own + uniquely designed chipset, this mapping is expected to be empty by default and should be + overridden by device-specific configs. This mapping helps the system to meaningfully attribute CPU wakeups to logical work that happened on the device. The devices are referred to by their names as defined in the kernel. - Currently defined subsystems are: + Currently, defined subsystems are: - Alarm: Use this to denote wakeup alarms requested by apps via the AlarmManager API. + - Wifi: Use this to denote network traffic that uses the wifi transport. The overlay should use tags <device> and <subsystem> to describe this mapping in the following way: diff --git a/core/tests/overlaytests/device/Android.bp b/core/tests/overlaytests/device/Android.bp index 0d3b15a41e8c..2b22344a4ef2 100644 --- a/core/tests/overlaytests/device/Android.bp +++ b/core/tests/overlaytests/device/Android.bp @@ -29,6 +29,7 @@ android_test { static_libs: [ "androidx.test.rules", "testng", + "compatibility-device-util-axt", ], test_suites: ["device-tests"], data: [ diff --git a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java index 8e4b9efafccd..fcf71ed39ef5 100644 --- a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java +++ b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java @@ -37,10 +37,12 @@ import android.view.View; import androidx.test.InstrumentationRegistry; +import com.android.compatibility.common.util.AmUtils; import com.android.internal.util.ArrayUtils; import com.android.overlaytest.view.TestTextView; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; @@ -70,6 +72,13 @@ public abstract class OverlayBaseTest { mMode = mode; } + @BeforeClass + public static void setUpClass() { + // Wait for package_added broadcasts to be handled so that OverlayManagerService + // can update it's internal state with the new packages. + AmUtils.waitForBroadcastBarrier(); + } + @Before public void setUp() { mContext = InstrumentationRegistry.getContext(); diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 3d81d37aff20..05e17720b175 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -271,6 +271,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, + "-1868518158": { + "message": "Pending back animation due to another animation is running", + "level": "WARN", + "group": "WM_DEBUG_BACK_PREVIEW", + "at": "com\/android\/server\/wm\/BackNavigationController.java" + }, "-1868124841": { "message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b", "level": "VERBOSE", @@ -1549,6 +1555,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DragState.java" }, + "-692907078": { + "message": "Handling the deferred animation after transition finished", + "level": "DEBUG", + "group": "WM_DEBUG_BACK_PREVIEW", + "at": "com\/android\/server\/wm\/BackNavigationController.java" + }, "-677449371": { "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b", "level": "DEBUG", diff --git a/libs/WindowManager/Shell/res/color/split_divider_background.xml b/libs/WindowManager/Shell/res/color-night/taskbar_background.xml index 049980803ee3..9473cdd607d6 100644 --- a/libs/WindowManager/Shell/res/color/split_divider_background.xml +++ b/libs/WindowManager/Shell/res/color-night/taskbar_background.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2021 The Android Open Source Project + ~ 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. @@ -14,6 +14,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> +<!-- Should be the same as in packages/apps/Launcher3/res/color-night-v31/taskbar_background.xml --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/system_neutral1_500" android:lStar="15" /> </selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/color/taskbar_background.xml b/libs/WindowManager/Shell/res/color/taskbar_background.xml index b3d260299106..0e165fca4fd3 100644 --- a/libs/WindowManager/Shell/res/color/taskbar_background.xml +++ b/libs/WindowManager/Shell/res/color/taskbar_background.xml @@ -16,5 +16,5 @@ --> <!-- Should be the same as in packages/apps/Launcher3/res/color-v31/taskbar_background.xml --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:color="@android:color/system_neutral1_500" android:lStar="15" /> + <item android:color="@android:color/system_neutral1_500" android:lStar="95" /> </selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/values-night/colors.xml b/libs/WindowManager/Shell/res/values-night/colors.xml index 83c4d93982f4..5c6bb57a7f1c 100644 --- a/libs/WindowManager/Shell/res/values-night/colors.xml +++ b/libs/WindowManager/Shell/res/values-night/colors.xml @@ -15,6 +15,7 @@ --> <resources> + <color name="docked_divider_handle">#ffffff</color> <!-- Bubbles --> <color name="bubbles_icon_tint">@color/GM2_grey_200</color> <!-- Splash screen--> diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml index 965ab1519df4..6fb70006e67f 100644 --- a/libs/WindowManager/Shell/res/values/colors.xml +++ b/libs/WindowManager/Shell/res/values/colors.xml @@ -17,7 +17,8 @@ */ --> <resources> - <color name="docked_divider_handle">#ffffff</color> + <color name="docked_divider_handle">#000000</color> + <color name="split_divider_background">@color/taskbar_background</color> <drawable name="forced_resizable_background">#59000000</drawable> <color name="minimize_dock_shadow_start">#60000000</color> <color name="minimize_dock_shadow_end">#00000000</color> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java index b3fff1d05263..0b8759890359 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java @@ -552,6 +552,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (runner.isWaitingAnimation()) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready."); return; + } else if (runner.isAnimationCancelled()) { + invokeOrCancelBack(); + return; } startPostCommitAnimation(); } @@ -653,7 +656,19 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } @Override - public void onAnimationCancelled() { } + public void onAnimationCancelled() { + mShellExecutor.execute(() -> { + final BackAnimationRunner runner = mAnimationDefinition.get( + mBackNavigationInfo.getType()); + if (runner == null) { + return; + } + runner.cancelAnimation(); + if (!mBackGestureStarted) { + invokeOrCancelBack(); + } + }); + } }; mBackAnimationAdapter = new BackAnimationAdapter(runner); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java index d70b8f53a911..82c523f337db 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java @@ -41,6 +41,9 @@ class BackAnimationRunner { // Whether we are waiting to receive onAnimationStart private boolean mWaitingAnimation; + /** True when the back animation is cancelled */ + private boolean mAnimationCancelled; + BackAnimationRunner(@NonNull IOnBackInvokedCallback callback, @NonNull IRemoteAnimationRunner runner) { mCallback = callback; @@ -81,9 +84,19 @@ class BackAnimationRunner { void startGesture() { mWaitingAnimation = true; + mAnimationCancelled = false; } boolean isWaitingAnimation() { return mWaitingAnimation; } + + void cancelAnimation() { + mWaitingAnimation = false; + mAnimationCancelled = true; + } + + boolean isAnimationCancelled() { + return mAnimationCancelled; + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 7ac4d51c1502..b447a543989e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -120,6 +120,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange private int mOrientation; private int mRotation; private int mDensity; + private int mUiMode; private final boolean mDimNonImeSide; private ValueAnimator mDividerFlingAnimator; @@ -295,10 +296,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange final Rect rootBounds = configuration.windowConfiguration.getBounds(); final int orientation = configuration.orientation; final int density = configuration.densityDpi; + final int uiMode = configuration.uiMode; if (mOrientation == orientation && mRotation == rotation && mDensity == density + && mUiMode == uiMode && mRootBounds.equals(rootBounds)) { return false; } @@ -310,6 +313,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mRootBounds.set(rootBounds); mRotation = rotation; mDensity = density; + mUiMode = uiMode; mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null); updateDividerConfig(mContext); initDividerPosition(mTempRect); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 427d79e3a1b9..225258773013 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -20,7 +20,6 @@ import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED; import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; @@ -661,6 +660,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); + prepareEvictChildTasksIfSplitActive(wct); setSideStagePosition(splitPosition, wct); options1 = options1 != null ? options1 : new Bundle(); addActivityOptions(options1, mSideStage); @@ -675,6 +675,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @SplitPosition int splitPosition, float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); + prepareEvictChildTasksIfSplitActive(wct); setSideStagePosition(splitPosition, wct); options1 = options1 != null ? options1 : new Bundle(); addActivityOptions(options1, mSideStage); @@ -688,6 +689,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); + prepareEvictChildTasksIfSplitActive(wct); setSideStagePosition(splitPosition, wct); options1 = options1 != null ? options1 : new Bundle(); addActivityOptions(options1, mSideStage); @@ -706,10 +708,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void startWithTask(WindowContainerTransaction wct, int mainTaskId, @Nullable Bundle mainOptions, float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { - if (mMainStage.isActive()) { - mMainStage.evictAllChildren(wct); - mSideStage.evictAllChildren(wct); - } else { + if (!mMainStage.isActive()) { // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(wct, false /* reparent */); @@ -1020,6 +1019,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSideStage.evictInvisibleChildren(wct); } + void prepareEvictChildTasksIfSplitActive(WindowContainerTransaction wct) { + if (mMainStage.isActive()) { + mMainStage.evictAllChildren(wct); + mSideStage.evictAllChildren(wct); + } + } + Bundle resolveStartStage(@StageType int stage, @SplitPosition int position, @Nullable Bundle options, @Nullable WindowContainerTransaction wct) { switch (stage) { @@ -2160,19 +2166,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } else if (isOpening && inFullscreen) { final int activityType = triggerTask.getActivityType(); - if (activityType == ACTIVITY_TYPE_ASSISTANT) { - // We don't want assistant panel to dismiss split screen, so do nothing. - } else if (activityType == ACTIVITY_TYPE_HOME + if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) { // Enter overview panel, so start recent transition. mSplitTransitions.setRecentTransition(transition, request.getRemoteTransition(), mRecentTransitionFinishedCallback); - } else if (mSplitTransitions.mPendingRecent == null) { - // If split-task is not controlled by recents animation - // and occluded by the other fullscreen task, dismiss both. - prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, out); - mSplitTransitions.setDismissTransition( - transition, STAGE_TYPE_UNDEFINED, EXIT_REASON_UNKNOWN); } } } else { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java index ed0ac5f1cdca..3901dabcaec8 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java @@ -284,41 +284,6 @@ public class SplitTransitionTests extends ShellTestCase { @Test @UiThreadTest - public void testDismissFromBeingOccluded() { - enterSplit(); - - ActivityManager.RunningTaskInfo normalTask = new TestRunningTaskInfoBuilder() - .setWindowingMode(WINDOWING_MODE_FULLSCREEN) - .build(); - - // Create a request to bring a normal task forward - TransitionRequestInfo request = - new TransitionRequestInfo(TRANSIT_TO_FRONT, normalTask, null); - IBinder transition = mock(IBinder.class); - WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request); - - assertTrue(containsSplitExit(result)); - - // make sure we haven't made any local changes yet (need to wait until transition is ready) - assertTrue(mStageCoordinator.isSplitScreenVisible()); - - // simulate the transition - TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT, 0) - .addChange(TRANSIT_TO_FRONT, normalTask) - .addChange(TRANSIT_TO_BACK, mMainChild) - .addChange(TRANSIT_TO_BACK, mSideChild) - .build(); - mMainStage.onTaskVanished(mMainChild); - mSideStage.onTaskVanished(mSideChild); - mStageCoordinator.startAnimation(transition, info, - mock(SurfaceControl.Transaction.class), - mock(SurfaceControl.Transaction.class), - mock(Transitions.TransitionFinishCallback.class)); - assertFalse(mStageCoordinator.isSplitScreenVisible()); - } - - @Test - @UiThreadTest public void testDismissFromMultiWindowSupport() { enterSplit(); diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle index 640aa01f307f..4563b7d75b22 100644 --- a/packages/SettingsLib/Spa/spa/build.gradle +++ b/packages/SettingsLib/Spa/spa/build.gradle @@ -48,11 +48,11 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = '17' freeCompilerArgs = ["-Xjvm-default=all"] } buildFeatures { diff --git a/packages/SettingsLib/Spa/testutils/build.gradle b/packages/SettingsLib/Spa/testutils/build.gradle index 536829e00b65..e7f7db2f1ec0 100644 --- a/packages/SettingsLib/Spa/testutils/build.gradle +++ b/packages/SettingsLib/Spa/testutils/build.gradle @@ -38,11 +38,11 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = '17' freeCompilerArgs = ["-Xjvm-default=all"] } buildFeatures { diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 93394f3872ee..f66fcba74bc5 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -239,5 +239,6 @@ public class SecureSettings { Settings.Secure.HEARING_AID_CALL_ROUTING, Settings.Secure.HEARING_AID_MEDIA_ROUTING, Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, + Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED }; } diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 96578626d5cc..558e19f19986 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -376,5 +376,6 @@ public class SecureSettingsValidators { new DiscreteValueValidator(new String[] {"0", "1", "2"})); VALIDATORS.put(Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, new DiscreteValueValidator(new String[] {"0", "1", "2"})); + VALIDATORS.put(Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, BOOLEAN_VALIDATOR); } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index fb3c3136280e..1a6920803b03 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1852,6 +1852,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, SecureSettingsProto.Accessibility.HEARING_AID_SYSTEM_SOUNDS_ROUTING); + dumpSetting(s, p, + Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, + SecureSettingsProto.Accessibility.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED); p.end(accessibilityToken); final long adaptiveSleepToken = p.start(SecureSettingsProto.ADAPTIVE_SLEEP); diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java index ace3d949480b..fca55b1c69b4 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java @@ -43,7 +43,6 @@ import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.wm.shell.util.TransitionUtil; import java.util.ArrayList; @@ -56,7 +55,7 @@ public class RemoteTransitionCompat { /** Constructor specifically for recents animation */ public static RemoteTransition newRemoteTransition(RecentsAnimationListener recents, - RecentsAnimationControllerCompat controller, IApplicationThread appThread) { + IApplicationThread appThread) { IRemoteTransition remote = new IRemoteTransition.Stub() { final RecentsControllerWrap mRecentsSession = new RecentsControllerWrap(); IBinder mToken = null; @@ -67,7 +66,7 @@ public class RemoteTransitionCompat { IRemoteTransitionFinishedCallback finishedCallback) { // TODO(b/177438007): Move this set-up logic into launcher's animation impl. mToken = transition; - mRecentsSession.start(controller, recents, mToken, info, t, finishedCallback); + mRecentsSession.start(recents, mToken, info, t, finishedCallback); } @Override @@ -96,9 +95,8 @@ public class RemoteTransitionCompat { * TODO(b/177438007): Remove this once Launcher handles shell transitions directly. */ @VisibleForTesting - static class RecentsControllerWrap extends RecentsAnimationControllerCompat { + static class RecentsControllerWrap extends IRecentsAnimationController.Default { private RecentsAnimationListener mListener = null; - private RecentsAnimationControllerCompat mWrapped = null; private IRemoteTransitionFinishedCallback mFinishCB = null; /** @@ -135,7 +133,7 @@ public class RemoteTransitionCompat { /** The latest state that the recents animation is operating in. */ private int mState = STATE_NORMAL; - void start(RecentsAnimationControllerCompat wrapped, RecentsAnimationListener listener, + void start(RecentsAnimationListener listener, IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishedCallback) { if (mInfo != null) { @@ -143,7 +141,6 @@ public class RemoteTransitionCompat { + " recents is already active."); } mListener = listener; - mWrapped = wrapped; mInfo = info; mFinishCB = finishedCallback; mPausingTasks = new ArrayList<>(); @@ -200,7 +197,8 @@ public class RemoteTransitionCompat { } } t.apply(); - mListener.onAnimationStart(this, apps.toArray(new RemoteAnimationTarget[apps.size()]), + mListener.onAnimationStart(new RecentsAnimationControllerCompat(this), + apps.toArray(new RemoteAnimationTarget[apps.size()]), wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]), new Rect(0, 0, 0, 0), new Rect()); } @@ -342,13 +340,9 @@ public class RemoteTransitionCompat { } } - @Override public ThumbnailData screenshotTask(int taskId) { + @Override public TaskSnapshot screenshotTask(int taskId) { try { - final TaskSnapshot snapshot = - ActivityTaskManager.getService().takeTaskSnapshot(taskId); - if (snapshot != null) { - return new ThumbnailData(snapshot); - } + return ActivityTaskManager.getService().takeTaskSnapshot(taskId); } catch (RemoteException e) { Log.e(TAG, "Failed to screenshot task", e); } @@ -356,30 +350,24 @@ public class RemoteTransitionCompat { } @Override public void setInputConsumerEnabled(boolean enabled) { - if (enabled) { - // transient launches don't receive focus automatically. Since we are taking over - // the gesture now, take focus explicitly. - // This also moves recents back to top if the user gestured before a switch - // animation finished. - try { - ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId); - } catch (RemoteException e) { - Log.e(TAG, "Failed to set focused task", e); - } + if (!enabled) return; + // transient launches don't receive focus automatically. Since we are taking over + // the gesture now, take focus explicitly. + // This also moves recents back to top if the user gestured before a switch + // animation finished. + try { + ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId); + } catch (RemoteException e) { + Log.e(TAG, "Failed to set focused task", e); } - if (mWrapped != null) mWrapped.setInputConsumerEnabled(enabled); } @Override public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) { - if (mWrapped != null) mWrapped.setAnimationTargetsBehindSystemBars(behindSystemBars); } @Override public void setFinishTaskTransaction(int taskId, PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) { mPipTransaction = finishTransaction; - if (mWrapped != null) { - mWrapped.setFinishTaskTransaction(taskId, finishTransaction, overlay); - } } @Override @@ -389,7 +377,6 @@ public class RemoteTransitionCompat { Log.e(TAG, "Duplicate call to finish", new RuntimeException()); return; } - if (mWrapped != null) mWrapped.finish(toHome, sendUserLeaveHint); final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); final WindowContainerTransaction wct = new WindowContainerTransaction(); @@ -462,7 +449,6 @@ public class RemoteTransitionCompat { // for releasing the leashes created by local. mInfo.releaseAllSurfaces(); // Reset all members. - mWrapped = null; mListener = null; mFinishCB = null; mPausingTasks = null; @@ -476,23 +462,20 @@ public class RemoteTransitionCompat { } @Override public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) { - if (mWrapped != null) mWrapped.setDeferCancelUntilNextTransition(defer, screenshot); } @Override public void cleanupScreenshot() { - if (mWrapped != null) mWrapped.cleanupScreenshot(); } @Override public void setWillFinishToHome(boolean willFinishToHome) { mWillFinishToHome = willFinishToHome; - if (mWrapped != null) mWrapped.setWillFinishToHome(willFinishToHome); } /** * @see IRecentsAnimationController#removeTask */ @Override public boolean removeTask(int taskId) { - return mWrapped != null ? mWrapped.removeTask(taskId) : false; + return false; } /** diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java index e52f1d9c61db..1c4602803426 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -16,7 +16,6 @@ package com.android.server.companion.virtual; -import static android.companion.virtual.VirtualDeviceParams.RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; @@ -29,7 +28,6 @@ import android.app.compat.CompatChanges; import android.companion.virtual.VirtualDeviceManager.ActivityListener; import android.companion.virtual.VirtualDeviceParams; import android.companion.virtual.VirtualDeviceParams.ActivityPolicy; -import android.companion.virtual.VirtualDeviceParams.RecentsPolicy; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.ComponentName; @@ -137,8 +135,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController new ArraySet<>(); @Nullable private final SecureWindowCallback mSecureWindowCallback; @Nullable private final List<String> mDisplayCategories; - @RecentsPolicy - private final int mDefaultRecentsPolicy; + + private final boolean mShowTasksInHostDeviceRecents; /** * Creates a window policy controller that is generic to the different use cases of virtual @@ -166,7 +164,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController * virtual display. * @param intentListenerCallback Callback that is called to intercept intents when matching * passed in filters. - * @param defaultRecentsPolicy a policy to indicate how to handle activities in recents. + * @param showTasksInHostDeviceRecents whether to show activities in recents on the host device. */ public GenericWindowPolicyController(int windowFlags, int systemWindowFlags, @NonNull ArraySet<UserHandle> allowedUsers, @@ -181,7 +179,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @NonNull SecureWindowCallback secureWindowCallback, @NonNull IntentListenerCallback intentListenerCallback, @NonNull List<String> displayCategories, - @RecentsPolicy int defaultRecentsPolicy) { + boolean showTasksInHostDeviceRecents) { super(); mAllowedUsers = allowedUsers; mAllowedCrossTaskNavigations = new ArraySet<>(allowedCrossTaskNavigations); @@ -196,7 +194,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController mSecureWindowCallback = secureWindowCallback; mIntentListenerCallback = intentListenerCallback; mDisplayCategories = displayCategories; - mDefaultRecentsPolicy = defaultRecentsPolicy; + mShowTasksInHostDeviceRecents = showTasksInHostDeviceRecents; } /** @@ -337,7 +335,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @Override public boolean canShowTasksInHostDeviceRecents() { - return (mDefaultRecentsPolicy & RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS) != 0; + return mShowTasksInHostDeviceRecents; } @Override diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index ee1b1fd4a500..2d010cf66e9b 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -846,7 +846,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub this::onSecureWindowShown, this::shouldInterceptIntent, displayCategories, - mParams.getDefaultRecentsPolicy()); + mParams.getDevicePolicy( + VirtualDeviceParams.POLICY_TYPE_RECENTS) + == VirtualDeviceParams.DEVICE_POLICY_DEFAULT); gwpc.registerRunningAppsChangedListener(/* listener= */ this); return gwpc; } diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java index 17ef9a232401..c6f63dd73a25 100644 --- a/services/core/java/android/os/BatteryStatsInternal.java +++ b/services/core/java/android/os/BatteryStatsInternal.java @@ -38,11 +38,13 @@ public abstract class BatteryStatsInternal { public static final int CPU_WAKEUP_SUBSYSTEM_UNKNOWN = -1; public static final int CPU_WAKEUP_SUBSYSTEM_ALARM = 1; + public static final int CPU_WAKEUP_SUBSYSTEM_WIFI = 2; /** @hide */ @IntDef(prefix = {"CPU_WAKEUP_SUBSYSTEM_"}, value = { CPU_WAKEUP_SUBSYSTEM_UNKNOWN, CPU_WAKEUP_SUBSYSTEM_ALARM, + CPU_WAKEUP_SUBSYSTEM_WIFI, }) @Retention(RetentionPolicy.SOURCE) @interface CpuWakeupSubsystem { diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 160756616907..0ee883f745ca 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -23,6 +23,7 @@ import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.POWER_SAVER; import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE; @@ -479,9 +480,29 @@ public final class BatteryStatsService extends IBatteryStats.Stub BatteryStatsService.this.noteJobsDeferred(uid, numDeferred, sinceLast); } + private int transportToSubsystem(NetworkCapabilities nc) { + if (nc.hasTransport(TRANSPORT_WIFI)) { + return CPU_WAKEUP_SUBSYSTEM_WIFI; + } + return CPU_WAKEUP_SUBSYSTEM_UNKNOWN; + } + @Override public void noteCpuWakingNetworkPacket(Network network, long elapsedMillis, int uid) { - Slog.d(TAG, "Wakeup due to incoming packet on network " + network + " to uid " + uid); + if (uid < 0) { + Slog.e(TAG, "Invalid uid for waking network packet: " + uid); + return; + } + final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); + final NetworkCapabilities nc = cm.getNetworkCapabilities(network); + final int subsystem = transportToSubsystem(nc); + + if (subsystem == CPU_WAKEUP_SUBSYSTEM_UNKNOWN) { + Slog.wtf(TAG, "Could not map transport for network: " + network + + " while attributing wakeup by packet sent to uid: " + uid); + return; + } + noteCpuWakingActivity(subsystem, elapsedMillis, uid); } @Override diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java index 49279d44ea7c..2d6966ad0cf8 100644 --- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java @@ -327,9 +327,12 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { } private void commitUidPendingState(int uid) { - int pendingUidState = mPendingUidStates.get(uid, MIN_PRIORITY_UID_STATE); - int pendingCapability = mPendingCapability.get(uid, PROCESS_CAPABILITY_NONE); - boolean pendingVisibleAppWidget = mPendingVisibleAppWidget.get(uid, false); + int pendingUidState = mPendingUidStates.get(uid, + mUidStates.get(uid, MIN_PRIORITY_UID_STATE)); + int pendingCapability = mPendingCapability.get(uid, + mCapability.get(uid, PROCESS_CAPABILITY_NONE)); + boolean pendingVisibleAppWidget = mPendingVisibleAppWidget.get(uid, + mVisibleAppWidget.get(uid, false)); int uidState = mUidStates.get(uid, MIN_PRIORITY_UID_STATE); int capability = mCapability.get(uid, PROCESS_CAPABILITY_NONE); diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index 67639fbef124..28cb7f0b03a6 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -2048,6 +2048,9 @@ class ShortcutPackage extends ShortcutPackageItem { shortcutUser.getUserId(), fromBackup); // Don't use addShortcut(), we don't need to save the icon. ret.mShortcuts.put(si.getId(), si); + } catch (IOException e) { + // Don't ignore IO exceptions. + throw e; } catch (Exception e) { // b/246540168 malformed shortcuts should be ignored Slog.e(TAG, "Failed parsing shortcut.", e); diff --git a/services/core/java/com/android/server/power/stats/CpuWakeupStats.java b/services/core/java/com/android/server/power/stats/CpuWakeupStats.java index 54f3476d3b86..e8c0e5924252 100644 --- a/services/core/java/com/android/server/power/stats/CpuWakeupStats.java +++ b/services/core/java/com/android/server/power/stats/CpuWakeupStats.java @@ -18,6 +18,7 @@ package com.android.server.power.stats; import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_ALARM; import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN; +import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI; import android.content.Context; import android.os.Handler; @@ -49,6 +50,7 @@ public class CpuWakeupStats { private static final String TAG = "CpuWakeupStats"; private static final String SUBSYSTEM_ALARM_STRING = "Alarm"; + private static final String SUBSYSTEM_ALARM_WIFI = "Wifi"; @VisibleForTesting static final long WAKEUP_RETENTION_MS = 3 * 24 * 60 * 60_000; // 3 days. @VisibleForTesting @@ -74,6 +76,8 @@ public class CpuWakeupStats { switch (subsystem) { case CPU_WAKEUP_SUBSYSTEM_ALARM: return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__ALARM; + case CPU_WAKEUP_SUBSYSTEM_WIFI: + return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__WIFI; } return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__UNKNOWN; } @@ -425,6 +429,8 @@ public class CpuWakeupStats { switch (rawSubsystem) { case SUBSYSTEM_ALARM_STRING: return CPU_WAKEUP_SUBSYSTEM_ALARM; + case SUBSYSTEM_ALARM_WIFI: + return CPU_WAKEUP_SUBSYSTEM_WIFI; } return CPU_WAKEUP_SUBSYSTEM_UNKNOWN; } @@ -433,6 +439,8 @@ public class CpuWakeupStats { switch (subsystem) { case CPU_WAKEUP_SUBSYSTEM_ALARM: return SUBSYSTEM_ALARM_STRING; + case CPU_WAKEUP_SUBSYSTEM_WIFI: + return SUBSYSTEM_ALARM_WIFI; case CPU_WAKEUP_SUBSYSTEM_UNKNOWN: return "Unknown"; } diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index a229fc5b00d3..2d45dc20c963 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -75,6 +75,11 @@ class BackNavigationController { private final ArrayList<WindowContainer> mTmpOpenApps = new ArrayList<>(); private final ArrayList<WindowContainer> mTmpCloseApps = new ArrayList<>(); + // This will be set if the back navigation is in progress and the current transition is still + // running. The pending animation builder will do the animation stuff includes creating leashes, + // re-parenting leashes and set launch behind, etc. Will be handled when transition finished. + private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder; + /** * true if the back predictability feature is enabled */ @@ -305,25 +310,26 @@ class BackNavigationController { || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) && adapter != null; - // Only prepare animation if no leash has been created (no animation is running). - // TODO(b/241808055): Cancel animation when preparing back animation. - if (prepareAnimation - && (removedWindowContainer.hasCommittedReparentToAnimationLeash() - || removedWindowContainer.mTransitionController.inTransition())) { - Slog.w(TAG, "Can't prepare back animation due to another animation is running."); - prepareAnimation = false; - } - if (prepareAnimation) { - mPendingAnimation = mAnimationHandler.scheduleAnimation(backType, adapter, - currentTask, prevTask, currentActivity, prevActivity); - prepareAnimation = mPendingAnimation != null; - mBackAnimationInProgress = prepareAnimation; - if (prepareAnimation) { - mWindowManagerService.mWindowPlacerLocked.requestTraversal(); - if (mShowWallpaper) { - currentTask.getDisplayContent().mWallpaperController - .adjustWallpaperWindows(); + final AnimationHandler.ScheduleAnimationBuilder builder = + mAnimationHandler.prepareAnimation(backType, adapter, + currentTask, prevTask, currentActivity, prevActivity); + mBackAnimationInProgress = builder != null; + if (mBackAnimationInProgress) { + if (removedWindowContainer.hasCommittedReparentToAnimationLeash() + || removedWindowContainer.mTransitionController.inTransition() + || mWindowManagerService.mSyncEngine.hasPendingSyncSets()) { + ProtoLog.w(WM_DEBUG_BACK_PREVIEW, + "Pending back animation due to another animation is running"); + mPendingAnimationBuilder = builder; + // Current transition is still running, we have to defer the hiding to the + // client process to prevent the unexpected relayout when handling the back + // animation. + if (prevActivity != null) { + prevActivity.setDeferHidingClient(true); + } + } else { + scheduleAnimation(builder); } } } @@ -345,6 +351,15 @@ class BackNavigationController { return isWaitBackTransition() || mNavigationMonitor.isMonitoring(); } + private void scheduleAnimation(@NonNull AnimationHandler.ScheduleAnimationBuilder builder) { + mPendingAnimation = builder.build(); + mWindowManagerService.mWindowPlacerLocked.requestTraversal(); + if (mShowWallpaper) { + mWindowManagerService.getDefaultDisplayContentLocked().mWallpaperController + .adjustWallpaperWindows(); + } + } + private boolean isWaitBackTransition() { return mAnimationHandler.mComposed && mAnimationHandler.mWaitTransition; } @@ -526,6 +541,57 @@ class BackNavigationController { mAnimationHandler.clearBackAnimateTarget(cleanupTransaction); } + /** + * Handle the pending animation when the running transition finished. + * @param targets The final animation targets derived in transition. + */ + boolean handleDeferredBackAnimation(@NonNull ArrayList<Transition.ChangeInfo> targets) { + if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) { + return false; + } + + ProtoLog.d(WM_DEBUG_BACK_PREVIEW, + "Handling the deferred animation after transition finished"); + + // Show the target surface and its parents to prevent it or its parents hidden when + // the transition finished. + // The target could be affected by transition when : + // Open transition -> the open target in back navigation + // Close transition -> the close target in back navigation. + boolean hasTarget = false; + final SurfaceControl.Transaction t = + mPendingAnimationBuilder.mCloseTarget.getPendingTransaction(); + for (int i = 0; i < targets.size(); i++) { + final WindowContainer wc = targets.get(i).mContainer; + if (wc.asActivityRecord() == null && wc.asTask() == null) { + continue; + } else if (!mPendingAnimationBuilder.containTarget(wc)) { + continue; + } + + hasTarget = true; + t.show(wc.getSurfaceControl()); + } + + if (!hasTarget) { + // Skip if no target participated in current finished transition. + Slog.w(TAG, "Finished transition didn't include the targets" + + " open: " + mPendingAnimationBuilder.mOpenTarget + + " close: " + mPendingAnimationBuilder.mCloseTarget); + try { + mPendingAnimationBuilder.mBackAnimationAdapter.getRunner().onAnimationCancelled(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + mPendingAnimationBuilder = null; + return false; + } + + scheduleAnimation(mPendingAnimationBuilder); + mPendingAnimationBuilder = null; + return true; + } + /** * Create and handling animations status for an open/close animation targets. */ @@ -638,6 +704,7 @@ class BackNavigationController { if (open) { return wc == mOpenAdaptor.mTarget || mOpenAdaptor.mTarget.hasChild(wc); } + if (mSwitchType == TASK_SWITCH) { return wc == mCloseAdaptor.mTarget || (wc.asTask() != null && wc.hasChild(mCloseAdaptor.mTarget)); @@ -841,23 +908,22 @@ class BackNavigationController { } } - Runnable scheduleAnimation(int backType, BackAnimationAdapter adapter, + ScheduleAnimationBuilder prepareAnimation(int backType, BackAnimationAdapter adapter, Task currentTask, Task previousTask, ActivityRecord currentActivity, ActivityRecord previousActivity) { switch (backType) { case BackNavigationInfo.TYPE_RETURN_TO_HOME: return new ScheduleAnimationBuilder(backType, adapter) .setIsLaunchBehind(true) - .setComposeTarget(currentTask, previousTask) - .build(); + .setComposeTarget(currentTask, previousTask); case BackNavigationInfo.TYPE_CROSS_ACTIVITY: return new ScheduleAnimationBuilder(backType, adapter) .setComposeTarget(currentActivity, previousActivity) - .setOpeningSnapshot(getActivitySnapshot(previousActivity)).build(); + .setOpeningSnapshot(getActivitySnapshot(previousActivity)); case BackNavigationInfo.TYPE_CROSS_TASK: return new ScheduleAnimationBuilder(backType, adapter) .setComposeTarget(currentTask, previousTask) - .setOpeningSnapshot(getTaskSnapshot(previousTask)).build(); + .setOpeningSnapshot(getTaskSnapshot(previousTask)); } return null; } @@ -891,6 +957,11 @@ class BackNavigationController { return this; } + boolean containTarget(@NonNull WindowContainer wc) { + return wc == mOpenTarget || wc == mCloseTarget + || wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget); + } + Runnable build() { if (mOpenTarget == null || mCloseTarget == null) { return null; @@ -967,47 +1038,41 @@ class BackNavigationController { } }; } + } + } - private void setLaunchBehind(ActivityRecord activity) { - if (activity == null) { - return; - } - if (!activity.isVisibleRequested()) { - activity.setVisibility(true); - } - activity.mLaunchTaskBehind = true; - - // Handle fixed rotation launching app. - final DisplayContent dc = activity.mDisplayContent; - dc.rotateInDifferentOrientationIfNeeded(activity); - if (activity.hasFixedRotationTransform()) { - // Set the record so we can recognize it to continue to update display - // orientation if the previous activity becomes the top later. - dc.setFixedRotationLaunchingApp(activity, - activity.getWindowConfiguration().getRotation()); - } + private static void setLaunchBehind(@NonNull ActivityRecord activity) { + if (!activity.isVisibleRequested()) { + activity.setVisibility(true); + } + activity.mLaunchTaskBehind = true; + + // Handle fixed rotation launching app. + final DisplayContent dc = activity.mDisplayContent; + dc.rotateInDifferentOrientationIfNeeded(activity); + if (activity.hasFixedRotationTransform()) { + // Set the record so we can recognize it to continue to update display + // orientation if the previous activity becomes the top later. + dc.setFixedRotationLaunchingApp(activity, + activity.getWindowConfiguration().getRotation()); + } - ProtoLog.d(WM_DEBUG_BACK_PREVIEW, - "Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity); - activity.mTaskSupervisor.mStoppingActivities.remove(activity); - activity.getDisplayContent().ensureActivitiesVisible(null /* starting */, - 0 /* configChanges */, false /* preserveWindows */, true); - } - private void restoreLaunchBehind(ActivityRecord activity) { - if (activity == null) { - return; - } + ProtoLog.d(WM_DEBUG_BACK_PREVIEW, + "Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity); + activity.mTaskSupervisor.mStoppingActivities.remove(activity); + activity.getDisplayContent().ensureActivitiesVisible(null /* starting */, + 0 /* configChanges */, false /* preserveWindows */, true); + } - activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(); + private static void restoreLaunchBehind(@NonNull ActivityRecord activity) { + activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(); - // Restore the launch-behind state. - activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token); - activity.mLaunchTaskBehind = false; - ProtoLog.d(WM_DEBUG_BACK_PREVIEW, - "Setting Activity.mLauncherTaskBehind to false. Activity=%s", - activity); - } - } + // Restore the launch-behind state. + activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token); + activity.mLaunchTaskBehind = false; + ProtoLog.d(WM_DEBUG_BACK_PREVIEW, + "Setting Activity.mLauncherTaskBehind to false. Activity=%s", + activity); } void checkAnimationReady(WallpaperController wallpaperController) { @@ -1039,6 +1104,7 @@ class BackNavigationController { mNavigationMonitor.stopMonitor(); mBackAnimationInProgress = false; mShowWallpaper = false; + mPendingAnimationBuilder = null; } private static TaskSnapshot getActivitySnapshot(@NonNull ActivityRecord r) { diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 12cfa2634244..a30ab11d9f6d 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -989,6 +989,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { cleanUpInternal(); mController.updateAnimatingState(mTmpTransaction); mTmpTransaction.apply(); + + // Handle back animation if it's already started. + mController.mAtm.mBackNavigationController.handleDeferredBackAnimation(mTargets); } void abort() { diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 8e22821820a1..b9cb59a17a2e 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -74,7 +74,9 @@ import android.graphics.Point; import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.Parcel; import android.os.RemoteException; import android.util.AndroidRuntimeException; @@ -998,11 +1000,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub activityOptions.setCallerDisplayId(DEFAULT_DISPLAY); } final Bundle options = activityOptions != null ? activityOptions.toBundle() : null; - waitAsyncStart(() -> mService.mAmInternal.sendIntentSender( + int res = waitAsyncStart(() -> mService.mAmInternal.sendIntentSender( hop.getPendingIntent().getTarget(), hop.getPendingIntent().getWhitelistToken(), 0 /* code */, hop.getActivityIntent(), resolvedType, null /* finishReceiver */, null /* requiredPermission */, options)); + if (ActivityManager.isStartResultSuccessful(res)) { + effects |= TRANSACT_EFFECTS_LIFECYCLE; + } break; } case HIERARCHY_OP_TYPE_START_SHORTCUT: { @@ -1353,9 +1358,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub * Post and wait for the result of the activity start to prevent potential deadlock against * {@link WindowManagerGlobalLock}. */ - private void waitAsyncStart(IntSupplier startActivity) { + private int waitAsyncStart(IntSupplier startActivity) { final Integer[] starterResult = {null}; - mService.mH.post(() -> { + final Handler handler = (Looper.myLooper() == mService.mH.getLooper()) + // uncommon case where a queued transaction is trying to start an activity. We can't + // post to our own thread and wait (otherwise we deadlock), so use anim thread + // instead (which is 1 higher priority). + ? mService.mWindowManager.mAnimationHandler + // Otherwise just put it on main handler + : mService.mH; + handler.post(() -> { try { starterResult[0] = startActivity.getAsInt(); } catch (Throwable t) { @@ -1372,6 +1384,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } catch (InterruptedException ignored) { } } + return starterResult[0]; } private int sanitizeAndApplyHierarchyOp(WindowContainer container, diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 3a7b9a49f161..90dbd539f029 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -115,6 +115,7 @@ android_test { ":StubTestApp", ":SuspendTestApp", ":MediaButtonReceiverHolderTestHelperApp", + "data/broken_shortcut.xml", ], java_resources: [ diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml index d9676470aca3..b304968f3e69 100644 --- a/services/tests/servicestests/AndroidTest.xml +++ b/services/tests/servicestests/AndroidTest.xml @@ -21,6 +21,8 @@ <option name="cleanup" value="true" /> <option name="push-file" key="SimpleServiceTestApp3.apk" value="/data/local/tmp/cts/content/SimpleServiceTestApp3.apk" /> + <option name="push-file" key="broken_shortcut.xml" + value="/data/local/tmp/cts/content/broken_shortcut.xml" /> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> diff --git a/services/tests/servicestests/data/broken_shortcut.xml b/services/tests/servicestests/data/broken_shortcut.xml Binary files differnew file mode 100644 index 000000000000..f2b083ddc3a0 --- /dev/null +++ b/services/tests/servicestests/data/broken_shortcut.xml diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index 09a84da9406a..2967c5c53e8a 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.companion.virtual; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT; +import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_SENSORS; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.content.Context.DEVICE_ID_INVALID; @@ -117,6 +118,7 @@ import com.android.server.sensors.SensorManagerInternal; import com.google.android.collect.Sets; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -372,6 +374,11 @@ public class VirtualDeviceManagerServiceTest { mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1); } + @After + public void tearDown() { + mDeviceImpl.close(); + } + @Test public void getDeviceIdForDisplayId_invalidDisplayId_returnsDefault() { assertThat(mVdm.getDeviceIdForDisplayId(Display.INVALID_DISPLAY)) @@ -444,6 +451,7 @@ public class VirtualDeviceManagerServiceTest { .setBlockedActivities(getBlockedActivities()) .setDevicePolicy(POLICY_TYPE_SENSORS, DEVICE_POLICY_CUSTOM) .build(); + mDeviceImpl.close(); mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params); assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS)) @@ -451,6 +459,35 @@ public class VirtualDeviceManagerServiceTest { } @Test + public void getDevicePolicy_defaultRecentsPolicy_gwpcCanShowRecentsOnHostDevice() { + VirtualDeviceParams params = new VirtualDeviceParams + .Builder() + .build(); + mDeviceImpl.close(); + mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params); + addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); + + GenericWindowPolicyController gwpc = + mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1); + assertThat(gwpc.canShowTasksInHostDeviceRecents()).isTrue(); + } + + @Test + public void getDevicePolicy_customRecentsPolicy_gwpcCannotShowRecentsOnHostDevice() { + VirtualDeviceParams params = new VirtualDeviceParams + .Builder() + .setDevicePolicy(POLICY_TYPE_RECENTS, DEVICE_POLICY_CUSTOM) + .build(); + mDeviceImpl.close(); + mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params); + addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); + + GenericWindowPolicyController gwpc = + mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1); + assertThat(gwpc.canShowTasksInHostDeviceRecents()).isFalse(); + } + + @Test public void getDeviceOwnerUid_oneDevice_returnsCorrectId() { int ownerUid = mLocalService.getDeviceOwnerUid(mDeviceImpl.getDeviceId()); assertThat(ownerUid).isEqualTo(mDeviceImpl.getOwnerUid()); @@ -501,6 +538,7 @@ public class VirtualDeviceManagerServiceTest { doReturn(SENSOR_HANDLE).when(mSensorManagerInternalMock).createRuntimeSensor( anyInt(), anyInt(), anyString(), anyString(), anyInt(), any()); + mDeviceImpl.close(); mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params); VirtualSensor sensor = mLocalService.getVirtualSensor(VIRTUAL_DEVICE_ID_1, SENSOR_HANDLE); diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java index 7b5af1e0fe98..d9e4da73c1c3 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java @@ -90,8 +90,7 @@ public class VirtualAudioControllerTest { /* secureWindowCallback= */ null, /* intentListenerCallback= */ null, /* displayCategories= */ new ArrayList<>(), - /* recentsPolicy= */ - VirtualDeviceParams.RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS); + /* showTasksInHostDeviceRecents= */ true); } diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index 861087a5ab54..e65f8cf2a199 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -4007,6 +4007,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // TODO Check all other fields } + public void testLoadCorruptedShortcuts() throws Exception { + initService(); + + addPackage("com.android.chrome", 0, 0); + + ShortcutUser user = new ShortcutUser(mService, 0); + + File corruptedShortcutPackage = new File("/data/local/tmp/cts/content/", + "broken_shortcut.xml"); + assertNull(ShortcutPackage.loadFromFile(mService, user, corruptedShortcutPackage, false)); + } + public void testSaveCorruptAndLoadUser() throws Exception { // First, create some shortcuts and save. runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java index 97538c1c833f..50f2ad4561cc 100644 --- a/telecomm/java/android/telecom/CallControl.java +++ b/telecomm/java/android/telecom/CallControl.java @@ -294,18 +294,21 @@ public final class CallControl { /** * Raises an event to the {@link android.telecom.InCallService} implementations tracking this * call via {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)}. - * These events and the associated extra keys for the {@code Bundle} parameter are defined - * in Android X. This API is used to relay additional information about a call other than - * what is specified in the {@link android.telecom.CallAttributes} to - * {@link android.telecom.InCallService}s. This might include, for example, a change to the list - * of participants in a meeting, or the name of the speakers who have their hand raised. Where - * appropriate, the {@link InCallService}s tracking this call may choose to render this - * additional information about the call. An automotive calling UX, for example may have enough - * screen real estate to indicate the number of participants in a meeting, but to prevent - * distractions could suppress the list of participants. + * These events and the associated extra keys for the {@code Bundle} parameter are mutually + * defined by a VoIP application and {@link android.telecom.InCallService}. This API is used to + * relay additional information about a call other than what is specified in the + * {@link android.telecom.CallAttributes} to {@link android.telecom.InCallService}s. This might + * include, for example, a change to the list of participants in a meeting, or the name of the + * speakers who have their hand raised. Where appropriate, the {@link InCallService}s tracking + * this call may choose to render this additional information about the call. An automotive + * calling UX, for example may have enough screen real estate to indicate the number of + * participants in a meeting, but to prevent distractions could suppress the list of + * participants. * - * @param event that is defined in AndroidX (ex. The number of participants changed) - * @param extras the updated value in relation to the event (ex. 4 participants) + * @param event a string event identifier agreed upon between a VoIP application and an + * {@link android.telecom.InCallService} + * @param extras a {@link android.os.Bundle} containing information about the event, as agreed + * upon between a VoIP application and {@link android.telecom.InCallService}. */ public void sendEvent(@NonNull String event, @NonNull Bundle extras) { Objects.requireNonNull(event); diff --git a/telecomm/java/android/telecom/CallEventCallback.java b/telecomm/java/android/telecom/CallEventCallback.java index d96c406c4294..a41c0113e933 100644 --- a/telecomm/java/android/telecom/CallEventCallback.java +++ b/telecomm/java/android/telecom/CallEventCallback.java @@ -60,14 +60,17 @@ public interface CallEventCallback { /** * Informs this {@link android.telecom.CallEventCallback} on events raised from a - * {@link android.telecom.InCallService} presenting this call. The event key and extra values - * are defined in AndroidX. This enables alternative calling surfaces, such as an automotive - * UI, to relay requests to perform other non-standard call actions to the app. For example, - * an automotive calling solution may offer the ability for the user to raise their hand - * during a meeting. + * {@link android.telecom.InCallService} presenting this call. These events and the + * associated extra keys for the {@code Bundle} parameter are mutually defined by a VoIP + * application and {@link android.telecom.InCallService}. This enables alternative calling + * surfaces, such as an automotive UI, to relay requests to perform other non-standard call + * actions to the app. For example, an automotive calling solution may offer the ability for + * the user to raise their hand during a meeting. * - * @param event that is defined in AndroidX (ex. the number of participants changed) - * @param extras the updated value in relation to the event (ex. 4 participants) + * @param event a string event identifier agreed upon between a VoIP application and an + * {@link android.telecom.InCallService} + * @param extras a {@link android.os.Bundle} containing information about the event, as agreed + * upon between a VoIP application and {@link android.telecom.InCallService}. */ void onEvent(@NonNull String event, @NonNull Bundle extras); } diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java index 1b35b626c302..ed4d699ad4de 100644 --- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java +++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java @@ -80,9 +80,11 @@ public final class NetworkProviderInfo implements Parcelable { DEVICE_TYPE_WATCH, DEVICE_TYPE_AUTO }) - public @interface DeviceType {} + public @interface DeviceType { + } - @DeviceType private final int mDeviceType; + @DeviceType + private final int mDeviceType; private final String mDeviceName; private final String mModelName; private final int mBatteryPercentage; @@ -98,7 +100,12 @@ public final class NetworkProviderInfo implements Parcelable { private int mBatteryPercentage; private int mConnectionStrength; - public Builder() {} + public Builder(@NonNull String deviceName, @NonNull String modelName) { + Objects.requireNonNull(deviceName); + Objects.requireNonNull(modelName); + mDeviceName = deviceName; + mModelName = modelName; + } /** * Sets the device type that provides connectivity. @@ -120,6 +127,7 @@ public final class NetworkProviderInfo implements Parcelable { */ @NonNull public Builder setDeviceName(@NonNull String deviceName) { + Objects.requireNonNull(deviceName); mDeviceName = deviceName; return this; } @@ -132,6 +140,7 @@ public final class NetworkProviderInfo implements Parcelable { */ @NonNull public Builder setModelName(@NonNull String modelName) { + Objects.requireNonNull(modelName); mModelName = modelName; return this; } @@ -176,15 +185,9 @@ public final class NetworkProviderInfo implements Parcelable { int batteryPercentage, int connectionStrength) { if (deviceType != DEVICE_TYPE_UNKNOWN && deviceType != DEVICE_TYPE_PHONE && deviceType != DEVICE_TYPE_TABLET && deviceType != DEVICE_TYPE_LAPTOP - && deviceType != DEVICE_TYPE_WATCH && deviceType != DEVICE_TYPE_AUTO) { + && deviceType != DEVICE_TYPE_WATCH && deviceType != DEVICE_TYPE_AUTO) { throw new IllegalArgumentException("Illegal device type"); } - if (Objects.isNull(deviceName)) { - throw new IllegalArgumentException("DeviceName must be set"); - } - if (Objects.isNull(modelName)) { - throw new IllegalArgumentException("ModelName must be set"); - } if (batteryPercentage < 0 || batteryPercentage > 100) { throw new IllegalArgumentException("BatteryPercentage must be in range 0-100"); } @@ -269,6 +272,7 @@ public final class NetworkProviderInfo implements Parcelable { return Objects.hash(mDeviceType, mDeviceName, mModelName, mBatteryPercentage, mConnectionStrength); } + @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mDeviceType); diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java index 1f76b484e6ae..b18ab5060924 100644 --- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java +++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java @@ -41,9 +41,9 @@ import java.util.Arrays; public class HotspotNetworkConnectionStatusTest { private static final long DEVICE_ID = 11L; private static final NetworkProviderInfo NETWORK_PROVIDER_INFO = - new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_TABLET) - .setDeviceName("TEST_NAME").setModelName("TEST_MODEL") - .setConnectionStrength(2).setBatteryPercentage(50).build(); + new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL") + .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2) + .setBatteryPercentage(50).build(); private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR; private static final String NETWORK_NAME = "TEST_NETWORK"; private static final String HOTSPOT_SSID = "TEST_SSID"; diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java index b76927095cf9..8e396b68ad3a 100644 --- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java +++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java @@ -42,9 +42,9 @@ import java.util.Arrays; public class HotspotNetworkTest { private static final long DEVICE_ID = 11L; private static final NetworkProviderInfo NETWORK_PROVIDER_INFO = - new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_TABLET) - .setDeviceName("TEST_NAME").setModelName("TEST_MODEL") - .setConnectionStrength(2).setBatteryPercentage(50).build(); + new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL") + .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2) + .setBatteryPercentage(50).build(); private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR; private static final String NETWORK_NAME = "TEST_NETWORK"; private static final String HOTSPOT_SSID = "TEST_SSID"; @@ -53,9 +53,9 @@ public class HotspotNetworkTest { private static final long DEVICE_ID_1 = 111L; private static final NetworkProviderInfo NETWORK_PROVIDER_INFO1 = - new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_PHONE) - .setDeviceName("TEST_NAME").setModelName("TEST_MODEL") - .setConnectionStrength(2).setBatteryPercentage(50).build(); + new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL") + .setDeviceType(DEVICE_TYPE_PHONE).setConnectionStrength(2) + .setBatteryPercentage(50).build(); private static final int NETWORK_TYPE_1 = NETWORK_TYPE_WIFI; private static final String NETWORK_NAME_1 = "TEST_NETWORK1"; private static final String HOTSPOT_SSID_1 = "TEST_SSID1"; diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java index 2a6046fd6944..f98a0fcc7574 100644 --- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java +++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java @@ -42,10 +42,9 @@ public class KnownNetworkConnectionStatusTest { private static final String SSID = "TEST_SSID"; private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP}; private static final NetworkProviderInfo NETWORK_PROVIDER_INFO = - new NetworkProviderInfo.Builder() - .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName( - "TEST_MODEL") - .setConnectionStrength(2).setBatteryPercentage(50).build(); + new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL") + .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2) + .setBatteryPercentage(50).build(); private static final String SSID_1 = "TEST_SSID1"; private static final String BUNDLE_KEY = "INT-KEY"; private static final int BUNDLE_VALUE = 1; diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java index 1b9a7ebd7856..1ecba7644cf9 100644 --- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java +++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java @@ -44,16 +44,16 @@ public class KnownNetworkTest { private static final String SSID = "TEST_SSID"; private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP}; private static final NetworkProviderInfo NETWORK_PROVIDER_INFO = - new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_TABLET) - .setDeviceName("TEST_NAME").setModelName("TEST_MODEL").setConnectionStrength(2) + new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL") + .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2) .setBatteryPercentage(50).build(); private static final int NETWORK_SOURCE_1 = NETWORK_SOURCE_CLOUD_SELF; private static final String SSID_1 = "TEST_SSID1"; private static final int[] SECURITY_TYPES_1 = {SECURITY_TYPE_PSK}; private static final NetworkProviderInfo NETWORK_PROVIDER_INFO1 = - new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_PHONE) - .setDeviceName("TEST_NAME_1").setModelName("TEST_MODEL_1") - .setConnectionStrength(3).setBatteryPercentage(33).build(); + new NetworkProviderInfo.Builder("TEST_NAME_1", "TEST_MODEL_1") + .setDeviceType(DEVICE_TYPE_PHONE).setConnectionStrength(3) + .setBatteryPercentage(33).build(); /** * Verifies parcel serialization/deserialization. diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java index 5de65442b9be..8f35d8d94a8b 100644 --- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java +++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java @@ -116,8 +116,7 @@ public class NetworkProviderInfoTest { } private NetworkProviderInfo.Builder buildNetworkProviderInfoBuilder() { - return new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE) - .setDeviceName(DEVICE_NAME).setModelName(DEVICE_MODEL) + return new NetworkProviderInfo.Builder(DEVICE_NAME, DEVICE_MODEL).setDeviceType(DEVICE_TYPE) .setBatteryPercentage(BATTERY_PERCENTAGE) .setConnectionStrength(CONNECTION_STRENGTH); } diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java index 9fc352cf133f..8c573e302213 100644 --- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java +++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java @@ -57,10 +57,9 @@ import java.util.concurrent.Executor; public class SharedConnectivityManagerTest { private static final long DEVICE_ID = 11L; private static final NetworkProviderInfo NETWORK_PROVIDER_INFO = - new NetworkProviderInfo.Builder() - .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName( - "TEST_MODEL") - .setConnectionStrength(2).setBatteryPercentage(50).build(); + new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL") + .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2) + .setBatteryPercentage(50).build(); private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR; private static final String NETWORK_NAME = "TEST_NETWORK"; private static final String HOTSPOT_SSID = "TEST_SSID"; diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java index cf437b7ea4fe..19effe5d6f14 100644 --- a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java +++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java @@ -56,10 +56,9 @@ import java.util.List; @SmallTest public class SharedConnectivityServiceTest { private static final NetworkProviderInfo NETWORK_PROVIDER_INFO = - new NetworkProviderInfo.Builder() - .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName( - "TEST_MODEL") - .setConnectionStrength(2).setBatteryPercentage(50).build(); + new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL") + .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2) + .setBatteryPercentage(50).build(); private static final HotspotNetwork HOTSPOT_NETWORK = new HotspotNetwork.Builder().setDeviceId(1).setNetworkProviderInfo( NETWORK_PROVIDER_INFO) |