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