1 /* 2 * Copyright (C) 2025 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ondevicepersonalization.services.reset; 18 19 import static com.android.adservices.shared.proto.JobPolicy.BatteryType.BATTERY_TYPE_REQUIRE_NOT_LOW; 20 import static com.android.adservices.shared.spe.JobServiceConstants.JOB_ENABLED_STATUS_DISABLED_FOR_KILL_SWITCH_ON; 21 import static com.android.adservices.shared.spe.JobServiceConstants.JOB_ENABLED_STATUS_ENABLED; 22 import static com.android.ondevicepersonalization.services.OnDevicePersonalizationConfig.RESET_DATA_JOB_ID; 23 24 import android.content.Context; 25 26 import com.android.adservices.shared.proto.JobPolicy; 27 import com.android.adservices.shared.spe.framework.ExecutionResult; 28 import com.android.adservices.shared.spe.framework.ExecutionRuntimeParameters; 29 import com.android.adservices.shared.spe.framework.JobWorker; 30 import com.android.adservices.shared.spe.scheduling.BackoffPolicy; 31 import com.android.adservices.shared.spe.scheduling.JobSpec; 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.ondevicepersonalization.internal.util.LoggerFactory; 34 import com.android.ondevicepersonalization.services.Flags; 35 import com.android.ondevicepersonalization.services.FlagsFactory; 36 import com.android.ondevicepersonalization.services.OnDevicePersonalizationExecutors; 37 import com.android.ondevicepersonalization.services.sharedlibrary.spe.OdpJobScheduler; 38 import com.android.ondevicepersonalization.services.sharedlibrary.spe.OdpJobServiceFactory; 39 40 import com.google.common.util.concurrent.Futures; 41 import com.google.common.util.concurrent.ListenableFuture; 42 43 /** 44 * JobService to handle the OnDevicePersonalization maintenance 45 */ 46 public final class ResetDataJob implements JobWorker { 47 private static final LoggerFactory.Logger sLogger = LoggerFactory.getLogger(); 48 private static final long MILLIS = 1000; 49 50 @Override getExecutionFuture(Context context, ExecutionRuntimeParameters executionRuntimeParameters)51 public ListenableFuture<ExecutionResult> getExecutionFuture(Context context, 52 ExecutionRuntimeParameters executionRuntimeParameters) { 53 return Futures.submit( 54 () -> { 55 deleteMeasurementData(); 56 return ExecutionResult.SUCCESS; 57 }, 58 OnDevicePersonalizationExecutors.getBackgroundExecutor()); 59 } 60 61 @Override getJobEnablementStatus()62 public int getJobEnablementStatus() { 63 if (!FlagsFactory.getFlags().getSpeOnResetDataJobEnabled()) { 64 sLogger.d("ResetDataJob is disabled; skipping and cancelling job"); 65 return JOB_ENABLED_STATUS_DISABLED_FOR_KILL_SWITCH_ON; 66 } 67 return JOB_ENABLED_STATUS_ENABLED; 68 } 69 70 /** Schedules a unique instance of {@link ResetDataJob}. */ schedule(Context context)71 public static void schedule(Context context) { 72 // If SPE is not enabled, force to schedule the job with the old JobService. 73 if (!FlagsFactory.getFlags().getSpeOnResetDataJobEnabled()) { 74 sLogger.d("SPE is not enabled. Schedule the job with ResetDataJobService."); 75 76 int resultCode = ResetDataJobService.schedule(/* forceSchedule */ false); 77 OdpJobServiceFactory.getInstance(context) 78 .getJobSchedulingLogger() 79 .recordOnSchedulingLegacy(RESET_DATA_JOB_ID, resultCode); 80 81 return; 82 } 83 84 OdpJobScheduler.getInstance(context).schedule(context, createDefaultJobSpec()); 85 } 86 87 @VisibleForTesting createDefaultJobSpec()88 static JobSpec createDefaultJobSpec() { 89 Flags flags = FlagsFactory.getFlags(); 90 91 JobPolicy jobPolicy = 92 JobPolicy.newBuilder() 93 .setJobId(RESET_DATA_JOB_ID) 94 .setBatteryType(BATTERY_TYPE_REQUIRE_NOT_LOW) 95 .setOneOffJobParams( 96 JobPolicy.OneOffJobParams.newBuilder() 97 .setMinimumLatencyMs( 98 flags.getResetDataDelaySeconds() * MILLIS) 99 .setOverrideDeadlineMs( 100 flags.getResetDataDeadlineSeconds() * MILLIS) 101 .build()) 102 .setIsPersisted(true) 103 .build(); 104 105 return new JobSpec.Builder(jobPolicy).build(); 106 } 107 108 @Override getBackoffPolicy()109 public BackoffPolicy getBackoffPolicy() { 110 return new BackoffPolicy.Builder().setShouldRetryOnExecutionStop(true).build(); 111 } 112 113 @VisibleForTesting deleteMeasurementData()114 void deleteMeasurementData() { 115 ResetDataTask.deleteMeasurementData(); 116 } 117 } 118