1 /* 2 * Copyright (C) 2019 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.wm; 18 19 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 20 21 import android.app.ActivityManager.ProcessState; 22 import android.util.SparseArray; 23 24 import java.io.PrintWriter; 25 26 /** 27 * This is a partial mirror of {@link @com.android.server.am.ActiveUids}. It is already thread 28 * safe so the heavy service lock is not needed when updating state from activity manager (oom 29 * adjustment) or getting state from window manager (background start check). 30 */ 31 class MirrorActiveUids { 32 private final SparseArray<UidRecord> mUidStates = new SparseArray<>(); 33 onUidActive(int uid, int procState)34 synchronized void onUidActive(int uid, int procState) { 35 UidRecord r = mUidStates.get(uid); 36 if (r == null) { 37 r = new UidRecord(); 38 mUidStates.put(uid, r); 39 } 40 r.mProcState = procState; 41 } 42 onUidInactive(int uid)43 synchronized void onUidInactive(int uid) { 44 mUidStates.delete(uid); 45 } 46 onUidProcStateChanged(int uid, int procState)47 synchronized void onUidProcStateChanged(int uid, int procState) { 48 final UidRecord r = mUidStates.get(uid); 49 if (r != null) { 50 r.mProcState = procState; 51 } 52 } 53 getUidState(int uid)54 synchronized @ProcessState int getUidState(int uid) { 55 final UidRecord r = mUidStates.get(uid); 56 return r != null ? r.mProcState : PROCESS_STATE_NONEXISTENT; 57 } 58 59 /** Called when the surface of non-application (exclude toast) window is shown or hidden. */ onNonAppSurfaceVisibilityChanged(int uid, boolean visible)60 synchronized void onNonAppSurfaceVisibilityChanged(int uid, boolean visible) { 61 final UidRecord r = mUidStates.get(uid); 62 if (r != null) { 63 r.mNumNonAppVisibleWindow += visible ? 1 : -1; 64 } 65 } 66 67 /** 68 * Returns {@code true} if the uid has any non-application (exclude toast) window currently 69 * visible to the user. The application window visibility of a uid can be found from 70 * {@link VisibleActivityProcessTracker}. 71 */ hasNonAppVisibleWindow(int uid)72 synchronized boolean hasNonAppVisibleWindow(int uid) { 73 final UidRecord r = mUidStates.get(uid); 74 return r != null && r.mNumNonAppVisibleWindow > 0; 75 } 76 dump(PrintWriter pw, String prefix)77 synchronized void dump(PrintWriter pw, String prefix) { 78 pw.print(prefix + "NumNonAppVisibleWindowByUid:["); 79 for (int i = mUidStates.size() - 1; i >= 0; i--) { 80 final UidRecord r = mUidStates.valueAt(i); 81 if (r.mNumNonAppVisibleWindow > 0) { 82 pw.print(" " + mUidStates.keyAt(i) + ":" + r.mNumNonAppVisibleWindow); 83 } 84 } 85 pw.println("]"); 86 } 87 88 private static final class UidRecord { 89 @ProcessState int mProcState; 90 int mNumNonAppVisibleWindow; 91 } 92 } 93