diff --git a/apex/jobscheduler/service/Android.bp b/apex/jobscheduler/service/Android.bp index a4a0b4b29200fe394b3a1489c160fde3d00b3ce8..887f7fe3a0e254b3c5b455d3507895050f43cb7c 100644 --- a/apex/jobscheduler/service/Android.bp +++ b/apex/jobscheduler/service/Android.bp @@ -13,6 +13,10 @@ java_library { name: "service-jobscheduler", installable: true, + defaults: [ + "service-jobscheduler-aconfig-libraries", + ], + srcs: [ "java/**/*.java", ":framework-jobscheduler-shared-srcs", diff --git a/apex/jobscheduler/service/aconfig/Android.bp b/apex/jobscheduler/service/aconfig/Android.bp new file mode 100644 index 0000000000000000000000000000000000000000..24ecd3d73814e3cdacdc1799645a02b485bdbf1e --- /dev/null +++ b/apex/jobscheduler/service/aconfig/Android.bp @@ -0,0 +1,29 @@ +// JobScheduler +aconfig_declarations { + name: "service-job.flags-aconfig", + package: "com.android.server.job", + srcs: [ + "job.aconfig", + ], +} + +java_aconfig_library { + name: "service-jobscheduler-job.flags-aconfig-java", + aconfig_declarations: "service-job.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], + visibility: ["//frameworks/base:__subpackages__"], +} + +service_jobscheduler_aconfig_srcjars = [ + ":service-jobscheduler-job.flags-aconfig-java{.generated_srcjars}", +] + +// Aconfig declarations and libraries for the core framework +java_defaults { + name: "service-jobscheduler-aconfig-libraries", + // Add java_aconfig_libraries to here to add them to the core framework + srcs: service_jobscheduler_aconfig_srcjars, + // Add aconfig-annotations-lib as a dependency for the optimization + libs: ["aconfig-annotations-lib"], + visibility: ["//frameworks/base:__subpackages__"], +} diff --git a/apex/jobscheduler/service/aconfig/job.aconfig b/apex/jobscheduler/service/aconfig/job.aconfig new file mode 100644 index 0000000000000000000000000000000000000000..4e3cb7d83451f60d73513245108fcc46ad829705 --- /dev/null +++ b/apex/jobscheduler/service/aconfig/job.aconfig @@ -0,0 +1,8 @@ +package: "com.android.server.job" + +flag { + name: "relax_prefetch_connectivity_constraint_only_on_charger" + namespace: "backstagepower" + description: "Only relax a prefetch job's connectivity constraint when the device is charging" + bug: "299329948" +} \ No newline at end of file diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java index 6d938debde10e1cd8404529a2e97bd9242783d0c..45f15db93a0dedd3709561d6b588574baf25297f 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java @@ -22,6 +22,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_MET import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; +import static com.android.server.job.Flags.FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER; +import static com.android.server.job.Flags.relaxPrefetchConnectivityConstraintOnlyOnCharger; import android.annotation.NonNull; import android.annotation.Nullable; @@ -929,6 +931,11 @@ public final class ConnectivityController extends RestrictingController implemen // Need to at least know the estimated download bytes for a prefetch job. return false; } + if (relaxPrefetchConnectivityConstraintOnlyOnCharger()) { + if (!mService.isBatteryCharging()) { + return false; + } + } // See if we match after relaxing any unmetered request final NetworkCapabilities.Builder builder = @@ -1735,6 +1742,14 @@ public final class ConnectivityController extends RestrictingController implemen Predicate<JobStatus> predicate) { final long nowElapsed = sElapsedRealtimeClock.millis(); + pw.println("Aconfig flags:"); + pw.increaseIndent(); + pw.print(FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER, + relaxPrefetchConnectivityConstraintOnlyOnCharger()); + pw.println(); + pw.decreaseIndent(); + pw.println(); + if (mRequestedWhitelistJobs.size() > 0) { pw.print("Requested standby exceptions:"); for (int i = 0; i < mRequestedWhitelistJobs.size(); i++) { diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index 101498aef183ace458ee9fcba4a7ccce95e6be90..0813bb09fd52ab1f585b52eb9656a4200ded58a2 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -46,6 +46,7 @@ android_test { "androidx.test.espresso.core", "androidx.test.espresso.contrib", "androidx.test.ext.truth", + "flag-junit", "frameworks-base-testutils", "hamcrest-library", "kotlin-test", diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java index 2b56ea8bba33bac3eafc7efb0a98d4b6d8de5df0..bded9b40e591496733b8ead6f7861f56809a85f0 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java @@ -34,6 +34,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; +import static com.android.server.job.Flags.FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER; import static com.android.server.job.JobSchedulerService.FREQUENT_INDEX; import static com.android.server.job.JobSchedulerService.RARE_INDEX; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; @@ -66,6 +67,7 @@ import android.net.NetworkPolicyManager; import android.os.Build; import android.os.Looper; import android.os.SystemClock; +import android.platform.test.flag.junit.SetFlagsRule; import android.telephony.CellSignalStrength; import android.telephony.SignalStrength; import android.telephony.TelephonyCallback; @@ -79,6 +81,7 @@ import com.android.server.job.JobSchedulerService.Constants; import com.android.server.net.NetworkPolicyManagerInternal; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -107,6 +110,9 @@ public class ConnectivityControllerTest { @Mock private PackageManager mPackageManager; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private Constants mConstants; private FlexibilityController mFlexibilityController; @@ -898,7 +904,8 @@ public class ConnectivityControllerTest { assertTrue(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants)); } - // Metered network is only when prefetching, late, and in opportunistic quota + // Metered network is only when prefetching, charging*, late, and in opportunistic quota + // *Charging only when the flag is enabled { final Network net = mock(Network.class); final NetworkCapabilities caps = createCapabilitiesBuilder() @@ -910,10 +917,27 @@ public class ConnectivityControllerTest { assertFalse(controller.isSatisfied(latePrefetch, net, caps, mConstants)); assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants)); assertFalse(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants)); + mSetFlagsRule.disableFlags(FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER); + when(mService.isBatteryCharging()).thenReturn(false); + + when(mNetPolicyManagerInternal.getSubscriptionOpportunisticQuota( + any(), eq(NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS))) + .thenReturn(9876543210L); + assertTrue(controller.isSatisfied(latePrefetch, net, caps, mConstants)); + // Only relax restrictions when we at least know the estimated download bytes. + assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants)); + assertTrue(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants)); + mSetFlagsRule.enableFlags(FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER); when(mNetPolicyManagerInternal.getSubscriptionOpportunisticQuota( any(), eq(NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS))) .thenReturn(9876543210L); + assertFalse(controller.isSatisfied(latePrefetch, net, caps, mConstants)); + // Only relax restrictions when we at least know the estimated download bytes. + assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants)); + assertFalse(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants)); + + when(mService.isBatteryCharging()).thenReturn(true); assertTrue(controller.isSatisfied(latePrefetch, net, caps, mConstants)); // Only relax restrictions when we at least know the estimated download bytes. assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants));