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 com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.verify;
27 
28 import android.os.UserHandle;
29 import android.platform.test.annotations.Presubmit;
30 import android.util.ArraySet;
31 
32 import androidx.test.filters.SmallTest;
33 
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 
38 /**
39  * Tests for the {@link WindowProcessControllerMap} class.
40  *
41  * Build/Install/Run:
42  *  atest WmTests:WindowProcessControllerMapTests
43  */
44 @SmallTest
45 @Presubmit
46 @RunWith(WindowTestRunner.class)
47 public class WindowProcessControllerMapTests extends WindowTestsBase {
48 
49     private static final int FAKE_UID1 = 666;
50     private static final int FAKE_UID2 = 667;
51     private static final int FAKE_PID1 = 668;
52     private static final int FAKE_PID2 = 669;
53     private static final int FAKE_PID3 = 670;
54     private static final int FAKE_PID4 = 671;
55 
56     private WindowProcessControllerMap mProcessMap;
57     private WindowProcessController pid1uid1;
58     private WindowProcessController pid1uid2;
59     private WindowProcessController pid2uid1;
60     private WindowProcessController pid3uid1;
61     private WindowProcessController pid4uid2;
62 
63     @Before
setUp()64     public void setUp() throws Exception {
65         mProcessMap = new WindowProcessControllerMap();
66         pid1uid1 = new WindowProcessController(
67                 mAtm, mAtm.mContext.getApplicationInfo(), "fakepid1fakeuid1", FAKE_UID1,
68                 UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
69         pid1uid1.setPid(FAKE_PID1);
70         pid1uid2 = new WindowProcessController(
71                 mAtm, mAtm.mContext.getApplicationInfo(), "fakepid1fakeuid2", FAKE_UID2,
72                 UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
73         pid1uid2.setPid(FAKE_PID1);
74         pid2uid1 = new WindowProcessController(
75                 mAtm, mAtm.mContext.getApplicationInfo(), "fakepid2fakeuid1", FAKE_UID1,
76                 UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
77         pid2uid1.setPid(FAKE_PID2);
78         pid3uid1 = new WindowProcessController(
79                 mAtm, mAtm.mContext.getApplicationInfo(), "fakepid3fakeuid1", FAKE_UID1,
80                 UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
81         pid3uid1.setPid(FAKE_PID3);
82         pid4uid2 = new WindowProcessController(
83                 mAtm, mAtm.mContext.getApplicationInfo(), "fakepid4fakeuid2", FAKE_UID2,
84                 UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
85         pid4uid2.setPid(FAKE_PID4);
86     }
87 
88     @Test
testAdditionsAndRemovals()89     public void testAdditionsAndRemovals() {
90         // test various additions and removals
91         mProcessMap.put(FAKE_PID1, pid1uid1);
92         mProcessMap.put(FAKE_PID2, pid2uid1);
93         assertEquals(pid1uid1, mProcessMap.getProcess(FAKE_PID1));
94         assertEquals(pid2uid1, mProcessMap.getProcess(FAKE_PID2));
95         ArraySet<WindowProcessController> uid1processes = mProcessMap.getProcesses(FAKE_UID1);
96         assertTrue(uid1processes.contains(pid1uid1));
97         assertTrue(uid1processes.contains(pid2uid1));
98         assertEquals(uid1processes.size(), 2);
99 
100         mProcessMap.remove(FAKE_PID2);
101         mProcessMap.put(FAKE_PID3, pid3uid1);
102         uid1processes = mProcessMap.getProcesses(FAKE_UID1);
103         assertTrue(uid1processes.contains(pid1uid1));
104         assertFalse(uid1processes.contains(pid2uid1));
105         assertTrue(uid1processes.contains(pid3uid1));
106         assertEquals(uid1processes.size(), 2);
107 
108         mProcessMap.put(FAKE_PID4, pid4uid2);
109         ArraySet<WindowProcessController> uid2processes = mProcessMap.getProcesses(FAKE_UID2);
110         assertTrue(uid2processes.contains(pid4uid2));
111         assertEquals(uid2processes.size(), 1);
112 
113         mProcessMap.remove(FAKE_PID1);
114         mProcessMap.remove(FAKE_PID3);
115         assertNull(mProcessMap.getProcesses(FAKE_UID1));
116         assertEquals(mProcessMap.getProcess(FAKE_PID4), pid4uid2);
117     }
118 
119     @Test
testReplacement()120     public void testReplacement() {
121         // test that replacing a process is handled correctly
122         mProcessMap.put(FAKE_PID1, pid1uid1);
123         ArraySet<WindowProcessController> uid1processes = mProcessMap.getProcesses(FAKE_UID1);
124         assertTrue(uid1processes.contains(pid1uid1));
125         assertEquals(uid1processes.size(), 1);
126 
127         mProcessMap.put(FAKE_PID1, pid1uid2);
128         assertNull(mProcessMap.getProcesses(FAKE_UID1));
129         ArraySet<WindowProcessController> uid2processes = mProcessMap.getProcesses(FAKE_UID2);
130         assertTrue(uid2processes.contains(pid1uid2));
131         assertEquals(uid2processes.size(), 1);
132         assertEquals(mProcessMap.getProcess(FAKE_PID1), pid1uid2);
133     }
134 
135     @Test
testRemove_callsDestroy()136     public void testRemove_callsDestroy() {
137         var proc = spy(pid1uid1);
138         mProcessMap.put(FAKE_PID1, proc);
139 
140         mProcessMap.remove(FAKE_PID1);
141 
142         verify(proc).destroy();
143     }
144 }
145