1 /* 2 * Copyright (C) 2015 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.am; 18 19 import android.Manifest; 20 import android.app.ActivityManager; 21 import android.content.pm.PackageManager; 22 import android.os.SystemClock; 23 import android.os.UserHandle; 24 import android.util.TimeUtils; 25 26 import com.android.internal.annotations.GuardedBy; 27 import com.android.internal.annotations.VisibleForTesting; 28 29 /** 30 * Overall information about a uid that has actively running processes. 31 */ 32 public final class UidRecord { 33 final int uid; 34 int curProcState; 35 int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT; 36 long lastBackgroundTime; 37 boolean ephemeral; 38 boolean foregroundServices; 39 boolean curWhitelist; 40 boolean setWhitelist; 41 boolean idle; 42 boolean setIdle; 43 int numProcs; 44 45 /** 46 * Sequence number associated with the {@link #curProcState}. This is incremented using 47 * {@link ActivityManagerService#mProcStateSeqCounter} 48 * when {@link #curProcState} changes from background to foreground or vice versa. 49 */ 50 @GuardedBy("networkStateUpdate") 51 long curProcStateSeq; 52 53 /** 54 * Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that 55 * network policies rules were updated. 56 */ 57 @GuardedBy("networkStateUpdate") 58 long lastNetworkUpdatedProcStateSeq; 59 60 /** 61 * Last seq number for which AcitivityManagerService dispatched uid state change to 62 * NetworkPolicyManagerService. 63 */ 64 @GuardedBy("networkStateUpdate") 65 long lastDispatchedProcStateSeq; 66 67 /** 68 * Indicates if any thread is waiting for network rules to get updated for {@link #uid}. 69 */ 70 volatile boolean waitingForNetwork; 71 72 /** 73 * Indicates whether this uid has internet permission or not. 74 */ 75 volatile boolean hasInternetPermission; 76 77 /** 78 * This object is used for waiting for the network state to get updated. 79 */ 80 final Object networkStateLock = new Object(); 81 82 static final int CHANGE_PROCSTATE = 0; 83 static final int CHANGE_GONE = 1<<0; 84 static final int CHANGE_IDLE = 1<<1; 85 static final int CHANGE_ACTIVE = 1<<2; 86 static final int CHANGE_CACHED = 1<<3; 87 static final int CHANGE_UNCACHED = 1<<4; 88 89 static final class ChangeItem { 90 UidRecord uidRecord; 91 int uid; 92 int change; 93 int processState; 94 boolean ephemeral; 95 long procStateSeq; 96 } 97 98 ChangeItem pendingChange; 99 int lastReportedChange; 100 101 public UidRecord(int _uid) { 102 uid = _uid; 103 idle = true; 104 reset(); 105 } 106 107 public void reset() { 108 curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 109 foregroundServices = false; 110 } 111 112 public void updateHasInternetPermission() { 113 hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET, 114 uid) == PackageManager.PERMISSION_GRANTED; 115 } 116 117 /** 118 * If the change being dispatched is not CHANGE_GONE (not interested in 119 * these changes), then update the {@link #lastDispatchedProcStateSeq} with 120 * {@link #curProcStateSeq}. 121 */ 122 public void updateLastDispatchedProcStateSeq(int changeToDispatch) { 123 if ((changeToDispatch & CHANGE_GONE) == 0) { 124 lastDispatchedProcStateSeq = curProcStateSeq; 125 } 126 } 127 128 public String toString() { 129 StringBuilder sb = new StringBuilder(128); 130 sb.append("UidRecord{"); 131 sb.append(Integer.toHexString(System.identityHashCode(this))); 132 sb.append(' '); 133 UserHandle.formatUid(sb, uid); 134 sb.append(' '); 135 sb.append(ProcessList.makeProcStateString(curProcState)); 136 if (ephemeral) { 137 sb.append(" ephemeral"); 138 } 139 if (foregroundServices) { 140 sb.append(" fgServices"); 141 } 142 if (curWhitelist) { 143 sb.append(" whitelist"); 144 } 145 if (lastBackgroundTime > 0) { 146 sb.append(" bg:"); 147 TimeUtils.formatDuration(SystemClock.elapsedRealtime()-lastBackgroundTime, sb); 148 } 149 if (idle) { 150 sb.append(" idle"); 151 } 152 if (lastReportedChange != 0) { 153 sb.append(" change:"); 154 boolean printed = false; 155 if ((lastReportedChange & CHANGE_GONE) != 0) { 156 printed = true; 157 sb.append("gone"); 158 } 159 if ((lastReportedChange & CHANGE_IDLE) != 0) { 160 if (printed) { 161 sb.append("|"); 162 } 163 printed = true; 164 sb.append("idle"); 165 } 166 if ((lastReportedChange & CHANGE_ACTIVE) != 0) { 167 if (printed) { 168 sb.append("|"); 169 } 170 printed = true; 171 sb.append("active"); 172 } 173 if ((lastReportedChange & CHANGE_CACHED) != 0) { 174 if (printed) { 175 sb.append("|"); 176 } 177 printed = true; 178 sb.append("cached"); 179 } 180 if ((lastReportedChange & CHANGE_UNCACHED) != 0) { 181 if (printed) { 182 sb.append("|"); 183 } 184 sb.append("uncached"); 185 } 186 } 187 sb.append(" procs:"); 188 sb.append(numProcs); 189 sb.append(" seq("); 190 sb.append(curProcStateSeq); 191 sb.append(","); 192 sb.append(lastNetworkUpdatedProcStateSeq); 193 sb.append(","); 194 sb.append(lastDispatchedProcStateSeq); 195 sb.append(")}"); 196 return sb.toString(); 197 } 198 } 199