blob: 2775fde4c8b9257198c179635a92f254266e095e [file] [log] [blame]
paulhu028d7a52019-03-26 01:39:10 +08001/*
2 * Copyright (C) 2019 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
17package com.android.server.connectivity.ipmemorystore;
18
19import android.app.job.JobInfo;
20import android.app.job.JobParameters;
21import android.app.job.JobScheduler;
22import android.app.job.JobService;
23import android.content.ComponentName;
24import android.content.Context;
25import android.net.ipmemorystore.IOnStatusListener;
26import android.net.ipmemorystore.Status;
27import android.net.ipmemorystore.StatusParcelable;
28import android.os.IBinder;
29import android.os.RemoteException;
30import android.util.Log;
31
32import java.util.ArrayList;
33import java.util.concurrent.TimeUnit;
34
35/**
36 * Regular maintenance job service.
37 * @hide
38 */
39public final class RegularMaintenanceJobService extends JobService {
40 // Must be unique within the system server uid.
41 public static final int REGULAR_MAINTENANCE_ID = 3345678;
42
43 /**
44 * Class for interrupt check of maintenance job.
45 */
46 public static final class InterruptMaintenance {
47 private volatile boolean mIsInterrupted;
48 private final int mJobId;
49
50 public InterruptMaintenance(int jobId) {
51 mJobId = jobId;
52 mIsInterrupted = false;
53 }
54
55 public int getJobId() {
56 return mJobId;
57 }
58
59 public void setInterrupted(boolean interrupt) {
60 mIsInterrupted = interrupt;
61 }
62
63 public boolean isInterrupted() {
64 return mIsInterrupted;
65 }
66 }
67
68 private static final ArrayList<InterruptMaintenance> sInterruptList = new ArrayList<>();
69 private static IpMemoryStoreService sIpMemoryStoreService;
70
71 @Override
72 public boolean onStartJob(JobParameters params) {
73 if (sIpMemoryStoreService == null) {
74 Log.wtf("RegularMaintenanceJobService",
75 "Can not start job because sIpMemoryStoreService is null.");
76 return false;
77 }
78 final InterruptMaintenance im = new InterruptMaintenance(params.getJobId());
79 sInterruptList.add(im);
80
81 sIpMemoryStoreService.fullMaintenance(new IOnStatusListener() {
82 @Override
83 public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
84 final Status result = new Status(statusParcelable);
85 if (!result.isSuccess()) {
86 Log.e("RegularMaintenanceJobService", "Regular maintenance failed."
87 + " Error is " + result.resultCode);
88 }
89 sInterruptList.remove(im);
90 jobFinished(params, !result.isSuccess());
91 }
92
93 @Override
94 public IBinder asBinder() {
95 return null;
96 }
97 }, im);
98 return true;
99 }
100
101 @Override
102 public boolean onStopJob(JobParameters params) {
103 final int jobId = params.getJobId();
104 for (InterruptMaintenance im : sInterruptList) {
105 if (im.getJobId() == jobId) {
106 im.setInterrupted(true);
107 }
108 }
109 return true;
110 }
111
112 /** Schedule regular maintenance job */
113 static void schedule(Context context, IpMemoryStoreService ipMemoryStoreService) {
114 final JobScheduler jobScheduler =
115 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
116
117 final ComponentName maintenanceJobName =
118 new ComponentName(context, RegularMaintenanceJobService.class);
119
120 // Regular maintenance is scheduled for when the device is idle with access power and a
121 // minimum interval of one day.
122 final JobInfo regularMaintenanceJob =
123 new JobInfo.Builder(REGULAR_MAINTENANCE_ID, maintenanceJobName)
124 .setRequiresDeviceIdle(true)
125 .setRequiresCharging(true)
126 .setRequiresBatteryNotLow(true)
127 .setPeriodic(TimeUnit.HOURS.toMillis(24)).build();
128
129 jobScheduler.schedule(regularMaintenanceJob);
130 sIpMemoryStoreService = ipMemoryStoreService;
131 }
132
133 /** Unschedule regular maintenance job */
134 static void unschedule(Context context) {
135 final JobScheduler jobScheduler =
136 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
137 jobScheduler.cancel(REGULAR_MAINTENANCE_ID);
138 sIpMemoryStoreService = null;
139 }
140}