Home | History | Annotate | Download | only in job
      1 /*
      2  * Copyright (C) 2016 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.job;
     18 
     19 import android.app.AppGlobals;
     20 import android.content.pm.IPackageManager;
     21 import android.content.pm.PackageManager;
     22 import android.os.Binder;
     23 import android.os.RemoteException;
     24 import android.os.ShellCommand;
     25 import android.os.UserHandle;
     26 
     27 import java.io.PrintWriter;
     28 
     29 public class JobSchedulerShellCommand extends ShellCommand {
     30     public static final int CMD_ERR_NO_PACKAGE = -1000;
     31     public static final int CMD_ERR_NO_JOB = -1001;
     32     public static final int CMD_ERR_CONSTRAINTS = -1002;
     33 
     34     JobSchedulerService mInternal;
     35     IPackageManager mPM;
     36 
     37     JobSchedulerShellCommand(JobSchedulerService service) {
     38         mInternal = service;
     39         mPM = AppGlobals.getPackageManager();
     40     }
     41 
     42     @Override
     43     public int onCommand(String cmd) {
     44         final PrintWriter pw = getOutPrintWriter();
     45         try {
     46             if ("run".equals(cmd)) {
     47                 return runJob();
     48             } else {
     49                 return handleDefaultCommands(cmd);
     50             }
     51         } catch (Exception e) {
     52             pw.println("Exception: " + e);
     53         }
     54         return -1;
     55     }
     56 
     57     private int runJob() {
     58         try {
     59             final int uid = Binder.getCallingUid();
     60             final int perm = mPM.checkUidPermission(
     61                     "android.permission.CHANGE_APP_IDLE_STATE", uid);
     62             if (perm != PackageManager.PERMISSION_GRANTED) {
     63                 throw new SecurityException("Uid " + uid
     64                         + " not permitted to force scheduled jobs");
     65             }
     66         } catch (RemoteException e) {
     67             // Can't happen
     68         }
     69 
     70         final PrintWriter pw = getOutPrintWriter();
     71         boolean force = false;
     72         int userId = UserHandle.USER_SYSTEM;
     73 
     74         String opt;
     75         while ((opt = getNextOption()) != null) {
     76             switch (opt) {
     77                 case "-f":
     78                 case "--force":
     79                     force = true;
     80                     break;
     81 
     82                 case "-u":
     83                 case "--user":
     84                     userId = Integer.parseInt(getNextArgRequired());
     85                     break;
     86 
     87                 default:
     88                     pw.println("Error: unknown option '" + opt + "'");
     89                     return -1;
     90             }
     91         }
     92 
     93         final String pkgName = getNextArgRequired();
     94         final int jobId = Integer.parseInt(getNextArgRequired());
     95 
     96         int ret = mInternal.executeRunCommand(pkgName, userId, jobId, force);
     97         switch (ret) {
     98             case CMD_ERR_NO_PACKAGE:
     99                 pw.print("Package not found: ");
    100                 pw.print(pkgName);
    101                 pw.print(" / user ");
    102                 pw.println(userId);
    103                 break;
    104 
    105             case CMD_ERR_NO_JOB:
    106                 pw.print("Could not find job ");
    107                 pw.print(jobId);
    108                 pw.print(" in package ");
    109                 pw.print(pkgName);
    110                 pw.print(" / user ");
    111                 pw.println(userId);
    112                 break;
    113 
    114             case CMD_ERR_CONSTRAINTS:
    115                 pw.print("Job ");
    116                 pw.print(jobId);
    117                 pw.print(" in package ");
    118                 pw.print(pkgName);
    119                 pw.print(" / user ");
    120                 pw.print(userId);
    121                 pw.println(" has functional constraints but --force not specified");
    122                 break;
    123 
    124             default:
    125                 // success!
    126                 pw.print("Running job");
    127                 if (force) {
    128                     pw.print(" [FORCED]");
    129                 }
    130                 pw.println();
    131                 break;
    132         }
    133         return ret;
    134     }
    135 
    136     @Override
    137     public void onHelp() {
    138         final PrintWriter pw = getOutPrintWriter();
    139 
    140         pw.println("Job scheduler (jobscheduler) commands:");
    141         pw.println("  help");
    142         pw.println("    Print this help text.");
    143         pw.println();
    144         pw.println("  run [-f | --force] [-u | --user USER_ID] PACKAGE JOB_ID");
    145         pw.println("    Trigger immediate execution of a specific scheduled job.");
    146         pw.println("    Options:");
    147         pw.println("      -f or --force: run the job even if technical constraints such as");
    148         pw.println("         connectivity are not currently met");
    149         pw.println("      -u or --user: specify which user's job is to be run; the default is");
    150         pw.println("         the primary or system user");
    151         pw.println();
    152     }
    153 
    154 }
    155