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 android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.ServiceConnection;
23 import android.os.IBinder;
24 import android.os.Process;
25 import android.test.AndroidTestCase;
26 import android.util.Log;
27 
28 public class ProcessTest extends AndroidTestCase {
29 
30     public static final int THREAD_PRIORITY_HIGHEST = -20;
31     private static final String NONE_EXISITENT_NAME = "abcdefcg";
32     private static final String WRONG_CACHE_NAME = "cache_abcdefg";
33     private static final String PROCESS_SHELL= "shell";
34     private static final String PROCESS_CACHE= "cache";
35     private static final String REMOTE_SERVICE = "android.app.REMOTESERVICE";
36     private static final String TAG = "ProcessTest";
37     private ISecondary mSecondaryService = null;
38     private Intent mIntent;
39     private Object mSync;
40     private boolean mHasConnected;
41     private boolean mHasDisconnected;
42     private ServiceConnection mSecondaryConnection;
43 
44     @Override
setUp()45     protected void setUp() throws Exception {
46         super.setUp();
47         mSync = new Object();
48         mSecondaryConnection = new ServiceConnection() {
49             public void onServiceConnected(ComponentName className,
50                     IBinder service) {
51                 // Connecting to a secondary interface is the same as any
52                 // other interface.
53                 android.util.Log.d(TAG, "connected");
54                 mSecondaryService = ISecondary.Stub.asInterface(service);
55                 synchronized (mSync) {
56                     mHasConnected = true;
57                     mSync.notify();
58                 }
59             }
60             public void onServiceDisconnected(ComponentName className) {
61                 Log.d(TAG, "disconnected");
62                 mSecondaryService = null;
63                 synchronized (mSync) {
64                     mHasDisconnected = true;
65                     mSync.notify();
66                 }
67             }
68         };
69         mIntent = new Intent(REMOTE_SERVICE);
70         mIntent.setPackage(getContext().getPackageName());
71         getContext().startService(mIntent);
72 
73         Intent secondaryIntent = new Intent(ISecondary.class.getName());
74         secondaryIntent.setPackage(getContext().getPackageName());
75         getContext().bindService(secondaryIntent, mSecondaryConnection,
76                 Context.BIND_AUTO_CREATE);
77         synchronized (mSync) {
78             if (!mHasConnected) {
79                 try {
80                     mSync.wait();
81                 } catch (InterruptedException e) {
82                 }
83             }
84         }
85     }
86 
87     @Override
tearDown()88     protected void tearDown() throws Exception {
89         super.tearDown();
90         if (mIntent != null) {
91             getContext().stopService(mIntent);
92         }
93         if (mSecondaryConnection != null) {
94             getContext().unbindService(mSecondaryConnection);
95         }
96     }
97 
testMiscMethods()98     public void testMiscMethods() {
99         /*
100          * Test setThreadPriority(int) and setThreadPriority(int, int)
101          * 1.Set the priority of the calling thread, based on Linux priorities level,
102          * from -20 for highest scheduling priority to 19 for lowest scheduling priority.
103          * 2.Throws IllegalArgumentException if tid does not exist.
104          */
105         int myTid = Process.myTid();
106 
107         int priority = Process.getThreadPriority(myTid);
108         assertTrue(priority >= THREAD_PRIORITY_HIGHEST
109                 && priority <= Process.THREAD_PRIORITY_LOWEST);
110 
111         Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
112         assertEquals(Process.THREAD_PRIORITY_AUDIO, Process.getThreadPriority(myTid));
113 
114         Process.setThreadPriority(myTid, Process.THREAD_PRIORITY_LOWEST);
115         assertEquals(Process.THREAD_PRIORITY_LOWEST, Process.getThreadPriority(myTid));
116 
117         Process.setThreadPriority(myTid, THREAD_PRIORITY_HIGHEST);
118         assertEquals(THREAD_PRIORITY_HIGHEST, Process.getThreadPriority(myTid));
119 
120         int invalidPriority = THREAD_PRIORITY_HIGHEST - 1;
121         Process.setThreadPriority(myTid, invalidPriority);
122         assertEquals(THREAD_PRIORITY_HIGHEST, Process.getThreadPriority(myTid));
123 
124         try {
125             Process.setThreadPriority(-1, Process.THREAD_PRIORITY_DEFAULT);
126             fail("Should throw IllegalArgumentException");
127         } catch (IllegalArgumentException e) {
128             // expect
129         } // Hard to address logic of throws SecurityException
130 
131         /*
132          * Returns the UID assigned to a particular user name, or -1 if there is
133          * none.  If the given string consists of only numbers, it is converted
134          * directly to a uid.
135          */
136         assertTrue(Process.getUidForName(PROCESS_SHELL) > 0);
137         assertEquals(-1, Process.getUidForName(NONE_EXISITENT_NAME));
138         assertEquals(0, Process.getUidForName("0"));
139 
140         /*
141          * Returns the GID assigned to a particular user name, or -1 if there is
142          * none.  If the given string consists of only numbers, it is converted
143          * directly to a gid.
144          */
145         assertTrue(Process.getGidForName(PROCESS_CACHE) > 0);
146         assertEquals(-1, Process.getGidForName(WRONG_CACHE_NAME));
147         assertEquals(0, Process.getGidForName("0"));
148 
149         assertTrue(Process.myUid() >= 0);
150     }
151 
152     /**
153      * Test point of killProcess(int)
154      * Only the process running the caller's packages/application
155      * and any additional processes created by that app be able to kill each other's processes.
156      */
testKillProcess()157     public void testKillProcess() throws Exception {
158         long time = 0;
159         int servicePid = 0;
160         try {
161             servicePid = mSecondaryService.getPid();
162             time = mSecondaryService.getElapsedCpuTime();
163         } finally {
164             getContext().stopService(mIntent);
165             mIntent = null;
166         }
167 
168         assertTrue(time > 0);
169         assertTrue(servicePid != Process.myPid());
170 
171         Process.killProcess(servicePid);
172         synchronized (mSync) {
173             if (!mHasDisconnected) {
174                 try {
175                     mSync.wait();
176                 } catch (InterruptedException e) {
177                 }
178             }
179         }
180         assertTrue(mHasDisconnected);
181     }
182 
183     /**
184      * Test myPid() point.
185      * Returns the identifier of this process, which can be used with
186      * {@link #killProcess} and {@link #sendSignal}.
187      * Test sendSignal(int) point.
188      * Send a signal to the given process.
189      */
testSendSignal()190     public void testSendSignal() throws Exception {
191         int servicePid = 0;
192         try {
193             servicePid = mSecondaryService.getPid();
194         } finally {
195             getContext().stopService(mIntent);
196             mIntent = null;
197         }
198         assertTrue(servicePid != 0);
199         assertTrue(Process.myPid() != servicePid);
200         Process.sendSignal(servicePid, Process.SIGNAL_KILL);
201         synchronized (mSync) {
202             if (!mHasDisconnected) {
203                 try {
204                     mSync.wait();
205                 } catch (InterruptedException e) {
206                 }
207             }
208         }
209         assertTrue(mHasDisconnected);
210     }
211 }
212