Skip to content

Commit

Permalink
Fix edge-to-edge enforcement check in ShadowCompatibility
Browse files Browse the repository at this point in the history
Apps that target Android V and above will be required to support edge-to-edge
content, where apps will be responsible for drawing content under the status
and navigation bars:
https://developer.android.com/about/versions/15/behavior-changes-15#edge-to-edge

In framework code, this is primarily detected using
CompatChanges.isChangeEnabled(ENFORCE_EDGE_TO_EDGE). However, this previously
always returned true because CompatChanges.isChangeEnabled returns true by
default in Robolectric.

In real Android, CompatChanges.isChangeEnabled(ENFORCE_EDGE_TO_EDGE) only
returns true when the target SDK is V or above.

PiperOrigin-RevId: 629401576
  • Loading branch information
hoisie authored and Copybara-Service committed Apr 30, 2024
1 parent 2e55d38 commit da5e70d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.robolectric.annotation.Config;
import org.robolectric.annotation.experimental.LazyApplication;
import org.robolectric.annotation.experimental.LazyApplication.LazyLoad;
import org.robolectric.versioning.AndroidVersions.U;
import org.robolectric.versioning.AndroidVersions.V;

/** Tests to make sure {@link android.compat.Compatibility} is instrumented correctly */
@RunWith(RobolectricTestRunner.class)
Expand All @@ -33,4 +35,10 @@ public void isChangeEnabled_logging() {
// verify there are no CompatibilityChangeReporter spam logs
assertThat(ShadowLog.getLogsForTag("CompatibilityChangeReporter")).isEmpty();
}

@Test
public void edgeToEdgeEncorcement_minSdk() {
assertThat(ShadowCompatibility.isEdgeToEdgeEnabled(U.SDK_INT)).isFalse();
assertThat(ShadowCompatibility.isEdgeToEdgeEnabled(V.SDK_INT)).isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,44 @@
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.os.Build.VERSION_CODES;
import com.google.common.annotations.VisibleForTesting;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.util.reflector.Direct;
import org.robolectric.util.reflector.ForType;
import org.robolectric.util.reflector.Static;
import org.robolectric.versioning.AndroidVersions.U;

/**
* Robolectric shadow to disable CALL_ACTIVITY_RESULT_BEFORE_RESUME using Compatibility's
* isChangeEnabled.
*/
/** Shadow for {@link Compatability}. */
@Implements(value = Compatibility.class, isInAndroidSdk = false)
public class ShadowCompatibility {

private static final long CALL_ACTIVITY_RESULT_BEFORE_RESUME = 78294732L;

private static final long ENFORCE_EDGE_TO_EDGE = 309578419L;

@RealObject protected static Compatibility realCompatibility;

@Implementation(minSdk = VERSION_CODES.S_V2)
protected static boolean isChangeEnabled(@ChangeId long changeId) {
if (changeId == CALL_ACTIVITY_RESULT_BEFORE_RESUME) {
return false;
} else if (changeId == ENFORCE_EDGE_TO_EDGE) {
int targetSdkVersion =
RuntimeEnvironment.getApplication().getApplicationInfo().targetSdkVersion;
return isEdgeToEdgeEnabled(targetSdkVersion);
}
return reflector(CompatibilityReflector.class).isChangeEnabled(changeId);
}

@VisibleForTesting
static boolean isEdgeToEdgeEnabled(int targetSdkVersion) {
// Edge-to-edge is enforced for apps that target Android V and above.
return targetSdkVersion > U.SDK_INT;
}

/** Reflector interface for {@link Compatibility}'s isChangeEnabled function. */
@ForType(Compatibility.class)
private interface CompatibilityReflector {
Expand Down

0 comments on commit da5e70d

Please sign in to comment.