Merge "Add flag to guard WM Extensions for all devices" into main
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c127a43..1e3e81f 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -93,8 +93,12 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.app.ActivityTaskManager;
+import android.app.ActivityThread;
import android.app.KeyguardManager;
import android.app.Presentation;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ClipData;
import android.content.ComponentName;
@@ -1416,23 +1420,71 @@
public static final String PARCEL_KEY_SHORTCUTS_ARRAY = "shortcuts_array";
/**
- * Whether the device supports the WindowManager Extensions.
- * OEMs can enable this by having their device config to inherit window_extensions.mk, such as:
+ * Whether the WindowManager Extensions - Activity Embedding feature should be guarded by
+ * the app's target SDK on Android 15.
+ *
+ * WindowManager Extensions are only required for foldable and large screen before Android 15,
+ * so we want to guard the Activity Embedding feature since it can have app compat impact on
+ * devices with a compact size display.
+ *
+ * <p>If {@code true}, the feature is only enabled if the app's target SDK is Android 15 or
+ * above.
+ *
+ * <p>If {@code false}, the feature is enabled for all apps.
+ *
+ * <p>The default value is {@code true}. OEMs can set to {@code false} by having their device
+ * config to inherit window_extensions.mk. This is also required for large screen devices.
* <pre>
* $(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)
* </pre>
+ *
* @hide
*/
- boolean WINDOW_EXTENSIONS_ENABLED =
+ boolean ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15 = SystemProperties.getBoolean(
+ "persist.wm.extensions.activity_embedding_guard_with_android_15", true);
+
+ /**
+ * For devices with {@link #ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15} as {@code true},
+ * the Activity Embedding feature is enabled if the app's target SDK is Android 15+.
+ *
+ * @see #ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ long ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15 = 306666082L;
+
+ /**
+ * Whether the device contains the WindowManager Extensions shared library.
+ * This is enabled for all devices through window_extensions_base.mk, but can be dropped if the
+ * device doesn't support multi window.
+ *
+ * <p>Note: Large screen devices must also inherit window_extensions.mk to enable the Activity
+ * Embedding feature by default for all apps.
+ *
+ * @see #ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15
+ * @hide
+ */
+ boolean HAS_WINDOW_EXTENSIONS_ON_DEVICE =
SystemProperties.getBoolean("persist.wm.extensions.enabled", false);
/**
- * @see #WINDOW_EXTENSIONS_ENABLED
+ * Whether the WindowManager Extensions are enabled.
+ * If {@code false}, the WM Jetpack will report most of its features as disabled.
+ * @see #HAS_WINDOW_EXTENSIONS_ON_DEVICE
* @hide
*/
@TestApi
static boolean hasWindowExtensionsEnabled() {
- return WINDOW_EXTENSIONS_ENABLED;
+ return HAS_WINDOW_EXTENSIONS_ON_DEVICE
+ && ActivityTaskManager.supportsMultiWindow(ActivityThread.currentApplication())
+ // Since enableWmExtensionsForAllFlag, HAS_WINDOW_EXTENSIONS_ON_DEVICE is now true
+ // on all devices by default as a build file property.
+ // Until finishing flag ramp up, only return true when
+ // ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15 is false, which is set per device by
+ // OEMs.
+ && (Flags.enableWmExtensionsForAllFlag()
+ || !ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15);
}
/**
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 7af1965..5297006 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -400,7 +400,7 @@
// WindowManager Extensions is an optional shared library that is required for WindowManager
// Jetpack to fully function. Since it is a widely used library, preload it to improve apps
// startup performance.
- if (WindowManager.hasWindowExtensionsEnabled()) {
+ if (WindowManager.HAS_WINDOW_EXTENSIONS_ON_DEVICE) {
final String systemExtFrameworkPath =
new File(Environment.getSystemExtDirectory(), "framework").getPath();
libs.add(new SharedLibraryInfo(
diff --git a/core/tests/coretests/src/android/view/WindowManagerTests.java b/core/tests/coretests/src/android/view/WindowManagerTests.java
new file mode 100644
index 0000000..c5a9d48
--- /dev/null
+++ b/core/tests/coretests/src/android/view/WindowManagerTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static com.android.window.flags.Flags.FLAG_ENABLE_WM_EXTENSIONS_FOR_ALL_FLAG;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link WindowManager}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:WindowManagerTests
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class WindowManagerTests {
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ @Test
+ public void testHasWindowExtensionsEnabled_flagDisabled() {
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_WM_EXTENSIONS_FOR_ALL_FLAG);
+
+ // Before FLAG_ENABLE_WM_EXTENSIONS_FOR_ALL_FLAG, Extensions are always bundled with AE.
+ assertEquals(isActivityEmbeddingEnableForAll(),
+ WindowManager.hasWindowExtensionsEnabled());
+ }
+
+ @Test
+ public void testHasWindowExtensionsEnabled_flagEnabled() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_WM_EXTENSIONS_FOR_ALL_FLAG);
+
+ // Extensions should be enabled on all devices.
+ assertTrue(WindowManager.hasWindowExtensionsEnabled());
+ }
+
+ @Test
+ public void testActivityEmbeddingAvailability() {
+ assumeTrue(isActivityEmbeddingEnableForAll());
+
+ // AE can only be enabled when extensions is enabled.
+ assertTrue(WindowManager.hasWindowExtensionsEnabled());
+ }
+
+ private static boolean isActivityEmbeddingEnableForAll() {
+ return !WindowManager.ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15;
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index 6714263..9756278 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
@@ -16,15 +16,19 @@
package androidx.window.extensions;
-import android.app.ActivityTaskManager;
+import static android.view.WindowManager.ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15;
+import static android.view.WindowManager.ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15;
+
import android.app.ActivityThread;
import android.app.Application;
+import android.app.compat.CompatChanges;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.RawFoldingFeatureProducer;
import androidx.window.extensions.area.WindowAreaComponent;
@@ -38,25 +42,38 @@
/**
- * The reference implementation of {@link WindowExtensions} that implements the initial API version.
+ * The reference implementation of {@link WindowExtensions} that implements the latest WindowManager
+ * Extensions APIs.
*/
-public class WindowExtensionsImpl implements WindowExtensions {
+class WindowExtensionsImpl implements WindowExtensions {
private static final String TAG = "WindowExtensionsImpl";
+
+ /**
+ * The min version of the WM Extensions that must be supported in the current platform version.
+ */
+ @VisibleForTesting
+ static final int EXTENSIONS_VERSION_CURRENT_PLATFORM = 5;
+
private final Object mLock = new Object();
private volatile DeviceStateManagerFoldingFeatureProducer mFoldingFeatureProducer;
private volatile WindowLayoutComponentImpl mWindowLayoutComponent;
private volatile SplitController mSplitController;
private volatile WindowAreaComponent mWindowAreaComponent;
- public WindowExtensionsImpl() {
- Log.i(TAG, "Initializing Window Extensions.");
+ private final int mVersion = EXTENSIONS_VERSION_CURRENT_PLATFORM;
+ private final boolean mIsActivityEmbeddingEnabled;
+
+ WindowExtensionsImpl() {
+ mIsActivityEmbeddingEnabled = isActivityEmbeddingEnabled();
+ Log.i(TAG, "Initializing Window Extensions, vendor API level=" + mVersion
+ + ", activity embedding enabled=" + mIsActivityEmbeddingEnabled);
}
// TODO(b/241126279) Introduce constants to better version functionality
@Override
public int getVendorApiLevel() {
- return 5;
+ return mVersion;
}
@NonNull
@@ -74,8 +91,8 @@
if (mFoldingFeatureProducer == null) {
synchronized (mLock) {
if (mFoldingFeatureProducer == null) {
- Context context = getApplication();
- RawFoldingFeatureProducer foldingFeatureProducer =
+ final Context context = getApplication();
+ final RawFoldingFeatureProducer foldingFeatureProducer =
new RawFoldingFeatureProducer(context);
mFoldingFeatureProducer =
new DeviceStateManagerFoldingFeatureProducer(context,
@@ -91,8 +108,8 @@
if (mWindowLayoutComponent == null) {
synchronized (mLock) {
if (mWindowLayoutComponent == null) {
- Context context = getApplication();
- DeviceStateManagerFoldingFeatureProducer producer =
+ final Context context = getApplication();
+ final DeviceStateManagerFoldingFeatureProducer producer =
getFoldingFeatureProducer();
mWindowLayoutComponent = new WindowLayoutComponentImpl(context, producer);
}
@@ -102,29 +119,35 @@
}
/**
- * Returns a reference implementation of {@link WindowLayoutComponent} if available,
- * {@code null} otherwise. The implementation must match the API level reported in
- * {@link WindowExtensions#getWindowLayoutComponent()}.
+ * Returns a reference implementation of the latest {@link WindowLayoutComponent}.
+ *
+ * The implementation must match the API level reported in
+ * {@link WindowExtensions#getVendorApiLevel()}.
+ *
* @return {@link WindowLayoutComponent} OEM implementation
*/
+ @NonNull
@Override
public WindowLayoutComponent getWindowLayoutComponent() {
return getWindowLayoutComponentImpl();
}
/**
- * Returns a reference implementation of {@link ActivityEmbeddingComponent} if available,
- * {@code null} otherwise. The implementation must match the API level reported in
- * {@link WindowExtensions#getWindowLayoutComponent()}.
+ * Returns a reference implementation of the latest {@link ActivityEmbeddingComponent} if the
+ * device supports this feature, {@code null} otherwise.
+ *
+ * The implementation must match the API level reported in
+ * {@link WindowExtensions#getVendorApiLevel()}.
+ *
* @return {@link ActivityEmbeddingComponent} OEM implementation.
*/
@Nullable
+ @Override
public ActivityEmbeddingComponent getActivityEmbeddingComponent() {
+ if (!mIsActivityEmbeddingEnabled) {
+ return null;
+ }
if (mSplitController == null) {
- if (!ActivityTaskManager.supportsMultiWindow(getApplication())) {
- // Disable AE for device that doesn't support multi window.
- return null;
- }
synchronized (mLock) {
if (mSplitController == null) {
mSplitController = new SplitController(
@@ -138,21 +161,35 @@
}
/**
- * Returns a reference implementation of {@link WindowAreaComponent} if available,
- * {@code null} otherwise. The implementation must match the API level reported in
- * {@link WindowExtensions#getWindowAreaComponent()}.
+ * Returns a reference implementation of the latest {@link WindowAreaComponent}
+ *
+ * The implementation must match the API level reported in
+ * {@link WindowExtensions#getVendorApiLevel()}.
+ *
* @return {@link WindowAreaComponent} OEM implementation.
*/
+ @Nullable
+ @Override
public WindowAreaComponent getWindowAreaComponent() {
if (mWindowAreaComponent == null) {
synchronized (mLock) {
if (mWindowAreaComponent == null) {
- Context context = ActivityThread.currentApplication();
- mWindowAreaComponent =
- new WindowAreaComponentImpl(context);
+ final Context context = getApplication();
+ mWindowAreaComponent = new WindowAreaComponentImpl(context);
}
}
}
return mWindowAreaComponent;
}
+
+ @VisibleForTesting
+ static boolean isActivityEmbeddingEnabled() {
+ if (!ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15) {
+ // Device enables it for all apps without targetSDK check.
+ // This must be true for all large screen devices.
+ return true;
+ }
+ // Use compat framework to guard the feature with targetSDK 15.
+ return CompatChanges.isChangeEnabled(ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15);
+ }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsProvider.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsProvider.java
index f9e1f07..b0a0c4d 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsProvider.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsProvider.java
@@ -17,13 +17,19 @@
package androidx.window.extensions;
import android.annotation.NonNull;
+import android.view.WindowManager;
+
+import androidx.annotation.Nullable;
+import androidx.window.extensions.area.WindowAreaComponent;
+import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
+import androidx.window.extensions.layout.WindowLayoutComponent;
/**
* Provides the OEM implementation of {@link WindowExtensions}.
*/
public class WindowExtensionsProvider {
- private static final WindowExtensions sWindowExtensions = new WindowExtensionsImpl();
+ private static volatile WindowExtensions sWindowExtensions;
/**
* Returns the OEM implementation of {@link WindowExtensions}. This method is implemented in
@@ -33,6 +39,44 @@
*/
@NonNull
public static WindowExtensions getWindowExtensions() {
+ if (sWindowExtensions == null) {
+ synchronized (WindowExtensionsProvider.class) {
+ if (sWindowExtensions == null) {
+ sWindowExtensions = WindowManager.hasWindowExtensionsEnabled()
+ ? new WindowExtensionsImpl()
+ : new DisabledWindowExtensions();
+ }
+ }
+ }
return sWindowExtensions;
}
+
+ /**
+ * The stub version to return when the WindowManager Extensions is disabled
+ * @see WindowManager#hasWindowExtensionsEnabled
+ */
+ private static class DisabledWindowExtensions implements WindowExtensions {
+ @Override
+ public int getVendorApiLevel() {
+ return 0;
+ }
+
+ @Nullable
+ @Override
+ public WindowLayoutComponent getWindowLayoutComponent() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public ActivityEmbeddingComponent getActivityEmbeddingComponent() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public WindowAreaComponent getWindowAreaComponent() {
+ return null;
+ }
+ }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 1abda42..0cc4b1f 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -88,7 +88,7 @@
import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
-import androidx.window.extensions.WindowExtensionsImpl;
+import androidx.window.extensions.WindowExtensions;
import androidx.window.extensions.core.util.function.Consumer;
import androidx.window.extensions.core.util.function.Function;
import androidx.window.extensions.core.util.function.Predicate;
@@ -410,7 +410,7 @@
* Registers the split organizer callback to notify about changes to active splits.
*
* @deprecated Use {@link #setSplitInfoCallback(Consumer)} starting with
- * {@link WindowExtensionsImpl#getVendorApiLevel()} 2.
+ * {@link WindowExtensions#getVendorApiLevel()} 2.
*/
@Deprecated
@Override
@@ -423,7 +423,7 @@
/**
* Registers the split organizer callback to notify about changes to active splits.
*
- * @since {@link WindowExtensionsImpl#getVendorApiLevel()} 2
+ * @since {@link WindowExtensions#getVendorApiLevel()} 2
*/
@Override
public void setSplitInfoCallback(Consumer<List<SplitInfo>> callback) {
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
index f471af0..4267749 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -16,12 +16,15 @@
package androidx.window.extensions;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static androidx.window.extensions.WindowExtensionsImpl.EXTENSIONS_VERSION_CURRENT_PLATFORM;
import static com.google.common.truth.Truth.assertThat;
-import android.app.ActivityTaskManager;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
import android.platform.test.annotations.Presubmit;
+import android.view.WindowManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -42,25 +45,61 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class WindowExtensionsTest {
+
private WindowExtensions mExtensions;
+ private int mVersion;
@Before
public void setUp() {
mExtensions = WindowExtensionsProvider.getWindowExtensions();
+ mVersion = mExtensions.getVendorApiLevel();
}
@Test
- public void testGetWindowLayoutComponent() {
+ public void testGetVendorApiLevel_extensionsEnabled_matchesCurrentVersion() {
+ assumeTrue(WindowManager.hasWindowExtensionsEnabled());
+ assertThat(mVersion).isEqualTo(EXTENSIONS_VERSION_CURRENT_PLATFORM);
+ }
+
+ @Test
+ public void testGetVendorApiLevel_extensionsDisabled_returnsZero() {
+ assumeFalse(WindowManager.hasWindowExtensionsEnabled());
+ assertThat(mVersion).isEqualTo(0);
+ }
+
+ @Test
+ public void testGetWindowLayoutComponent_extensionsEnabled_returnsImplementation() {
+ assumeTrue(WindowManager.hasWindowExtensionsEnabled());
assertThat(mExtensions.getWindowLayoutComponent()).isNotNull();
}
@Test
- public void testGetActivityEmbeddingComponent() {
- if (ActivityTaskManager.supportsMultiWindow(getInstrumentation().getContext())) {
- assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull();
- } else {
- assertThat(mExtensions.getActivityEmbeddingComponent()).isNull();
- }
+ public void testGetWindowLayoutComponent_extensionsDisabled_returnsNull() {
+ assumeFalse(WindowManager.hasWindowExtensionsEnabled());
+ assertThat(mExtensions.getWindowLayoutComponent()).isNull();
+ }
+ @Test
+ public void testGetActivityEmbeddingComponent_featureDisabled_returnsNull() {
+ assumeFalse(WindowExtensionsImpl.isActivityEmbeddingEnabled());
+ assertThat(mExtensions.getActivityEmbeddingComponent()).isNull();
+ }
+
+ @Test
+ public void testGetActivityEmbeddingComponent_featureEnabled_returnsImplementation() {
+ assumeTrue(WindowExtensionsImpl.isActivityEmbeddingEnabled());
+ assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull();
+ }
+
+ @Test
+ public void testGetWindowAreaComponent_extensionsEnabled_returnsImplementation() {
+ assumeTrue(WindowManager.hasWindowExtensionsEnabled());
+ assertThat(mExtensions.getWindowAreaComponent()).isNotNull();
+ }
+
+ @Test
+ public void testGetWindowAreaComponent_extensionsDisabled_returnsNull() {
+ assumeFalse(WindowManager.hasWindowExtensionsEnabled());
+ assertThat(mExtensions.getWindowAreaComponent()).isNull();
}
@Test
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6fa6957..23f9743 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -118,6 +118,7 @@
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
+import static android.view.WindowManager.ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -125,10 +126,12 @@
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED;
import static android.view.WindowManager.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING;
+import static android.view.WindowManager.ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
+import static android.view.WindowManager.hasWindowExtensionsEnabled;
import static android.window.TransitionInfo.FLAGS_IS_OCCLUDED_NO_ANIMATION;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
@@ -282,6 +285,7 @@
import android.app.WindowConfiguration;
import android.app.admin.DevicePolicyManager;
import android.app.assist.ActivityId;
+import android.app.compat.CompatChanges;
import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ActivityLifecycleItem;
import android.app.servertransaction.ActivityRelaunchItem;
@@ -2266,16 +2270,7 @@
mActivityRecordInputSink = new ActivityRecordInputSink(this, sourceRecord);
- boolean appActivityEmbeddingEnabled = false;
- try {
- appActivityEmbeddingEnabled = WindowManager.hasWindowExtensionsEnabled()
- && mAtmService.mContext.getPackageManager()
- .getProperty(PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED, packageName)
- .getBoolean();
- } catch (PackageManager.NameNotFoundException e) {
- // No such property name.
- }
- mAppActivityEmbeddingSplitsEnabled = appActivityEmbeddingEnabled;
+ mAppActivityEmbeddingSplitsEnabled = isAppActivityEmbeddingSplitsEnabled();
mAllowUntrustedEmbeddingStateSharing = getAllowUntrustedEmbeddingStateSharingProperty();
mOptInOnBackInvoked = WindowOnBackInvokedDispatcher
@@ -2294,6 +2289,28 @@
mCallerState = new ActivityCallerState(mAtmService);
}
+ private boolean isAppActivityEmbeddingSplitsEnabled() {
+ if (!hasWindowExtensionsEnabled()) {
+ // WM Extensions disabled.
+ return false;
+ }
+ if (ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15 && !CompatChanges.isChangeEnabled(
+ ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15,
+ info.packageName,
+ UserHandle.getUserHandleForUid(getUid()))) {
+ // Activity Embedding is guarded with Android 15+, but this app is not qualified.
+ return false;
+ }
+ try {
+ return mAtmService.mContext.getPackageManager()
+ .getProperty(PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED, packageName)
+ .getBoolean();
+ } catch (PackageManager.NameNotFoundException e) {
+ // No such property name.
+ return false;
+ }
+ }
+
/**
* Generate the task affinity with uid and activity launch mode. For b/35954083, Limit task
* affinity to uid to avoid issues associated with sharing affinity across uids.