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