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
17package com.android.server.am;
18
19import android.Manifest;
20import android.app.ActivityManager;
21import android.content.pm.PackageManager;
22import android.os.SystemClock;
23import android.os.UserHandle;
24import android.util.TimeUtils;
25
26import com.android.internal.annotations.GuardedBy;
27import com.android.internal.annotations.VisibleForTesting;
28
29/**
30 * Overall information about a uid that has actively running processes.
31 */
32public 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
98    public UidRecord(int _uid) {
99        uid = _uid;
100        idle = true;
101        reset();
102    }
103
104    public void reset() {
105        curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
106        foregroundServices = false;
107    }
108
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     */
119    public void updateLastDispatchedProcStateSeq(int changeToDispatch) {
120        if (changeToDispatch != CHANGE_GONE && changeToDispatch != CHANGE_GONE_IDLE) {
121            lastDispatchedProcStateSeq = curProcStateSeq;
122        }
123    }
124
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