1 /*
2  * Copyright (C) 2014 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.server.backup;
18 
19 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
20 
21 import android.app.job.JobInfo;
22 import android.app.job.JobParameters;
23 import android.app.job.JobScheduler;
24 import android.app.job.JobService;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.os.Bundle;
28 import android.util.SparseArray;
29 
30 import com.android.internal.annotations.GuardedBy;
31 import com.android.internal.annotations.VisibleForTesting;
32 
33 public class FullBackupJob extends JobService {
34     private static final String USER_ID_EXTRA_KEY = "userId";
35 
36     @VisibleForTesting
37     public static final int MIN_JOB_ID = 52418896;
38     @VisibleForTesting
39     public static final int MAX_JOB_ID = 52419896;
40 
41     private static ComponentName sIdleService =
42             new ComponentName(PLATFORM_PACKAGE_NAME, FullBackupJob.class.getName());
43 
44     @GuardedBy("mParamsForUser")
45     private final SparseArray<JobParameters> mParamsForUser = new SparseArray<>();
46 
schedule(int userId, Context ctx, long minDelay, BackupManagerConstants constants)47     public static void schedule(int userId, Context ctx, long minDelay,
48             BackupManagerConstants constants) {
49         JobScheduler js = (JobScheduler) ctx.getSystemService(Context.JOB_SCHEDULER_SERVICE);
50         JobInfo.Builder builder = new JobInfo.Builder(getJobIdForUserId(userId), sIdleService);
51         synchronized (constants) {
52             builder.setRequiresDeviceIdle(true)
53                     .setRequiredNetworkType(constants.getFullBackupRequiredNetworkType())
54                     .setRequiresCharging(constants.getFullBackupRequireCharging());
55         }
56         if (minDelay > 0) {
57             builder.setMinimumLatency(minDelay);
58         }
59 
60         Bundle extraInfo = new Bundle();
61         extraInfo.putInt(USER_ID_EXTRA_KEY, userId);
62         builder.setTransientExtras(extraInfo);
63 
64         js.schedule(builder.build());
65     }
66 
cancel(int userId, Context ctx)67     public static void cancel(int userId, Context ctx) {
68         JobScheduler js = (JobScheduler) ctx.getSystemService(
69                 Context.JOB_SCHEDULER_SERVICE);
70         js.cancel(getJobIdForUserId(userId));
71     }
72 
73     // callback from the Backup Manager Service: it's finished its work for this pass
finishBackupPass(int userId)74     public void finishBackupPass(int userId) {
75         synchronized (mParamsForUser) {
76             JobParameters jobParameters = mParamsForUser.get(userId);
77             if (jobParameters != null) {
78                 jobFinished(jobParameters, false);
79                 mParamsForUser.remove(userId);
80             }
81         }
82     }
83 
84     // ----- scheduled job interface -----
85 
86     @Override
onStartJob(JobParameters params)87     public boolean onStartJob(JobParameters params) {
88         int userId = params.getTransientExtras().getInt(USER_ID_EXTRA_KEY);
89 
90         synchronized (mParamsForUser) {
91             mParamsForUser.put(userId, params);
92         }
93 
94         BackupManagerService service = BackupManagerService.getInstance();
95         return service.beginFullBackup(userId, this);
96     }
97 
98     @Override
onStopJob(JobParameters params)99     public boolean onStopJob(JobParameters params) {
100         int userId = params.getTransientExtras().getInt(USER_ID_EXTRA_KEY);
101 
102         synchronized (mParamsForUser) {
103             if (mParamsForUser.removeReturnOld(userId) == null) {
104                 return false;
105             }
106         }
107 
108         BackupManagerService service = BackupManagerService.getInstance();
109         service.endFullBackup(userId);
110 
111         return false;
112     }
113 
getJobIdForUserId(int userId)114     private static int getJobIdForUserId(int userId) {
115         return JobIdManager.getJobIdForUserId(MIN_JOB_ID, MAX_JOB_ID, userId);
116     }
117 }
118