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 android.util.ArraySet;
20 import android.util.SparseArray;
21 
22 import java.util.Map;
23 import java.util.HashMap;
24 
25 final class WindowProcessControllerMap {
26 
27     /** All processes we currently have running mapped by pid */
28     private final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
29     /** All processes we currently have running mapped by uid */
30     private final Map<Integer, ArraySet<WindowProcessController>> mUidMap = new HashMap<>();
31 
32     /** Retrieves a currently running process for pid. */
getProcess(int pid)33     WindowProcessController getProcess(int pid) {
34         return mPidMap.get(pid);
35     }
36 
37     /** Retrieves all currently running processes for uid. */
getProcesses(int uid)38     ArraySet<WindowProcessController> getProcesses(int uid) {
39         return mUidMap.get(uid);
40     }
41 
getPidMap()42     SparseArray<WindowProcessController> getPidMap() {
43         return mPidMap;
44     }
45 
put(int pid, WindowProcessController proc)46     void put(int pid, WindowProcessController proc) {
47         // if there is a process for this pid already in mPidMap it'll get replaced automagically,
48         // but we actually need to remove it from mUidMap too before adding the new one
49         final WindowProcessController prevProc = mPidMap.get(pid);
50         if (prevProc != null) {
51             removeProcessFromUidMap(prevProc);
52         }
53         // put process into mPidMap
54         mPidMap.put(pid, proc);
55         // put process into mUidMap
56         final int uid = proc.mUid;
57         ArraySet<WindowProcessController> procSet = mUidMap.getOrDefault(uid,
58                 new ArraySet<WindowProcessController>());
59         procSet.add(proc);
60         mUidMap.put(uid, procSet);
61     }
62 
remove(int pid)63     void remove(int pid) {
64         final WindowProcessController proc = mPidMap.get(pid);
65         if (proc != null) {
66             // remove process from mPidMap
67             mPidMap.remove(pid);
68             // remove process from mUidMap
69             removeProcessFromUidMap(proc);
70         }
71     }
72 
removeProcessFromUidMap(WindowProcessController proc)73     private void removeProcessFromUidMap(WindowProcessController proc) {
74         if (proc == null) {
75             return;
76         }
77         final int uid = proc.mUid;
78         ArraySet<WindowProcessController> procSet = mUidMap.get(uid);
79         if (procSet != null) {
80             procSet.remove(proc);
81             if (procSet.isEmpty()) {
82                 mUidMap.remove(uid);
83             }
84         }
85     }
86 }
87