1 /* 2 * Copyright (C) 2022 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.tare; 18 19 import android.Manifest; 20 import android.annotation.NonNull; 21 import android.content.pm.PackageManager; 22 import android.os.Binder; 23 24 import com.android.modules.utils.BasicShellCommandHandler; 25 26 import java.io.PrintWriter; 27 28 /** 29 * Shell command handler for TARE. 30 */ 31 public class TareShellCommand extends BasicShellCommandHandler { 32 static final int COMMAND_ERROR = -1; 33 static final int COMMAND_SUCCESS = 0; 34 35 private final InternalResourceService mIrs; 36 TareShellCommand(@onNull InternalResourceService irs)37 public TareShellCommand(@NonNull InternalResourceService irs) { 38 mIrs = irs; 39 } 40 41 @Override onCommand(String cmd)42 public int onCommand(String cmd) { 43 final PrintWriter pw = getOutPrintWriter(); 44 try { 45 switch (cmd != null ? cmd : "") { 46 case "clear-vip": 47 return runClearVip(pw); 48 case "set-vip": 49 return runSetVip(pw); 50 default: 51 return handleDefaultCommands(cmd); 52 } 53 } catch (Exception e) { 54 pw.println("Exception: " + e); 55 } 56 return COMMAND_ERROR; 57 } 58 59 @Override onHelp()60 public void onHelp() { 61 final PrintWriter pw = getOutPrintWriter(); 62 63 pw.println("TARE commands:"); 64 pw.println(" help"); 65 pw.println(" Print this help text."); 66 pw.println(" clear-vip"); 67 pw.println(" Clears all VIP settings resulting from previous calls using `set-vip` and"); 68 pw.println(" resets them all to default."); 69 pw.println(" set-vip <USER_ID> <PACKAGE> <true|false|default>"); 70 pw.println(" Designate the app as a Very Important Package or not. A VIP is allowed to"); 71 pw.println(" do as much work as it wants, regardless of TARE state."); 72 pw.println(" The user ID must be an explicit user ID. USER_ALL, CURRENT, etc. are not"); 73 pw.println(" supported."); 74 pw.println(); 75 } 76 checkPermission(@onNull String operation)77 private void checkPermission(@NonNull String operation) throws Exception { 78 final int perm = mIrs.getContext() 79 .checkCallingOrSelfPermission(Manifest.permission.CHANGE_APP_IDLE_STATE); 80 if (perm != PackageManager.PERMISSION_GRANTED) { 81 throw new SecurityException("Uid " + Binder.getCallingUid() 82 + " not permitted to " + operation); 83 } 84 } 85 runClearVip(@onNull PrintWriter pw)86 private int runClearVip(@NonNull PrintWriter pw) throws Exception { 87 checkPermission("clear vip"); 88 89 final long ident = Binder.clearCallingIdentity(); 90 try { 91 return mIrs.executeClearVip(pw); 92 } finally { 93 Binder.restoreCallingIdentity(ident); 94 } 95 } 96 runSetVip(@onNull PrintWriter pw)97 private int runSetVip(@NonNull PrintWriter pw) throws Exception { 98 checkPermission("modify vip"); 99 100 final int userId = Integer.parseInt(getNextArgRequired()); 101 final String pkgName = getNextArgRequired(); 102 final String vipState = getNextArgRequired(); 103 final Boolean isVip = "default".equals(vipState) ? null : Boolean.valueOf(vipState); 104 105 final long ident = Binder.clearCallingIdentity(); 106 try { 107 return mIrs.executeSetVip(pw, userId, pkgName, isVip); 108 } finally { 109 Binder.restoreCallingIdentity(ident); 110 } 111 } 112 } 113