Home | History | Annotate | Download | only in am
      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     boolean setIdle;
     43     int numProcs;
     44 
     45     /**
     46      * Sequence number associated with the {@link #curProcState}. This is incremented using
     47      * {@link ActivityManagerService#mProcStateSeqCounter}
     48      * when {@link #curProcState} changes from background to foreground or vice versa.
     49      */
     50     @GuardedBy("networkStateUpdate")
     51     long curProcStateSeq;
     52 
     53     /**
     54      * Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that
     55      * network policies rules were updated.
     56      */
     57     @GuardedBy("networkStateUpdate")
     58     long lastNetworkUpdatedProcStateSeq;
     59 
     60     /**
     61      * Last seq number for which AcitivityManagerService dispatched uid state change to
     62      * NetworkPolicyManagerService.
     63      */
     64     @GuardedBy("networkStateUpdate")
     65     long lastDispatchedProcStateSeq;
     66 
     67     /**
     68      * Indicates if any thread is waiting for network rules to get updated for {@link #uid}.
     69      */
     70     volatile boolean waitingForNetwork;
     71 
     72     /**
     73      * Indicates whether this uid has internet permission or not.
     74      */
     75     volatile boolean hasInternetPermission;
     76 
     77     /**
     78      * This object is used for waiting for the network state to get updated.
     79      */
     80     final Object networkStateLock = new Object();
     81 
     82     static final int CHANGE_PROCSTATE = 0;
     83     static final int CHANGE_GONE = 1<<0;
     84     static final int CHANGE_IDLE = 1<<1;
     85     static final int CHANGE_ACTIVE = 1<<2;
     86     static final int CHANGE_CACHED = 1<<3;
     87     static final int CHANGE_UNCACHED = 1<<4;
     88 
     89     static final class ChangeItem {
     90         UidRecord uidRecord;
     91         int uid;
     92         int change;
     93         int processState;
     94         boolean ephemeral;
     95         long procStateSeq;
     96     }
     97 
     98     ChangeItem pendingChange;
     99     int lastReportedChange;
    100 
    101     public UidRecord(int _uid) {
    102         uid = _uid;
    103         idle = true;
    104         reset();
    105     }
    106 
    107     public void reset() {
    108         curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
    109         foregroundServices = false;
    110     }
    111 
    112     public void updateHasInternetPermission() {
    113         hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET,
    114                 uid) == PackageManager.PERMISSION_GRANTED;
    115     }
    116 
    117     /**
    118      * If the change being dispatched is not CHANGE_GONE (not interested in
    119      * these changes), then update the {@link #lastDispatchedProcStateSeq} with
    120      * {@link #curProcStateSeq}.
    121      */
    122     public void updateLastDispatchedProcStateSeq(int changeToDispatch) {
    123         if ((changeToDispatch & CHANGE_GONE) == 0) {
    124             lastDispatchedProcStateSeq = curProcStateSeq;
    125         }
    126     }
    127 
    128     public String toString() {
    129         StringBuilder sb = new StringBuilder(128);
    130         sb.append("UidRecord{");
    131         sb.append(Integer.toHexString(System.identityHashCode(this)));
    132         sb.append(' ');
    133         UserHandle.formatUid(sb, uid);
    134         sb.append(' ');
    135         sb.append(ProcessList.makeProcStateString(curProcState));
    136         if (ephemeral) {
    137             sb.append(" ephemeral");
    138         }
    139         if (foregroundServices) {
    140             sb.append(" fgServices");
    141         }
    142         if (curWhitelist) {
    143             sb.append(" whitelist");
    144         }
    145         if (lastBackgroundTime > 0) {
    146             sb.append(" bg:");
    147             TimeUtils.formatDuration(SystemClock.elapsedRealtime()-lastBackgroundTime, sb);
    148         }
    149         if (idle) {
    150             sb.append(" idle");
    151         }
    152         if (lastReportedChange != 0) {
    153             sb.append(" change:");
    154             boolean printed = false;
    155             if ((lastReportedChange & CHANGE_GONE) != 0) {
    156                 printed = true;
    157                 sb.append("gone");
    158             }
    159             if ((lastReportedChange & CHANGE_IDLE) != 0) {
    160                 if (printed) {
    161                     sb.append("|");
    162                 }
    163                 printed = true;
    164                 sb.append("idle");
    165             }
    166             if ((lastReportedChange & CHANGE_ACTIVE) != 0) {
    167                 if (printed) {
    168                     sb.append("|");
    169                 }
    170                 printed = true;
    171                 sb.append("active");
    172             }
    173             if ((lastReportedChange & CHANGE_CACHED) != 0) {
    174                 if (printed) {
    175                     sb.append("|");
    176                 }
    177                 printed = true;
    178                 sb.append("cached");
    179             }
    180             if ((lastReportedChange & CHANGE_UNCACHED) != 0) {
    181                 if (printed) {
    182                     sb.append("|");
    183                 }
    184                 sb.append("uncached");
    185             }
    186         }
    187         sb.append(" procs:");
    188         sb.append(numProcs);
    189         sb.append(" seq(");
    190         sb.append(curProcStateSeq);
    191         sb.append(",");
    192         sb.append(lastNetworkUpdatedProcStateSeq);
    193         sb.append(",");
    194         sb.append(lastDispatchedProcStateSeq);
    195         sb.append(")}");
    196         return sb.toString();
    197     }
    198 }
    199