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.annotation.ElapsedRealtimeLong; 21 import android.app.ActivityManager; 22 import android.content.pm.PackageManager; 23 import android.os.SystemClock; 24 import android.os.UserHandle; 25 import android.text.TextUtils; 26 import android.util.ArraySet; 27 import android.util.TimeUtils; 28 import android.util.proto.ProtoOutputStream; 29 import android.util.proto.ProtoUtils; 30 31 import com.android.internal.annotations.CompositeRWLock; 32 import com.android.internal.annotations.GuardedBy; 33 import com.android.server.am.UidObserverController.ChangeRecord; 34 35 import java.util.function.Consumer; 36 37 /** 38 * Overall information about a uid that has actively running processes. 39 */ 40 public final class UidRecord { 41 private final ActivityManagerService mService; 42 private final ActivityManagerGlobalLock mProcLock; 43 private final int mUid; 44 45 @CompositeRWLock({"mService", "mProcLock"}) 46 private int mCurProcState; 47 48 @CompositeRWLock({"mService", "mProcLock"}) 49 private int mSetProcState = ActivityManager.PROCESS_STATE_NONEXISTENT; 50 51 @CompositeRWLock({"mService", "mProcLock"}) 52 private boolean mProcAdjChanged; 53 54 @CompositeRWLock({"mService", "mProcLock"}) 55 private int mCurAdj; 56 57 @CompositeRWLock({"mService", "mProcLock"}) 58 private int mSetAdj; 59 60 @CompositeRWLock({"mService", "mProcLock"}) 61 private int mCurCapability; 62 63 @CompositeRWLock({"mService", "mProcLock"}) 64 private int mSetCapability; 65 66 @CompositeRWLock({"mService", "mProcLock"}) 67 private long mLastBackgroundTime; 68 69 /** 70 * Last time the UID became idle. This is set to 0, once the UID becomes active. 71 */ 72 @ElapsedRealtimeLong 73 @CompositeRWLock({"mService", "mProcLock"}) 74 private long mLastIdleTimeIfStillIdle; 75 76 /** 77 * Last time the UID became idle. Unlike {@link #mLastIdleTimeIfStillIdle}, we never clear it. 78 */ 79 @ElapsedRealtimeLong 80 @CompositeRWLock({"mService", "mProcLock"}) 81 private long mRealLastIdleTime; 82 83 @CompositeRWLock({"mService", "mProcLock"}) 84 private boolean mEphemeral; 85 86 @CompositeRWLock({"mService", "mProcLock"}) 87 private boolean mForegroundServices; 88 89 @CompositeRWLock({"mService", "mProcLock"}) 90 private boolean mCurAllowList;; 91 92 @CompositeRWLock({"mService", "mProcLock"}) 93 private boolean mSetAllowList; 94 95 @CompositeRWLock({"mService", "mProcLock"}) 96 private boolean mIdle; 97 98 @CompositeRWLock({"mService", "mProcLock"}) 99 private boolean mSetIdle; 100 101 @CompositeRWLock({"mService", "mProcLock"}) 102 private int mNumProcs; 103 104 @CompositeRWLock({"mService", "mProcLock"}) 105 private ArraySet<ProcessRecord> mProcRecords = new ArraySet<>(); 106 107 /** 108 * Sequence number associated with the {@link #mCurProcState}. This is incremented using 109 * {@link ActivityManagerService#mProcStateSeqCounter} 110 * when {@link #mCurProcState} changes from background to foreground or vice versa. 111 */ 112 @GuardedBy("networkStateUpdate") 113 long curProcStateSeq; 114 115 /** 116 * Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that 117 * network policies rules were updated. 118 */ 119 @GuardedBy("networkStateUpdate") 120 long lastNetworkUpdatedProcStateSeq; 121 122 /** 123 * Indicates if any thread is waiting for network rules to get updated for {@link #mUid}. 124 */ 125 volatile long procStateSeqWaitingForNetwork; 126 127 /** 128 * Indicates whether this uid has internet permission or not. 129 */ 130 volatile boolean hasInternetPermission; 131 132 /** 133 * This object is used for waiting for the network state to get updated. 134 */ 135 final Object networkStateLock = new Object(); 136 137 /* 138 * Change bitmask flags. 139 */ 140 static final int CHANGE_GONE = 1 << 0; 141 static final int CHANGE_IDLE = 1 << 1; 142 static final int CHANGE_ACTIVE = 1 << 2; 143 static final int CHANGE_CACHED = 1 << 3; 144 static final int CHANGE_UNCACHED = 1 << 4; 145 static final int CHANGE_CAPABILITY = 1 << 5; 146 static final int CHANGE_PROCADJ = 1 << 6; 147 static final int CHANGE_PROCSTATE = 1 << 31; 148 149 // Keep the enum lists in sync 150 private static int[] ORIG_ENUMS = new int[] { 151 CHANGE_GONE, 152 CHANGE_IDLE, 153 CHANGE_ACTIVE, 154 CHANGE_CACHED, 155 CHANGE_UNCACHED, 156 CHANGE_CAPABILITY, 157 CHANGE_PROCSTATE, 158 }; 159 private static int[] PROTO_ENUMS = new int[] { 160 UidRecordProto.CHANGE_GONE, 161 UidRecordProto.CHANGE_IDLE, 162 UidRecordProto.CHANGE_ACTIVE, 163 UidRecordProto.CHANGE_CACHED, 164 UidRecordProto.CHANGE_UNCACHED, 165 UidRecordProto.CHANGE_CAPABILITY, 166 UidRecordProto.CHANGE_PROCSTATE, 167 }; 168 169 // UidObserverController is the only thing that should modify this. 170 final ChangeRecord pendingChange = new ChangeRecord(); 171 172 @GuardedBy("mService") 173 private int mLastReportedChange; 174 175 /** 176 * This indicates whether the entire Uid is frozen or not. 177 * It is used by CachedAppOptimizer to avoid sending multiple 178 * UID_FROZEN_STATE_UNFROZEN messages on process unfreeze. 179 */ 180 @GuardedBy(anyOf = {"mService", "mProcLock"}) 181 private boolean mUidIsFrozen; 182 UidRecord(int uid, ActivityManagerService service)183 public UidRecord(int uid, ActivityManagerService service) { 184 mUid = uid; 185 mService = service; 186 mProcLock = service != null ? service.mProcLock : null; 187 mIdle = true; 188 reset(); 189 } 190 getUid()191 int getUid() { 192 return mUid; 193 } 194 195 @GuardedBy(anyOf = {"mService", "mProcLock"}) getCurProcState()196 int getCurProcState() { 197 return mCurProcState; 198 } 199 200 @GuardedBy({"mService", "mProcLock"}) setCurProcState(int curProcState)201 void setCurProcState(int curProcState) { 202 mCurProcState = curProcState; 203 } 204 205 @GuardedBy(anyOf = {"mService", "mProcLock"}) getSetProcState()206 int getSetProcState() { 207 return mSetProcState; 208 } 209 210 @GuardedBy({"mService", "mProcLock"}) setSetProcState(int setProcState)211 void setSetProcState(int setProcState) { 212 mSetProcState = setProcState; 213 } 214 215 @GuardedBy({"mService", "mProcLock"}) noteProcAdjChanged()216 void noteProcAdjChanged() { 217 mProcAdjChanged = true; 218 } 219 220 @GuardedBy({"mService", "mProcLock"}) clearProcAdjChanged()221 void clearProcAdjChanged() { 222 mProcAdjChanged = false; 223 } 224 225 @GuardedBy(anyOf = {"mService", "mProcLock"}) getProcAdjChanged()226 boolean getProcAdjChanged() { 227 return mProcAdjChanged; 228 } 229 230 @GuardedBy(anyOf = {"mService", "mProcLock"}) getMinProcAdj()231 int getMinProcAdj() { 232 int minAdj = ProcessList.UNKNOWN_ADJ; 233 for (int i = mProcRecords.size() - 1; i >= 0; i--) { 234 int adj = mProcRecords.valueAt(i).getSetAdj(); 235 if (adj < minAdj) { 236 minAdj = adj; 237 } 238 } 239 return minAdj; 240 } 241 242 @GuardedBy(anyOf = {"mService", "mProcLock"}) getCurCapability()243 int getCurCapability() { 244 return mCurCapability; 245 } 246 247 @GuardedBy({"mService", "mProcLock"}) setCurCapability(int curCapability)248 void setCurCapability(int curCapability) { 249 mCurCapability = curCapability; 250 } 251 252 @GuardedBy(anyOf = {"mService", "mProcLock"}) getSetCapability()253 int getSetCapability() { 254 return mSetCapability; 255 } 256 257 @GuardedBy({"mService", "mProcLock"}) setSetCapability(int setCapability)258 void setSetCapability(int setCapability) { 259 mSetCapability = setCapability; 260 } 261 262 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLastBackgroundTime()263 long getLastBackgroundTime() { 264 return mLastBackgroundTime; 265 } 266 267 @GuardedBy({"mService", "mProcLock"}) setLastBackgroundTime(long lastBackgroundTime)268 void setLastBackgroundTime(long lastBackgroundTime) { 269 mLastBackgroundTime = lastBackgroundTime; 270 } 271 272 /** 273 * Last time the UID became idle. This is set to 0, once the UID becomes active. 274 */ 275 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLastIdleTimeIfStillIdle()276 long getLastIdleTimeIfStillIdle() { 277 return mLastIdleTimeIfStillIdle; 278 } 279 280 /** 281 * Last time the UID became idle. Unlike {@link #getLastIdleTimeIfStillIdle}, we never clear it. 282 */ 283 @GuardedBy(anyOf = {"mService", "mProcLock"}) getRealLastIdleTime()284 long getRealLastIdleTime() { 285 return mRealLastIdleTime; 286 } 287 288 @GuardedBy({"mService", "mProcLock"}) setLastIdleTime(@lapsedRealtimeLong long lastIdleTime)289 void setLastIdleTime(@ElapsedRealtimeLong long lastIdleTime) { 290 mLastIdleTimeIfStillIdle = lastIdleTime; 291 if (lastIdleTime > 0) { 292 mRealLastIdleTime = lastIdleTime; 293 } 294 } 295 296 @GuardedBy(anyOf = {"mService", "mProcLock"}) isEphemeral()297 boolean isEphemeral() { 298 return mEphemeral; 299 } 300 301 @GuardedBy({"mService", "mProcLock"}) setEphemeral(boolean ephemeral)302 void setEphemeral(boolean ephemeral) { 303 mEphemeral = ephemeral; 304 } 305 306 /** Returns whether the UID has any FGS of any type or not (including "short fgs") */ 307 @GuardedBy(anyOf = {"mService", "mProcLock"}) hasForegroundServices()308 boolean hasForegroundServices() { 309 return mForegroundServices; 310 } 311 312 /** Sets whether the UID has any FGS of any type or not (including "short fgs") */ 313 @GuardedBy({"mService", "mProcLock"}) setForegroundServices(boolean foregroundServices)314 void setForegroundServices(boolean foregroundServices) { 315 mForegroundServices = foregroundServices; 316 } 317 318 @GuardedBy(anyOf = {"mService", "mProcLock"}) isCurAllowListed()319 boolean isCurAllowListed() { 320 return mCurAllowList; 321 } 322 323 @GuardedBy({"mService", "mProcLock"}) setCurAllowListed(boolean curAllowList)324 void setCurAllowListed(boolean curAllowList) { 325 mCurAllowList = curAllowList; 326 } 327 328 @GuardedBy(anyOf = {"mService", "mProcLock"}) isSetAllowListed()329 boolean isSetAllowListed() { 330 return mSetAllowList; 331 } 332 333 @GuardedBy({"mService", "mProcLock"}) setSetAllowListed(boolean setAllowlist)334 void setSetAllowListed(boolean setAllowlist) { 335 mSetAllowList = setAllowlist; 336 } 337 338 @GuardedBy(anyOf = {"mService", "mProcLock"}) isIdle()339 boolean isIdle() { 340 return mIdle; 341 } 342 343 @GuardedBy({"mService", "mProcLock"}) setIdle(boolean idle)344 void setIdle(boolean idle) { 345 mIdle = idle; 346 } 347 348 @GuardedBy(anyOf = {"mService", "mProcLock"}) isSetIdle()349 boolean isSetIdle() { 350 return mSetIdle; 351 } 352 353 @GuardedBy({"mService", "mProcLock"}) setSetIdle(boolean setIdle)354 void setSetIdle(boolean setIdle) { 355 mSetIdle = setIdle; 356 } 357 358 @GuardedBy(anyOf = {"mService", "mProcLock"}) getNumOfProcs()359 int getNumOfProcs() { 360 return mProcRecords.size(); 361 } 362 363 @GuardedBy(anyOf = {"mService", "mProcLock"}) forEachProcess(Consumer<ProcessRecord> callback)364 void forEachProcess(Consumer<ProcessRecord> callback) { 365 for (int i = mProcRecords.size() - 1; i >= 0; i--) { 366 callback.accept(mProcRecords.valueAt(i)); 367 } 368 } 369 370 @GuardedBy(anyOf = {"mService", "mProcLock"}) getProcessRecordByIndex(int idx)371 ProcessRecord getProcessRecordByIndex(int idx) { 372 return mProcRecords.valueAt(idx); 373 } 374 375 @GuardedBy(anyOf = {"mService", "mProcLock"}) getProcessInPackage(String packageName)376 ProcessRecord getProcessInPackage(String packageName) { 377 for (int i = mProcRecords.size() - 1; i >= 0; i--) { 378 final ProcessRecord app = mProcRecords.valueAt(i); 379 if (app != null && TextUtils.equals(app.info.packageName, packageName)) { 380 return app; 381 } 382 } 383 return null; 384 } 385 386 /** 387 * Check whether all processes in the Uid are frozen. 388 * 389 * @param excluding Skip this process record during the check. 390 * @return true if all processes in the Uid are frozen, false otherwise. 391 */ 392 @GuardedBy(anyOf = {"mService", "mProcLock"}) areAllProcessesFrozen(ProcessRecord excluding)393 public boolean areAllProcessesFrozen(ProcessRecord excluding) { 394 for (int i = mProcRecords.size() - 1; i >= 0; i--) { 395 final ProcessRecord app = mProcRecords.valueAt(i); 396 final ProcessCachedOptimizerRecord opt = app.mOptRecord; 397 398 if (excluding != app && !opt.isFrozen()) { 399 return false; 400 } 401 } 402 return true; 403 } 404 405 /** 406 * @return true if all processes in the Uid are frozen, false otherwise. 407 */ 408 @GuardedBy(anyOf = {"mService", "mProcLock"}) areAllProcessesFrozen()409 public boolean areAllProcessesFrozen() { 410 return areAllProcessesFrozen(null); 411 } 412 413 @GuardedBy(anyOf = {"mService", "mProcLock"}) setFrozen(boolean frozen)414 public void setFrozen(boolean frozen) { 415 mUidIsFrozen = frozen; 416 } 417 418 @GuardedBy(anyOf = {"mService", "mProcLock"}) isFrozen()419 public boolean isFrozen() { 420 return mUidIsFrozen; 421 } 422 423 @GuardedBy({"mService", "mProcLock"}) addProcess(ProcessRecord app)424 void addProcess(ProcessRecord app) { 425 mProcRecords.add(app); 426 } 427 428 @GuardedBy({"mService", "mProcLock"}) removeProcess(ProcessRecord app)429 void removeProcess(ProcessRecord app) { 430 mProcRecords.remove(app); 431 } 432 433 @GuardedBy("mService") setLastReportedChange(int lastReportedChange)434 void setLastReportedChange(int lastReportedChange) { 435 mLastReportedChange = lastReportedChange; 436 } 437 438 @GuardedBy({"mService", "mProcLock"}) reset()439 void reset() { 440 setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY); 441 mForegroundServices = false; 442 mCurCapability = 0; 443 } 444 updateHasInternetPermission()445 public void updateHasInternetPermission() { 446 hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET, 447 mUid) == PackageManager.PERMISSION_GRANTED; 448 } 449 dumpDebug(ProtoOutputStream proto, long fieldId)450 void dumpDebug(ProtoOutputStream proto, long fieldId) { 451 long token = proto.start(fieldId); 452 proto.write(UidRecordProto.UID, mUid); 453 proto.write(UidRecordProto.CURRENT, ProcessList.makeProcStateProtoEnum(mCurProcState)); 454 proto.write(UidRecordProto.EPHEMERAL, mEphemeral); 455 proto.write(UidRecordProto.FG_SERVICES, mForegroundServices); 456 proto.write(UidRecordProto.WHILELIST, mCurAllowList); 457 ProtoUtils.toDuration(proto, UidRecordProto.LAST_BACKGROUND_TIME, 458 mLastBackgroundTime, SystemClock.elapsedRealtime()); 459 proto.write(UidRecordProto.IDLE, mIdle); 460 if (mLastReportedChange != 0) { 461 ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidRecordProto.LAST_REPORTED_CHANGES, 462 mLastReportedChange, ORIG_ENUMS, PROTO_ENUMS); 463 } 464 proto.write(UidRecordProto.NUM_PROCS, mNumProcs); 465 466 long seqToken = proto.start(UidRecordProto.NETWORK_STATE_UPDATE); 467 proto.write(UidRecordProto.ProcStateSequence.CURURENT, curProcStateSeq); 468 proto.write(UidRecordProto.ProcStateSequence.LAST_NETWORK_UPDATED, 469 lastNetworkUpdatedProcStateSeq); 470 proto.end(seqToken); 471 472 proto.end(token); 473 } 474 toString()475 public String toString() { 476 StringBuilder sb = new StringBuilder(128); 477 sb.append("UidRecord{"); 478 sb.append(Integer.toHexString(System.identityHashCode(this))); 479 sb.append(' '); 480 UserHandle.formatUid(sb, mUid); 481 sb.append(' '); 482 sb.append(ProcessList.makeProcStateString(mCurProcState)); 483 if (mEphemeral) { 484 sb.append(" ephemeral"); 485 } 486 if (mForegroundServices) { 487 sb.append(" fgServices"); 488 } 489 if (mCurAllowList) { 490 sb.append(" allowlist"); 491 } 492 if (mLastBackgroundTime > 0) { 493 sb.append(" bg:"); 494 TimeUtils.formatDuration(SystemClock.elapsedRealtime() - mLastBackgroundTime, sb); 495 } 496 if (mIdle) { 497 sb.append(" idle"); 498 } 499 if (mLastReportedChange != 0) { 500 sb.append(" change:"); 501 boolean printed = false; 502 if ((mLastReportedChange & CHANGE_GONE) != 0) { 503 printed = true; 504 sb.append("gone"); 505 } 506 if ((mLastReportedChange & CHANGE_IDLE) != 0) { 507 if (printed) { 508 sb.append("|"); 509 } 510 printed = true; 511 sb.append("idle"); 512 } 513 if ((mLastReportedChange & CHANGE_ACTIVE) != 0) { 514 if (printed) { 515 sb.append("|"); 516 } 517 printed = true; 518 sb.append("active"); 519 } 520 if ((mLastReportedChange & CHANGE_CACHED) != 0) { 521 if (printed) { 522 sb.append("|"); 523 } 524 printed = true; 525 sb.append("cached"); 526 } 527 if ((mLastReportedChange & CHANGE_UNCACHED) != 0) { 528 if (printed) { 529 sb.append("|"); 530 } 531 sb.append("uncached"); 532 } 533 if ((mLastReportedChange & CHANGE_PROCSTATE) != 0) { 534 if (printed) { 535 sb.append("|"); 536 } 537 sb.append("procstate"); 538 } 539 if ((mLastReportedChange & CHANGE_PROCADJ) != 0) { 540 if (printed) { 541 sb.append("|"); 542 } 543 sb.append("procadj"); 544 } 545 } 546 sb.append(" procs:"); 547 sb.append(mNumProcs); 548 sb.append(" seq("); 549 sb.append(curProcStateSeq); 550 sb.append(","); 551 sb.append(lastNetworkUpdatedProcStateSeq); 552 sb.append(")}"); 553 sb.append(" caps="); 554 ActivityManager.printCapabilitiesSummary(sb, mCurCapability); 555 return sb.toString(); 556 } 557 } 558