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.CompositeRWLock; 30 import com.android.internal.annotations.GuardedBy; 31 import com.android.server.am.UidObserverController.ChangeRecord; 32 33 import java.util.function.Consumer; 34 35 /** 36 * Overall information about a uid that has actively running processes. 37 */ 38 public final class UidRecord { 39 private final ActivityManagerService mService; 40 private final ActivityManagerGlobalLock mProcLock; 41 private final int mUid; 42 43 @CompositeRWLock({"mService", "mProcLock"}) 44 private int mCurProcState; 45 46 @CompositeRWLock({"mService", "mProcLock"}) 47 private int mSetProcState = ActivityManager.PROCESS_STATE_NONEXISTENT; 48 49 @CompositeRWLock({"mService", "mProcLock"}) 50 private int mCurCapability; 51 52 @CompositeRWLock({"mService", "mProcLock"}) 53 private int mSetCapability; 54 55 @CompositeRWLock({"mService", "mProcLock"}) 56 private long mLastBackgroundTime; 57 58 @CompositeRWLock({"mService", "mProcLock"}) 59 private boolean mEphemeral; 60 61 @CompositeRWLock({"mService", "mProcLock"}) 62 private boolean mForegroundServices; 63 64 @CompositeRWLock({"mService", "mProcLock"}) 65 private boolean mCurAllowList;; 66 67 @CompositeRWLock({"mService", "mProcLock"}) 68 private boolean mSetAllowList; 69 70 @CompositeRWLock({"mService", "mProcLock"}) 71 private boolean mIdle; 72 73 @CompositeRWLock({"mService", "mProcLock"}) 74 private boolean mSetIdle; 75 76 @CompositeRWLock({"mService", "mProcLock"}) 77 private int mNumProcs; 78 79 @CompositeRWLock({"mService", "mProcLock"}) 80 private ArraySet<ProcessRecord> mProcRecords = new ArraySet<>(); 81 82 /** 83 * Sequence number associated with the {@link #mCurProcState}. This is incremented using 84 * {@link ActivityManagerService#mProcStateSeqCounter} 85 * when {@link #mCurProcState} changes from background to foreground or vice versa. 86 */ 87 @GuardedBy("networkStateUpdate") 88 long curProcStateSeq; 89 90 /** 91 * Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that 92 * network policies rules were updated. 93 */ 94 @GuardedBy("networkStateUpdate") 95 long lastNetworkUpdatedProcStateSeq; 96 97 /** 98 * Last seq number for which AcitivityManagerService dispatched uid state change to 99 * NetworkPolicyManagerService. 100 */ 101 @GuardedBy("networkStateUpdate") 102 long lastDispatchedProcStateSeq; 103 104 /** 105 * Indicates if any thread is waiting for network rules to get updated for {@link #uid}. 106 */ 107 volatile boolean waitingForNetwork; 108 109 /** 110 * Indicates whether this uid has internet permission or not. 111 */ 112 volatile boolean hasInternetPermission; 113 114 /** 115 * This object is used for waiting for the network state to get updated. 116 */ 117 final Object networkStateLock = new Object(); 118 119 static final int CHANGE_PROCSTATE = 0; 120 static final int CHANGE_GONE = 1<<0; 121 static final int CHANGE_IDLE = 1<<1; 122 static final int CHANGE_ACTIVE = 1<<2; 123 static final int CHANGE_CACHED = 1<<3; 124 static final int CHANGE_UNCACHED = 1<<4; 125 static final int CHANGE_CAPABILITY = 1<<5; 126 127 // Keep the enum lists in sync 128 private static int[] ORIG_ENUMS = new int[] { 129 CHANGE_GONE, 130 CHANGE_IDLE, 131 CHANGE_ACTIVE, 132 CHANGE_CACHED, 133 CHANGE_UNCACHED, 134 CHANGE_CAPABILITY, 135 }; 136 private static int[] PROTO_ENUMS = new int[] { 137 UidRecordProto.CHANGE_GONE, 138 UidRecordProto.CHANGE_IDLE, 139 UidRecordProto.CHANGE_ACTIVE, 140 UidRecordProto.CHANGE_CACHED, 141 UidRecordProto.CHANGE_UNCACHED, 142 UidRecordProto.CHANGE_CAPABILITY, 143 }; 144 145 // UidObserverController is the only thing that should modify this. 146 final ChangeRecord pendingChange = new ChangeRecord(); 147 148 @GuardedBy("mService") 149 private int mLastReportedChange; 150 UidRecord(int uid, ActivityManagerService service)151 public UidRecord(int uid, ActivityManagerService service) { 152 mUid = uid; 153 mService = service; 154 mProcLock = service != null ? service.mProcLock : null; 155 mIdle = true; 156 reset(); 157 } 158 getUid()159 int getUid() { 160 return mUid; 161 } 162 163 @GuardedBy(anyOf = {"mService", "mProcLock"}) getCurProcState()164 int getCurProcState() { 165 return mCurProcState; 166 } 167 168 @GuardedBy({"mService", "mProcLock"}) setCurProcState(int curProcState)169 void setCurProcState(int curProcState) { 170 mCurProcState = curProcState; 171 } 172 173 @GuardedBy(anyOf = {"mService", "mProcLock"}) getSetProcState()174 int getSetProcState() { 175 return mSetProcState; 176 } 177 178 @GuardedBy({"mService", "mProcLock"}) setSetProcState(int setProcState)179 void setSetProcState(int setProcState) { 180 mSetProcState = setProcState; 181 } 182 183 @GuardedBy(anyOf = {"mService", "mProcLock"}) getCurCapability()184 int getCurCapability() { 185 return mCurCapability; 186 } 187 188 @GuardedBy({"mService", "mProcLock"}) setCurCapability(int curCapability)189 void setCurCapability(int curCapability) { 190 mCurCapability = curCapability; 191 } 192 193 @GuardedBy(anyOf = {"mService", "mProcLock"}) getSetCapability()194 int getSetCapability() { 195 return mSetCapability; 196 } 197 198 @GuardedBy({"mService", "mProcLock"}) setSetCapability(int setCapability)199 void setSetCapability(int setCapability) { 200 mSetCapability = setCapability; 201 } 202 203 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLastBackgroundTime()204 long getLastBackgroundTime() { 205 return mLastBackgroundTime; 206 } 207 208 @GuardedBy({"mService", "mProcLock"}) setLastBackgroundTime(long lastBackgroundTime)209 void setLastBackgroundTime(long lastBackgroundTime) { 210 mLastBackgroundTime = lastBackgroundTime; 211 } 212 213 @GuardedBy(anyOf = {"mService", "mProcLock"}) isEphemeral()214 boolean isEphemeral() { 215 return mEphemeral; 216 } 217 218 @GuardedBy({"mService", "mProcLock"}) setEphemeral(boolean ephemeral)219 void setEphemeral(boolean ephemeral) { 220 mEphemeral = ephemeral; 221 } 222 223 @GuardedBy(anyOf = {"mService", "mProcLock"}) hasForegroundServices()224 boolean hasForegroundServices() { 225 return mForegroundServices; 226 } 227 228 @GuardedBy({"mService", "mProcLock"}) setForegroundServices(boolean foregroundServices)229 void setForegroundServices(boolean foregroundServices) { 230 mForegroundServices = foregroundServices; 231 } 232 233 @GuardedBy(anyOf = {"mService", "mProcLock"}) isCurAllowListed()234 boolean isCurAllowListed() { 235 return mCurAllowList; 236 } 237 238 @GuardedBy({"mService", "mProcLock"}) setCurAllowListed(boolean curAllowList)239 void setCurAllowListed(boolean curAllowList) { 240 mCurAllowList = curAllowList; 241 } 242 243 @GuardedBy(anyOf = {"mService", "mProcLock"}) isSetAllowListed()244 boolean isSetAllowListed() { 245 return mSetAllowList; 246 } 247 248 @GuardedBy({"mService", "mProcLock"}) setSetAllowListed(boolean setAllowlist)249 void setSetAllowListed(boolean setAllowlist) { 250 mSetAllowList = setAllowlist; 251 } 252 253 @GuardedBy(anyOf = {"mService", "mProcLock"}) isIdle()254 boolean isIdle() { 255 return mIdle; 256 } 257 258 @GuardedBy({"mService", "mProcLock"}) setIdle(boolean idle)259 void setIdle(boolean idle) { 260 mIdle = idle; 261 } 262 263 @GuardedBy(anyOf = {"mService", "mProcLock"}) isSetIdle()264 boolean isSetIdle() { 265 return mSetIdle; 266 } 267 268 @GuardedBy({"mService", "mProcLock"}) setSetIdle(boolean setIdle)269 void setSetIdle(boolean setIdle) { 270 mSetIdle = setIdle; 271 } 272 273 @GuardedBy(anyOf = {"mService", "mProcLock"}) getNumOfProcs()274 int getNumOfProcs() { 275 return mProcRecords.size(); 276 } 277 278 @GuardedBy(anyOf = {"mService", "mProcLock"}) forEachProcess(Consumer<ProcessRecord> callback)279 void forEachProcess(Consumer<ProcessRecord> callback) { 280 for (int i = mProcRecords.size() - 1; i >= 0; i--) { 281 callback.accept(mProcRecords.valueAt(i)); 282 } 283 } 284 285 @GuardedBy({"mService", "mProcLock"}) addProcess(ProcessRecord app)286 void addProcess(ProcessRecord app) { 287 mProcRecords.add(app); 288 } 289 290 @GuardedBy({"mService", "mProcLock"}) removeProcess(ProcessRecord app)291 void removeProcess(ProcessRecord app) { 292 mProcRecords.remove(app); 293 } 294 295 @GuardedBy("mService") setLastReportedChange(int lastReportedChange)296 void setLastReportedChange(int lastReportedChange) { 297 mLastReportedChange = lastReportedChange; 298 } 299 300 @GuardedBy({"mService", "mProcLock"}) reset()301 void reset() { 302 setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY); 303 mForegroundServices = false; 304 mCurCapability = 0; 305 } 306 updateHasInternetPermission()307 public void updateHasInternetPermission() { 308 hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET, 309 mUid) == PackageManager.PERMISSION_GRANTED; 310 } 311 312 /** 313 * If the change being dispatched is not CHANGE_GONE (not interested in 314 * these changes), then update the {@link #lastDispatchedProcStateSeq} with 315 * {@link #curProcStateSeq}. 316 */ updateLastDispatchedProcStateSeq(int changeToDispatch)317 public void updateLastDispatchedProcStateSeq(int changeToDispatch) { 318 if ((changeToDispatch & CHANGE_GONE) == 0) { 319 lastDispatchedProcStateSeq = curProcStateSeq; 320 } 321 } 322 323 dumpDebug(ProtoOutputStream proto, long fieldId)324 void dumpDebug(ProtoOutputStream proto, long fieldId) { 325 long token = proto.start(fieldId); 326 proto.write(UidRecordProto.UID, mUid); 327 proto.write(UidRecordProto.CURRENT, ProcessList.makeProcStateProtoEnum(mCurProcState)); 328 proto.write(UidRecordProto.EPHEMERAL, mEphemeral); 329 proto.write(UidRecordProto.FG_SERVICES, mForegroundServices); 330 proto.write(UidRecordProto.WHILELIST, mCurAllowList); 331 ProtoUtils.toDuration(proto, UidRecordProto.LAST_BACKGROUND_TIME, 332 mLastBackgroundTime, SystemClock.elapsedRealtime()); 333 proto.write(UidRecordProto.IDLE, mIdle); 334 if (mLastReportedChange != 0) { 335 ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidRecordProto.LAST_REPORTED_CHANGES, 336 mLastReportedChange, ORIG_ENUMS, PROTO_ENUMS); 337 } 338 proto.write(UidRecordProto.NUM_PROCS, mNumProcs); 339 340 long seqToken = proto.start(UidRecordProto.NETWORK_STATE_UPDATE); 341 proto.write(UidRecordProto.ProcStateSequence.CURURENT, curProcStateSeq); 342 proto.write(UidRecordProto.ProcStateSequence.LAST_NETWORK_UPDATED, 343 lastNetworkUpdatedProcStateSeq); 344 proto.write(UidRecordProto.ProcStateSequence.LAST_DISPATCHED, lastDispatchedProcStateSeq); 345 proto.end(seqToken); 346 347 proto.end(token); 348 } 349 toString()350 public String toString() { 351 StringBuilder sb = new StringBuilder(128); 352 sb.append("UidRecord{"); 353 sb.append(Integer.toHexString(System.identityHashCode(this))); 354 sb.append(' '); 355 UserHandle.formatUid(sb, mUid); 356 sb.append(' '); 357 sb.append(ProcessList.makeProcStateString(mCurProcState)); 358 if (mEphemeral) { 359 sb.append(" ephemeral"); 360 } 361 if (mForegroundServices) { 362 sb.append(" fgServices"); 363 } 364 if (mCurAllowList) { 365 sb.append(" allowlist"); 366 } 367 if (mLastBackgroundTime > 0) { 368 sb.append(" bg:"); 369 TimeUtils.formatDuration(SystemClock.elapsedRealtime() - mLastBackgroundTime, sb); 370 } 371 if (mIdle) { 372 sb.append(" idle"); 373 } 374 if (mLastReportedChange != 0) { 375 sb.append(" change:"); 376 boolean printed = false; 377 if ((mLastReportedChange & CHANGE_GONE) != 0) { 378 printed = true; 379 sb.append("gone"); 380 } 381 if ((mLastReportedChange & CHANGE_IDLE) != 0) { 382 if (printed) { 383 sb.append("|"); 384 } 385 printed = true; 386 sb.append("idle"); 387 } 388 if ((mLastReportedChange & CHANGE_ACTIVE) != 0) { 389 if (printed) { 390 sb.append("|"); 391 } 392 printed = true; 393 sb.append("active"); 394 } 395 if ((mLastReportedChange & CHANGE_CACHED) != 0) { 396 if (printed) { 397 sb.append("|"); 398 } 399 printed = true; 400 sb.append("cached"); 401 } 402 if ((mLastReportedChange & CHANGE_UNCACHED) != 0) { 403 if (printed) { 404 sb.append("|"); 405 } 406 sb.append("uncached"); 407 } 408 } 409 sb.append(" procs:"); 410 sb.append(mNumProcs); 411 sb.append(" seq("); 412 sb.append(curProcStateSeq); 413 sb.append(","); 414 sb.append(lastNetworkUpdatedProcStateSeq); 415 sb.append(","); 416 sb.append(lastDispatchedProcStateSeq); 417 sb.append(")}"); 418 return sb.toString(); 419 } 420 } 421