diff options
| author | 2023-10-03 20:37:46 +0000 | |
|---|---|---|
| committer | 2023-10-04 20:16:14 +0000 | |
| commit | 95071adc2264c48d6e986a8abe28b75361964da1 (patch) | |
| tree | 3634d4ff5b954c64f33fa499ee04489611abfa9d | |
| parent | 925853a950ec5459fbd16242381904833106ca34 (diff) | |
Turn off prefetch constraint relaxation on battery.
Only let prefetch jobs use the opportunistic quota when the device
is on charger to reduce excess battery drain. The opportunistic quota
usage behavior is optional and not required for prefetch jobs, so we can
disable it without impacting app or developer expectations.
Bug: 295046507
Bug: 299329948
Test: atest FrameworksMockingServicesTests:ConnectivityControllerTest
Test: atest FrameworksMockingServicesTests:PrefetchControllerTest
Change-Id: Idc137279fea1100f53ecf20279153fe92fdb5617
6 files changed, 82 insertions, 1 deletions
diff --git a/apex/jobscheduler/service/Android.bp b/apex/jobscheduler/service/Android.bp index a4a0b4b29200..887f7fe3a0e2 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 000000000000..24ecd3d73814 --- /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 000000000000..4e3cb7d83451 --- /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 6d938debde10..45f15db93a0d 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 101498aef183..0813bb09fd52 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 2b56ea8bba33..bded9b40e591 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)); |