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