Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
**Bug Fixes**

* Downgrade to kotlin 1.9
* Support launching activities in fullscreen mode with ActivityScenario on XR devices

**New Features**

Expand Down
43 changes: 39 additions & 4 deletions core/java/androidx/test/core/app/ActivityScenario.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import android.app.Instrumentation.ActivityResult;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.Property;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Looper;
Expand Down Expand Up @@ -200,7 +202,7 @@ private ActivityScenario(Class<A> activityClass) {
*/
public static <A extends Activity> ActivityScenario<A> launch(Class<A> activityClass) {
ActivityScenario<A> scenario = new ActivityScenario<>(checkNotNull(activityClass));
scenario.launchInternal(/*activityOptions=*/ null, /*launchActivityForResult=*/ false);
scenario.checkXrAndLaunchInternal(/* activityOptions= */ null);
return scenario;
}

Expand All @@ -213,7 +215,7 @@ public static <A extends Activity> ActivityScenario<A> launch(Class<A> activityC
public static <A extends Activity> ActivityScenario<A> launch(
Class<A> activityClass, @Nullable Bundle activityOptions) {
ActivityScenario<A> scenario = new ActivityScenario<>(checkNotNull(activityClass));
scenario.launchInternal(activityOptions, /*launchActivityForResult=*/ false);
scenario.checkXrAndLaunchInternal(activityOptions);
return scenario;
}

Expand All @@ -234,7 +236,7 @@ public static <A extends Activity> ActivityScenario<A> launch(
*/
public static <A extends Activity> ActivityScenario<A> launch(Intent startActivityIntent) {
ActivityScenario<A> scenario = new ActivityScenario<>(checkNotNull(startActivityIntent));
scenario.launchInternal(/*activityOptions=*/ null, /*launchActivityForResult=*/ false);
scenario.checkXrAndLaunchInternal(/* activityOptions= */ null);
return scenario;
}

Expand All @@ -249,7 +251,7 @@ public static <A extends Activity> ActivityScenario<A> launch(Intent startActivi
public static <A extends Activity> ActivityScenario<A> launch(
Intent startActivityIntent, @Nullable Bundle activityOptions) {
ActivityScenario<A> scenario = new ActivityScenario<>(checkNotNull(startActivityIntent));
scenario.launchInternal(activityOptions, /*launchActivityForResult=*/ false);
scenario.checkXrAndLaunchInternal(activityOptions);
return scenario;
}

Expand Down Expand Up @@ -383,6 +385,39 @@ private void launchInternal(@Nullable Bundle activityOptions, boolean launchActi
}
}

/**
* An internal helper method for handling launching the activity for the given scenario instance
* on XR devices.
*
* @param activityOptions activity options bundle to be passed when launching this activity
*/
private void checkXrAndLaunchInternal(@Nullable Bundle activityOptions) {
// Activities cannot be launched in full screen mode from the application context on XR devices.
// Check if the current device is an XR device and fall back to launching activity for result
// if the android.window.PROPERTY_XR_ACTIVITY_START_MODE property is set to full screen mode
// so that the bootstrap activity can act as a temporary focused activity which the requested
// activity is launched from.
PackageManager packageManager = getInstrumentation().getTargetContext().getPackageManager();
if (packageManager.hasSystemFeature("android.software.xr.immersive")) {
String packageName = getInstrumentation().getTargetContext().getPackageName();
try {
Property startMode =
packageManager.getProperty(
"android.window.PROPERTY_XR_ACTIVITY_START_MODE", packageName);
if (startMode.getString().equals("XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED")
|| startMode.getString().equals("XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED")) {
launchInternal(activityOptions, true);
} else {
launchInternal(activityOptions, false);
}
} catch (PackageManager.NameNotFoundException e) {
launchInternal(activityOptions, false);
}
} else {
launchInternal(activityOptions, false);
}
}

/**
* Finishes the managed activity and cleans up device's state. This method blocks execution until
* the activity becomes {@link State#DESTROYED}.
Expand Down
Loading