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