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