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