• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 android.os.cts;
18 
19 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotEquals;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27 
28 import android.content.ComponentName;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.ServiceConnection;
32 import android.content.pm.PackageManager;
33 import android.os.IBinder;
34 import android.os.Process;
35 import android.util.Log;
36 
37 import androidx.test.InstrumentationRegistry;
38 
39 import org.junit.After;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.junit.runners.JUnit4;
44 
45 
46 /**
47  * CTS for {@link android.os.Process}.
48  *
49  * We have more test in cts/tests/process/ too.
50  */
51 @RunWith(JUnit4.class)
52 public class ProcessTest {
53 
54     public static final int THREAD_PRIORITY_HIGHEST = -20;
55     private static final String NONE_EXISITENT_NAME = "abcdefcg";
56     private static final String WRONG_CACHE_NAME = "cache_abcdefg";
57     private static final String PROCESS_SHELL= "shell";
58     private static final String PROCESS_CACHE= "cache";
59     private static final String REMOTE_SERVICE = "android.app.REMOTESERVICE";
60     private static final int APP_UID = 10001;
61     private static final int SANDBOX_SDK_UID = 20001;
62     private static final String TAG = "ProcessTest";
63     private ISecondary mSecondaryService = null;
64     private Intent mIntent;
65     private Object mSync;
66     private boolean mHasConnected;
67     private boolean mHasDisconnected;
68     private ServiceConnection mSecondaryConnection;
69     private Context mContext;
70 
71     @Before
setUp()72     public void setUp() throws Exception {
73         mContext = InstrumentationRegistry.getContext();
74         mSync = new Object();
75         mSecondaryConnection = new ServiceConnection() {
76             public void onServiceConnected(ComponentName className,
77                     IBinder service) {
78                 // Connecting to a secondary interface is the same as any
79                 // other interface.
80                 android.util.Log.d(TAG, "connected");
81                 mSecondaryService = ISecondary.Stub.asInterface(service);
82                 synchronized (mSync) {
83                     mHasConnected = true;
84                     mSync.notify();
85                 }
86             }
87             public void onServiceDisconnected(ComponentName className) {
88                 Log.d(TAG, "disconnected");
89                 mSecondaryService = null;
90                 synchronized (mSync) {
91                     mHasDisconnected = true;
92                     mSync.notify();
93                 }
94             }
95         };
96         mIntent = new Intent(REMOTE_SERVICE);
97         mIntent.setPackage(mContext.getPackageName());
98         mContext.startService(mIntent);
99 
100         Intent secondaryIntent = new Intent(ISecondary.class.getName());
101         secondaryIntent.setPackage(mContext.getPackageName());
102         mContext.bindService(secondaryIntent, mSecondaryConnection,
103                 Context.BIND_AUTO_CREATE);
104         synchronized (mSync) {
105             if (!mHasConnected) {
106                 try {
107                     mSync.wait();
108                 } catch (InterruptedException e) {
109                 }
110             }
111         }
112     }
113 
114     @After
tearDown()115     public void tearDown() throws Exception {
116         if (mIntent != null) {
117             mContext.stopService(mIntent);
118         }
119         if (mSecondaryConnection != null) {
120             mContext.unbindService(mSecondaryConnection);
121         }
122     }
123 
124     @Test
testMiscMethods()125     public void testMiscMethods() {
126         /*
127          * Test setThreadPriority(int) and setThreadPriority(int, int)
128          * 1.Set the priority of the calling thread, based on Linux priorities level,
129          * from -20 for highest scheduling priority to 19 for lowest scheduling priority.
130          * 2.Throws IllegalArgumentException if tid does not exist.
131          */
132         int myTid = Process.myTid();
133 
134         int priority = Process.getThreadPriority(myTid);
135         assertTrue(priority >= THREAD_PRIORITY_HIGHEST
136                 && priority <= Process.THREAD_PRIORITY_LOWEST);
137 
138         Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
139         assertEquals(Process.THREAD_PRIORITY_AUDIO, Process.getThreadPriority(myTid));
140 
141         Process.setThreadPriority(myTid, Process.THREAD_PRIORITY_LOWEST);
142         assertEquals(Process.THREAD_PRIORITY_LOWEST, Process.getThreadPriority(myTid));
143 
144         Process.setThreadPriority(myTid, THREAD_PRIORITY_HIGHEST);
145         assertEquals(THREAD_PRIORITY_HIGHEST, Process.getThreadPriority(myTid));
146 
147         int invalidPriority = THREAD_PRIORITY_HIGHEST - 1;
148         Process.setThreadPriority(myTid, invalidPriority);
149         assertEquals(THREAD_PRIORITY_HIGHEST, Process.getThreadPriority(myTid));
150 
151         try {
152             Process.setThreadPriority(-1, Process.THREAD_PRIORITY_DEFAULT);
153             fail("Should throw IllegalArgumentException");
154         } catch (IllegalArgumentException e) {
155             // expect
156         } // Hard to address logic of throws SecurityException
157 
158         /*
159          * Returns the UID assigned to a particular user name, or -1 if there is
160          * none.  If the given string consists of only numbers, it is converted
161          * directly to a uid.
162          */
163         assertTrue(Process.getUidForName(PROCESS_SHELL) > 0);
164         assertEquals(-1, Process.getUidForName(NONE_EXISITENT_NAME));
165         assertEquals(0, Process.getUidForName("0"));
166 
167         /*
168          * Returns the GID assigned to a particular user name, or -1 if there is
169          * none.  If the given string consists of only numbers, it is converted
170          * directly to a gid.
171          */
172         assertTrue(Process.getGidForName(PROCESS_CACHE) > 0);
173         assertEquals(-1, Process.getGidForName(WRONG_CACHE_NAME));
174         assertEquals(0, Process.getGidForName("0"));
175 
176         assertTrue(Process.myUid() >= 0);
177 
178         assertNotEquals(null, Process.getExclusiveCores());
179     }
180 
181     /**
182      * Test point of killProcess(int)
183      * Only the process running the caller's packages/application
184      * and any additional processes created by that app be able to kill each other's processes.
185      */
186     @Test
testKillProcess()187     public void testKillProcess() throws Exception {
188         long time = 0;
189         int servicePid = 0;
190         try {
191             servicePid = mSecondaryService.getPid();
192             time = mSecondaryService.getElapsedCpuTime();
193         } finally {
194             mContext.stopService(mIntent);
195             mIntent = null;
196         }
197 
198         assertTrue(time > 0);
199         assertTrue(servicePid != Process.myPid());
200 
201         Process.killProcess(servicePid);
202         synchronized (mSync) {
203             if (!mHasDisconnected) {
204                 try {
205                     mSync.wait();
206                 } catch (InterruptedException e) {
207                 }
208             }
209         }
210         assertTrue(mHasDisconnected);
211     }
212 
213     /**
214      * Test myPid() point.
215      * Returns the identifier of this process, which can be used with
216      * {@link #killProcess} and {@link #sendSignal}.
217      * Test sendSignal(int) point.
218      * Send a signal to the given process.
219      */
220     @Test
testSendSignal()221     public void testSendSignal() throws Exception {
222         int servicePid = 0;
223         try {
224             servicePid = mSecondaryService.getPid();
225         } finally {
226             mContext.stopService(mIntent);
227             mIntent = null;
228         }
229         assertTrue(servicePid != 0);
230         assertTrue(Process.myPid() != servicePid);
231         Process.sendSignal(servicePid, Process.SIGNAL_KILL);
232         synchronized (mSync) {
233             if (!mHasDisconnected) {
234                 try {
235                     mSync.wait();
236                 } catch (InterruptedException e) {
237                 }
238             }
239         }
240         assertTrue(mHasDisconnected);
241     }
242 
243     /**
244      * Tests APIs related to sdk sandbox uids.
245      */
246     @Test
testSdkSandboxUids()247     public void testSdkSandboxUids() {
248         assertEquals(SANDBOX_SDK_UID, Process.toSdkSandboxUid(APP_UID));
249         assertEquals(APP_UID, Process.getAppUidForSdkSandboxUid(SANDBOX_SDK_UID));
250 
251         assertFalse(Process.isSdkSandboxUid(APP_UID));
252         assertTrue(Process.isSdkSandboxUid(SANDBOX_SDK_UID));
253 
254         assertFalse(Process.isSdkSandbox());
255     }
256 
257     /**
258      * Tests that the reserved UID is not taken by an actual package.
259      */
260     @Test
testReservedVirtualUid()261     public void testReservedVirtualUid() {
262         PackageManager pm = mContext.getPackageManager();
263         final String name = pm.getNameForUid(Process.SDK_SANDBOX_VIRTUAL_UID);
264         assertNull(name);
265 
266         // PackageManager#getPackagesForUid requires android.permission.INTERACT_ACROSS_USERS for
267         // cross-user calls.
268         runWithShellPermissionIdentity(() -> {
269             final String[] packages = pm.getPackagesForUid(Process.SDK_SANDBOX_VIRTUAL_UID);
270             assertNull(packages);
271         });
272     }
273 }
274