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.SparseIntArray; 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 /** Uid -> process state. */ 33 private final SparseIntArray mUidStates = new SparseIntArray(); 34 35 /** Uid -> number of non-app visible windows belong to the uid. */ 36 private final SparseIntArray mNumNonAppVisibleWindowMap = new SparseIntArray(); 37 onUidActive(int uid, int procState)38 synchronized void onUidActive(int uid, int procState) { 39 mUidStates.put(uid, procState); 40 } 41 onUidInactive(int uid)42 synchronized void onUidInactive(int uid) { 43 mUidStates.delete(uid); 44 } 45 onUidProcStateChanged(int uid, int procState)46 synchronized void onUidProcStateChanged(int uid, int procState) { 47 final int index = mUidStates.indexOfKey(uid); 48 if (index >= 0) { 49 mUidStates.setValueAt(index, procState); 50 } 51 } 52 getUidState(int uid)53 synchronized @ProcessState int getUidState(int uid) { 54 return mUidStates.get(uid, PROCESS_STATE_NONEXISTENT); 55 } 56 57 /** Called when the surface of non-application (exclude toast) window is shown or hidden. */ onNonAppSurfaceVisibilityChanged(int uid, boolean visible)58 synchronized void onNonAppSurfaceVisibilityChanged(int uid, boolean visible) { 59 final int index = mNumNonAppVisibleWindowMap.indexOfKey(uid); 60 if (index >= 0) { 61 final int num = mNumNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1); 62 if (num > 0) { 63 mNumNonAppVisibleWindowMap.setValueAt(index, num); 64 } else { 65 mNumNonAppVisibleWindowMap.removeAt(index); 66 } 67 } else if (visible) { 68 mNumNonAppVisibleWindowMap.append(uid, 1); 69 } 70 } 71 72 /** 73 * Returns {@code true} if the uid has any non-application (exclude toast) window currently 74 * visible to the user. The application window visibility of a uid can be found from 75 * {@link VisibleActivityProcessTracker}. 76 */ hasNonAppVisibleWindow(int uid)77 synchronized boolean hasNonAppVisibleWindow(int uid) { 78 return mNumNonAppVisibleWindowMap.get(uid) > 0; 79 } 80 dump(PrintWriter pw, String prefix)81 synchronized void dump(PrintWriter pw, String prefix) { 82 pw.print(prefix + "NumNonAppVisibleWindowUidMap:["); 83 for (int i = mNumNonAppVisibleWindowMap.size() - 1; i >= 0; i--) { 84 pw.print(" " + mNumNonAppVisibleWindowMap.keyAt(i) + ":" 85 + mNumNonAppVisibleWindowMap.valueAt(i)); 86 } 87 pw.println("]"); 88 } 89 } 90