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.ArraySet; 25 import android.util.TimeUtils; 26 import android.util.proto.ProtoOutputStream; 27 import android.util.proto.ProtoUtils; 28 29 import com.android.internal.annotations.GuardedBy; 30 31 /** 32 * Overall information about a uid that has actively running processes. 33 */ 34 public final class UidRecord { 35 final int uid; 36 int mCurProcState; 37 int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT; 38 int curCapability; 39 int setCapability; 40 long lastBackgroundTime; 41 boolean ephemeral; 42 boolean foregroundServices; 43 boolean curWhitelist; 44 boolean setWhitelist; 45 boolean idle; 46 boolean setIdle; 47 int numProcs; 48 ArraySet<ProcessRecord> procRecords = new ArraySet<>(); 49 50 /** 51 * Sequence number associated with the {@link #mCurProcState}. This is incremented using 52 * {@link ActivityManagerService#mProcStateSeqCounter} 53 * when {@link #mCurProcState} changes from background to foreground or vice versa. 54 */ 55 @GuardedBy("networkStateUpdate") 56 long curProcStateSeq; 57 58 /** 59 * Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that 60 * network policies rules were updated. 61 */ 62 @GuardedBy("networkStateUpdate") 63 long lastNetworkUpdatedProcStateSeq; 64 65 /** 66 * Last seq number for which AcitivityManagerService dispatched uid state change to 67 * NetworkPolicyManagerService. 68 */ 69 @GuardedBy("networkStateUpdate") 70 long lastDispatchedProcStateSeq; 71 72 /** 73 * Indicates if any thread is waiting for network rules to get updated for {@link #uid}. 74 */ 75 volatile boolean waitingForNetwork; 76 77 /** 78 * Indicates whether this uid has internet permission or not. 79 */ 80 volatile boolean hasInternetPermission; 81 82 /** 83 * This object is used for waiting for the network state to get updated. 84 */ 85 final Object networkStateLock = new Object(); 86 87 static final int CHANGE_PROCSTATE = 0; 88 static final int CHANGE_GONE = 1<<0; 89 static final int CHANGE_IDLE = 1<<1; 90 static final int CHANGE_ACTIVE = 1<<2; 91 static final int CHANGE_CACHED = 1<<3; 92 static final int CHANGE_UNCACHED = 1<<4; 93 94 // Keep the enum lists in sync 95 private static int[] ORIG_ENUMS = new int[] { 96 CHANGE_GONE, 97 CHANGE_IDLE, 98 CHANGE_ACTIVE, 99 CHANGE_CACHED, 100 CHANGE_UNCACHED, 101 }; 102 private static int[] PROTO_ENUMS = new int[] { 103 UidRecordProto.CHANGE_GONE, 104 UidRecordProto.CHANGE_IDLE, 105 UidRecordProto.CHANGE_ACTIVE, 106 UidRecordProto.CHANGE_CACHED, 107 UidRecordProto.CHANGE_UNCACHED, 108 }; 109 110 static final class ChangeItem { 111 UidRecord uidRecord; 112 int uid; 113 int change; 114 int processState; 115 int capability; 116 boolean ephemeral; 117 long procStateSeq; 118 } 119 120 ChangeItem pendingChange; 121 int lastReportedChange; 122 UidRecord(int _uid)123 public UidRecord(int _uid) { 124 uid = _uid; 125 idle = true; 126 reset(); 127 } 128 getCurProcState()129 public int getCurProcState() { 130 return mCurProcState; 131 } 132 setCurProcState(int curProcState)133 public void setCurProcState(int curProcState) { 134 mCurProcState = curProcState; 135 } 136 reset()137 public void reset() { 138 setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY); 139 foregroundServices = false; 140 curCapability = 0; 141 142 } 143 updateHasInternetPermission()144 public void updateHasInternetPermission() { 145 hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET, 146 uid) == PackageManager.PERMISSION_GRANTED; 147 } 148 149 /** 150 * If the change being dispatched is not CHANGE_GONE (not interested in 151 * these changes), then update the {@link #lastDispatchedProcStateSeq} with 152 * {@link #curProcStateSeq}. 153 */ updateLastDispatchedProcStateSeq(int changeToDispatch)154 public void updateLastDispatchedProcStateSeq(int changeToDispatch) { 155 if ((changeToDispatch & CHANGE_GONE) == 0) { 156 lastDispatchedProcStateSeq = curProcStateSeq; 157 } 158 } 159 160 dumpDebug(ProtoOutputStream proto, long fieldId)161 void dumpDebug(ProtoOutputStream proto, long fieldId) { 162 long token = proto.start(fieldId); 163 proto.write(UidRecordProto.UID, uid); 164 proto.write(UidRecordProto.CURRENT, ProcessList.makeProcStateProtoEnum(mCurProcState)); 165 proto.write(UidRecordProto.EPHEMERAL, ephemeral); 166 proto.write(UidRecordProto.FG_SERVICES, foregroundServices); 167 proto.write(UidRecordProto.WHILELIST, curWhitelist); 168 ProtoUtils.toDuration(proto, UidRecordProto.LAST_BACKGROUND_TIME, 169 lastBackgroundTime, SystemClock.elapsedRealtime()); 170 proto.write(UidRecordProto.IDLE, idle); 171 if (lastReportedChange != 0) { 172 ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidRecordProto.LAST_REPORTED_CHANGES, 173 lastReportedChange, ORIG_ENUMS, PROTO_ENUMS); 174 } 175 proto.write(UidRecordProto.NUM_PROCS, numProcs); 176 177 long seqToken = proto.start(UidRecordProto.NETWORK_STATE_UPDATE); 178 proto.write(UidRecordProto.ProcStateSequence.CURURENT, curProcStateSeq); 179 proto.write(UidRecordProto.ProcStateSequence.LAST_NETWORK_UPDATED, 180 lastNetworkUpdatedProcStateSeq); 181 proto.write(UidRecordProto.ProcStateSequence.LAST_DISPATCHED, lastDispatchedProcStateSeq); 182 proto.end(seqToken); 183 184 proto.end(token); 185 } 186 toString()187 public String toString() { 188 StringBuilder sb = new StringBuilder(128); 189 sb.append("UidRecord{"); 190 sb.append(Integer.toHexString(System.identityHashCode(this))); 191 sb.append(' '); 192 UserHandle.formatUid(sb, uid); 193 sb.append(' '); 194 sb.append(ProcessList.makeProcStateString(mCurProcState)); 195 if (ephemeral) { 196 sb.append(" ephemeral"); 197 } 198 if (foregroundServices) { 199 sb.append(" fgServices"); 200 } 201 if (curWhitelist) { 202 sb.append(" whitelist"); 203 } 204 if (lastBackgroundTime > 0) { 205 sb.append(" bg:"); 206 TimeUtils.formatDuration(SystemClock.elapsedRealtime()-lastBackgroundTime, sb); 207 } 208 if (idle) { 209 sb.append(" idle"); 210 } 211 if (lastReportedChange != 0) { 212 sb.append(" change:"); 213 boolean printed = false; 214 if ((lastReportedChange & CHANGE_GONE) != 0) { 215 printed = true; 216 sb.append("gone"); 217 } 218 if ((lastReportedChange & CHANGE_IDLE) != 0) { 219 if (printed) { 220 sb.append("|"); 221 } 222 printed = true; 223 sb.append("idle"); 224 } 225 if ((lastReportedChange & CHANGE_ACTIVE) != 0) { 226 if (printed) { 227 sb.append("|"); 228 } 229 printed = true; 230 sb.append("active"); 231 } 232 if ((lastReportedChange & CHANGE_CACHED) != 0) { 233 if (printed) { 234 sb.append("|"); 235 } 236 printed = true; 237 sb.append("cached"); 238 } 239 if ((lastReportedChange & CHANGE_UNCACHED) != 0) { 240 if (printed) { 241 sb.append("|"); 242 } 243 sb.append("uncached"); 244 } 245 } 246 sb.append(" procs:"); 247 sb.append(numProcs); 248 sb.append(" seq("); 249 sb.append(curProcStateSeq); 250 sb.append(","); 251 sb.append(lastNetworkUpdatedProcStateSeq); 252 sb.append(","); 253 sb.append(lastDispatchedProcStateSeq); 254 sb.append(")}"); 255 return sb.toString(); 256 } 257 } 258