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.TimeUtils;
25 
26 import com.android.internal.annotations.GuardedBy;
27 import com.android.internal.annotations.VisibleForTesting;
28 
29 /**
30  * Overall information about a uid that has actively running processes.
31  */
32 public final class UidRecord {
33     final int uid;
34     int curProcState;
35     int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
36     long lastBackgroundTime;
37     boolean ephemeral;
38     boolean foregroundServices;
39     boolean curWhitelist;
40     boolean setWhitelist;
41     boolean idle;
42     int numProcs;
43 
44     /**
45      * Sequence number associated with the {@link #curProcState}. This is incremented using
46      * {@link ActivityManagerService#mProcStateSeqCounter}
47      * when {@link #curProcState} changes from background to foreground or vice versa.
48      */
49     @GuardedBy("networkStateUpdate")
50     long curProcStateSeq;
51 
52     /**
53      * Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that
54      * network policies rules were updated.
55      */
56     @GuardedBy("networkStateUpdate")
57     long lastNetworkUpdatedProcStateSeq;
58 
59     /**
60      * Last seq number for which AcitivityManagerService dispatched uid state change to
61      * NetworkPolicyManagerService.
62      */
63     @GuardedBy("networkStateUpdate")
64     long lastDispatchedProcStateSeq;
65 
66     /**
67      * Indicates if any thread is waiting for network rules to get updated for {@link #uid}.
68      */
69     volatile boolean waitingForNetwork;
70 
71     /**
72      * Indicates whether this uid has internet permission or not.
73      */
74     volatile boolean hasInternetPermission;
75 
76     /**
77      * This object is used for waiting for the network state to get updated.
78      */
79     final Object networkStateLock = new Object();
80 
81     static final int CHANGE_PROCSTATE = 0;
82     static final int CHANGE_GONE = 1;
83     static final int CHANGE_GONE_IDLE = 2;
84     static final int CHANGE_IDLE = 3;
85     static final int CHANGE_ACTIVE = 4;
86 
87     static final class ChangeItem {
88         UidRecord uidRecord;
89         int uid;
90         int change;
91         int processState;
92         boolean ephemeral;
93         long procStateSeq;
94     }
95 
96     ChangeItem pendingChange;
97 
UidRecord(int _uid)98     public UidRecord(int _uid) {
99         uid = _uid;
100         idle = true;
101         reset();
102     }
103 
reset()104     public void reset() {
105         curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
106         foregroundServices = false;
107     }
108 
updateHasInternetPermission()109     public void updateHasInternetPermission() {
110         hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET,
111                 uid) == PackageManager.PERMISSION_GRANTED;
112     }
113 
114     /**
115      * If the change being dispatched is neither CHANGE_GONE nor CHANGE_GONE_IDLE (not interested in
116      * these changes), then update the {@link #lastDispatchedProcStateSeq} with
117      * {@link #curProcStateSeq}.
118      */
updateLastDispatchedProcStateSeq(int changeToDispatch)119     public void updateLastDispatchedProcStateSeq(int changeToDispatch) {
120         if (changeToDispatch != CHANGE_GONE && changeToDispatch != CHANGE_GONE_IDLE) {
121             lastDispatchedProcStateSeq = curProcStateSeq;
122         }
123     }
124 
toString()125     public String toString() {
126         StringBuilder sb = new StringBuilder(128);
127         sb.append("UidRecord{");
128         sb.append(Integer.toHexString(System.identityHashCode(this)));
129         sb.append(' ');
130         UserHandle.formatUid(sb, uid);
131         sb.append(' ');
132         sb.append(ProcessList.makeProcStateString(curProcState));
133         if (ephemeral) {
134             sb.append(" ephemeral");
135         }
136         if (foregroundServices) {
137             sb.append(" fgServices");
138         }
139         if (curWhitelist) {
140             sb.append(" whitelist");
141         }
142         if (lastBackgroundTime > 0) {
143             sb.append(" bg:");
144             TimeUtils.formatDuration(SystemClock.elapsedRealtime()-lastBackgroundTime, sb);
145         }
146         if (idle) {
147             sb.append(" idle");
148         }
149         sb.append(" procs:");
150         sb.append(numProcs);
151         sb.append(" seq(");
152         sb.append(curProcStateSeq);
153         sb.append(",");
154         sb.append(lastNetworkUpdatedProcStateSeq);
155         sb.append(",");
156         sb.append(lastDispatchedProcStateSeq);
157         sb.append(")}");
158         return sb.toString();
159     }
160 }
161