blob: c8559c8025bd78a6a0f250f5e8b13dc04b08653d [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.connectivity.ipmemorystore;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.Status;
import android.net.ipmemorystore.StatusParcelable;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
/**
* Regular maintenance job service.
* @hide
*/
public final class RegularMaintenanceJobService extends JobService {
// Must be unique within the system server uid.
public static final int REGULAR_MAINTENANCE_ID = 3345678;
/**
* Class for interrupt check of maintenance job.
*/
public static final class InterruptMaintenance {
private volatile boolean mIsInterrupted;
private final int mJobId;
public InterruptMaintenance(int jobId) {
mJobId = jobId;
mIsInterrupted = false;
}
public int getJobId() {
return mJobId;
}
public void setInterrupted(boolean interrupt) {
mIsInterrupted = interrupt;
}
public boolean isInterrupted() {
return mIsInterrupted;
}
}
private static final CopyOnWriteArrayList<InterruptMaintenance> sInterruptList =
new CopyOnWriteArrayList<>();
private static IpMemoryStoreService sIpMemoryStoreService;
@Override
public boolean onStartJob(JobParameters params) {
if (sIpMemoryStoreService == null) {
Log.wtf("RegularMaintenanceJobService",
"Can not start job because sIpMemoryStoreService is null.");
return false;
}
final InterruptMaintenance im = new InterruptMaintenance(params.getJobId());
sInterruptList.add(im);
sIpMemoryStoreService.fullMaintenance(new IOnStatusListener() {
@Override
public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
final Status result = new Status(statusParcelable);
if (!result.isSuccess()) {
Log.e("RegularMaintenanceJobService", "Regular maintenance failed."
+ " Error is " + result.resultCode);
}
sInterruptList.remove(im);
jobFinished(params, !result.isSuccess());
}
@Override
public int getInterfaceVersion() {
return this.VERSION;
}
@Override
public String getInterfaceHash() {
return this.HASH;
}
@Override
public IBinder asBinder() {
return null;
}
}, im);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
final int jobId = params.getJobId();
for (InterruptMaintenance im : sInterruptList) {
if (im.getJobId() == jobId) {
im.setInterrupted(true);
}
}
return true;
}
/** Schedule regular maintenance job */
static void schedule(Context context, IpMemoryStoreService ipMemoryStoreService) {
final JobScheduler jobScheduler =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
final ComponentName maintenanceJobName =
new ComponentName(context, RegularMaintenanceJobService.class);
// Regular maintenance is scheduled for when the device is idle with access power and a
// minimum interval of one day.
final JobInfo regularMaintenanceJob =
new JobInfo.Builder(REGULAR_MAINTENANCE_ID, maintenanceJobName)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.setPeriodic(TimeUnit.HOURS.toMillis(24)).build();
jobScheduler.schedule(regularMaintenanceJob);
sIpMemoryStoreService = ipMemoryStoreService;
}
/** Unschedule regular maintenance job */
static void unschedule(Context context) {
final JobScheduler jobScheduler =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.cancel(REGULAR_MAINTENANCE_ID);
sIpMemoryStoreService = null;
}
}