• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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;
18 
19 import android.net.LocalSocketAddress;
20 import android.net.LocalSocket;
21 import android.util.Log;
22 import dalvik.system.Zygote;
23 
24 import java.io.BufferedWriter;
25 import java.io.DataInputStream;
26 import java.io.IOException;
27 import java.io.OutputStreamWriter;
28 import java.util.ArrayList;
29 
30 /*package*/ class ZygoteStartFailedEx extends Exception {
31     /**
32      * Something prevented the zygote process startup from happening normally
33      */
34 
ZygoteStartFailedEx()35     ZygoteStartFailedEx() {};
ZygoteStartFailedEx(String s)36     ZygoteStartFailedEx(String s) {super(s);}
ZygoteStartFailedEx(Throwable cause)37     ZygoteStartFailedEx(Throwable cause) {super(cause);}
38 }
39 
40 /**
41  * Tools for managing OS processes.
42  */
43 public class Process {
44     private static final String LOG_TAG = "Process";
45 
46     private static final String ZYGOTE_SOCKET = "zygote";
47 
48     /**
49      * Name of a process for running the platform's media services.
50      * {@hide}
51      */
52     public static final String ANDROID_SHARED_MEDIA = "com.android.process.media";
53 
54     /**
55      * Name of the process that Google content providers can share.
56      * {@hide}
57      */
58     public static final String GOOGLE_SHARED_APP_CONTENT = "com.google.process.content";
59 
60     /**
61      * Defines the UID/GID under which system code runs.
62      */
63     public static final int SYSTEM_UID = 1000;
64 
65     /**
66      * Defines the UID/GID under which the telephony code runs.
67      */
68     public static final int PHONE_UID = 1001;
69 
70     /**
71      * Defines the UID/GID for the user shell.
72      * @hide
73      */
74     public static final int SHELL_UID = 2000;
75 
76     /**
77      * Defines the UID/GID for the log group.
78      * @hide
79      */
80     public static final int LOG_UID = 1007;
81 
82     /**
83      * Defines the UID/GID for the WIFI supplicant process.
84      * @hide
85      */
86     public static final int WIFI_UID = 1010;
87 
88     /**
89      * Defines the UID/GID for the mediaserver process.
90      * @hide
91      */
92     public static final int MEDIA_UID = 1013;
93 
94     /**
95      * Defines the UID/GID for the DRM process.
96      * @hide
97      */
98     public static final int DRM_UID = 1019;
99 
100     /**
101      * Defines the GID for the group that allows write access to the SD card.
102      * @hide
103      */
104     public static final int SDCARD_RW_GID = 1015;
105 
106     /**
107      * Defines the UID/GID for the group that controls VPN services.
108      * @hide
109      */
110     public static final int VPN_UID = 1016;
111 
112     /**
113      * Defines the UID/GID for the NFC service process.
114      * @hide
115      */
116     public static final int NFC_UID = 1027;
117 
118     /**
119      * Defines the UID/GID for the Bluetooth service process.
120      * @hide
121      */
122     public static final int BLUETOOTH_UID = 1002;
123 
124     /**
125      * Defines the GID for the group that allows write access to the internal media storage.
126      * @hide
127      */
128     public static final int MEDIA_RW_GID = 1023;
129 
130     /**
131      * Defines the start of a range of UIDs (and GIDs), going from this
132      * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
133      * to applications.
134      */
135     public static final int FIRST_APPLICATION_UID = 10000;
136     /**
137      * Last of application-specific UIDs starting at
138      * {@link #FIRST_APPLICATION_UID}.
139      */
140     public static final int LAST_APPLICATION_UID = 19999;
141 
142     /**
143      * First uid used for fully isolated sandboxed processes (with no permissions of their own)
144      * @hide
145      */
146     public static final int FIRST_ISOLATED_UID = 99000;
147 
148     /**
149      * Last uid used for fully isolated sandboxed processes (with no permissions of their own)
150      * @hide
151      */
152     public static final int LAST_ISOLATED_UID = 99999;
153 
154     /**
155      * First gid for applications to share resources. Used when forward-locking
156      * is enabled but all UserHandles need to be able to read the resources.
157      * @hide
158      */
159     public static final int FIRST_SHARED_APPLICATION_GID = 50000;
160 
161     /**
162      * Last gid for applications to share resources. Used when forward-locking
163      * is enabled but all UserHandles need to be able to read the resources.
164      * @hide
165      */
166     public static final int LAST_SHARED_APPLICATION_GID = 59999;
167 
168     /**
169      * Standard priority of application threads.
170      * Use with {@link #setThreadPriority(int)} and
171      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
172      * {@link java.lang.Thread} class.
173      */
174     public static final int THREAD_PRIORITY_DEFAULT = 0;
175 
176     /*
177      * ***************************************
178      * ** Keep in sync with utils/threads.h **
179      * ***************************************
180      */
181 
182     /**
183      * Lowest available thread priority.  Only for those who really, really
184      * don't want to run if anything else is happening.
185      * Use with {@link #setThreadPriority(int)} and
186      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
187      * {@link java.lang.Thread} class.
188      */
189     public static final int THREAD_PRIORITY_LOWEST = 19;
190 
191     /**
192      * Standard priority background threads.  This gives your thread a slightly
193      * lower than normal priority, so that it will have less chance of impacting
194      * the responsiveness of the user interface.
195      * Use with {@link #setThreadPriority(int)} and
196      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
197      * {@link java.lang.Thread} class.
198      */
199     public static final int THREAD_PRIORITY_BACKGROUND = 10;
200 
201     /**
202      * Standard priority of threads that are currently running a user interface
203      * that the user is interacting with.  Applications can not normally
204      * change to this priority; the system will automatically adjust your
205      * application threads as the user moves through the UI.
206      * Use with {@link #setThreadPriority(int)} and
207      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
208      * {@link java.lang.Thread} class.
209      */
210     public static final int THREAD_PRIORITY_FOREGROUND = -2;
211 
212     /**
213      * Standard priority of system display threads, involved in updating
214      * the user interface.  Applications can not
215      * normally change to this priority.
216      * Use with {@link #setThreadPriority(int)} and
217      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
218      * {@link java.lang.Thread} class.
219      */
220     public static final int THREAD_PRIORITY_DISPLAY = -4;
221 
222     /**
223      * Standard priority of the most important display threads, for compositing
224      * the screen and retrieving input events.  Applications can not normally
225      * change to this priority.
226      * Use with {@link #setThreadPriority(int)} and
227      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
228      * {@link java.lang.Thread} class.
229      */
230     public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8;
231 
232     /**
233      * Standard priority of audio threads.  Applications can not normally
234      * change to this priority.
235      * Use with {@link #setThreadPriority(int)} and
236      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
237      * {@link java.lang.Thread} class.
238      */
239     public static final int THREAD_PRIORITY_AUDIO = -16;
240 
241     /**
242      * Standard priority of the most important audio threads.
243      * Applications can not normally change to this priority.
244      * Use with {@link #setThreadPriority(int)} and
245      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
246      * {@link java.lang.Thread} class.
247      */
248     public static final int THREAD_PRIORITY_URGENT_AUDIO = -19;
249 
250     /**
251      * Minimum increment to make a priority more favorable.
252      */
253     public static final int THREAD_PRIORITY_MORE_FAVORABLE = -1;
254 
255     /**
256      * Minimum increment to make a priority less favorable.
257      */
258     public static final int THREAD_PRIORITY_LESS_FAVORABLE = +1;
259 
260     /**
261      * Default scheduling policy
262      * @hide
263      */
264     public static final int SCHED_OTHER = 0;
265 
266     /**
267      * First-In First-Out scheduling policy
268      * @hide
269      */
270     public static final int SCHED_FIFO = 1;
271 
272     /**
273      * Round-Robin scheduling policy
274      * @hide
275      */
276     public static final int SCHED_RR = 2;
277 
278     /**
279      * Batch scheduling policy
280      * @hide
281      */
282     public static final int SCHED_BATCH = 3;
283 
284     /**
285      * Idle scheduling policy
286      * @hide
287      */
288     public static final int SCHED_IDLE = 5;
289 
290     // Keep in sync with SP_* constants of enum type SchedPolicy
291     // declared in system/core/include/cutils/sched_policy.h,
292     // except THREAD_GROUP_DEFAULT does not correspond to any SP_* value.
293 
294     /**
295      * Default thread group -
296      * has meaning with setProcessGroup() only, cannot be used with setThreadGroup().
297      * When used with setProcessGroup(), the group of each thread in the process
298      * is conditionally changed based on that thread's current priority, as follows:
299      * threads with priority numerically less than THREAD_PRIORITY_BACKGROUND
300      * are moved to foreground thread group.  All other threads are left unchanged.
301      * @hide
302      */
303     public static final int THREAD_GROUP_DEFAULT = -1;
304 
305     /**
306      * Background thread group - All threads in
307      * this group are scheduled with a reduced share of the CPU.
308      * Value is same as constant SP_BACKGROUND of enum SchedPolicy.
309      * FIXME rename to THREAD_GROUP_BACKGROUND.
310      * @hide
311      */
312     public static final int THREAD_GROUP_BG_NONINTERACTIVE = 0;
313 
314     /**
315      * Foreground thread group - All threads in
316      * this group are scheduled with a normal share of the CPU.
317      * Value is same as constant SP_FOREGROUND of enum SchedPolicy.
318      * Not used at this level.
319      * @hide
320      **/
321     private static final int THREAD_GROUP_FOREGROUND = 1;
322 
323     /**
324      * System thread group.
325      * @hide
326      **/
327     public static final int THREAD_GROUP_SYSTEM = 2;
328 
329     /**
330      * Application audio thread group.
331      * @hide
332      **/
333     public static final int THREAD_GROUP_AUDIO_APP = 3;
334 
335     /**
336      * System audio thread group.
337      * @hide
338      **/
339     public static final int THREAD_GROUP_AUDIO_SYS = 4;
340 
341     public static final int SIGNAL_QUIT = 3;
342     public static final int SIGNAL_KILL = 9;
343     public static final int SIGNAL_USR1 = 10;
344 
345     // State for communicating with zygote process
346 
347     static LocalSocket sZygoteSocket;
348     static DataInputStream sZygoteInputStream;
349     static BufferedWriter sZygoteWriter;
350 
351     /** true if previous zygote open failed */
352     static boolean sPreviousZygoteOpenFailed;
353 
354     /**
355      * Start a new process.
356      *
357      * <p>If processes are enabled, a new process is created and the
358      * static main() function of a <var>processClass</var> is executed there.
359      * The process will continue running after this function returns.
360      *
361      * <p>If processes are not enabled, a new thread in the caller's
362      * process is created and main() of <var>processClass</var> called there.
363      *
364      * <p>The niceName parameter, if not an empty string, is a custom name to
365      * give to the process instead of using processClass.  This allows you to
366      * make easily identifyable processes even if you are using the same base
367      * <var>processClass</var> to start them.
368      *
369      * @param processClass The class to use as the process's main entry
370      *                     point.
371      * @param niceName A more readable name to use for the process.
372      * @param uid The user-id under which the process will run.
373      * @param gid The group-id under which the process will run.
374      * @param gids Additional group-ids associated with the process.
375      * @param debugFlags Additional flags.
376      * @param targetSdkVersion The target SDK version for the app.
377      * @param seInfo null-ok SE Android information for the new process.
378      * @param zygoteArgs Additional arguments to supply to the zygote process.
379      *
380      * @return An object that describes the result of the attempt to start the process.
381      * @throws RuntimeException on fatal start failure
382      *
383      * {@hide}
384      */
start(final String processClass, final String niceName, int uid, int gid, int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String[] zygoteArgs)385     public static final ProcessStartResult start(final String processClass,
386                                   final String niceName,
387                                   int uid, int gid, int[] gids,
388                                   int debugFlags, int mountExternal,
389                                   int targetSdkVersion,
390                                   String seInfo,
391                                   String[] zygoteArgs) {
392         try {
393             return startViaZygote(processClass, niceName, uid, gid, gids,
394                     debugFlags, mountExternal, targetSdkVersion, seInfo, zygoteArgs);
395         } catch (ZygoteStartFailedEx ex) {
396             Log.e(LOG_TAG,
397                     "Starting VM process through Zygote failed");
398             throw new RuntimeException(
399                     "Starting VM process through Zygote failed", ex);
400         }
401     }
402 
403     /** retry interval for opening a zygote socket */
404     static final int ZYGOTE_RETRY_MILLIS = 500;
405 
406     /**
407      * Tries to open socket to Zygote process if not already open. If
408      * already open, does nothing.  May block and retry.
409      */
openZygoteSocketIfNeeded()410     private static void openZygoteSocketIfNeeded()
411             throws ZygoteStartFailedEx {
412 
413         int retryCount;
414 
415         if (sPreviousZygoteOpenFailed) {
416             /*
417              * If we've failed before, expect that we'll fail again and
418              * don't pause for retries.
419              */
420             retryCount = 0;
421         } else {
422             retryCount = 10;
423         }
424 
425         /*
426          * See bug #811181: Sometimes runtime can make it up before zygote.
427          * Really, we'd like to do something better to avoid this condition,
428          * but for now just wait a bit...
429          */
430         for (int retry = 0
431                 ; (sZygoteSocket == null) && (retry < (retryCount + 1))
432                 ; retry++ ) {
433 
434             if (retry > 0) {
435                 try {
436                     Log.i("Zygote", "Zygote not up yet, sleeping...");
437                     Thread.sleep(ZYGOTE_RETRY_MILLIS);
438                 } catch (InterruptedException ex) {
439                     // should never happen
440                 }
441             }
442 
443             try {
444                 sZygoteSocket = new LocalSocket();
445 
446                 sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,
447                         LocalSocketAddress.Namespace.RESERVED));
448 
449                 sZygoteInputStream
450                         = new DataInputStream(sZygoteSocket.getInputStream());
451 
452                 sZygoteWriter =
453                     new BufferedWriter(
454                             new OutputStreamWriter(
455                                     sZygoteSocket.getOutputStream()),
456                             256);
457 
458                 Log.i("Zygote", "Process: zygote socket opened");
459 
460                 sPreviousZygoteOpenFailed = false;
461                 break;
462             } catch (IOException ex) {
463                 if (sZygoteSocket != null) {
464                     try {
465                         sZygoteSocket.close();
466                     } catch (IOException ex2) {
467                         Log.e(LOG_TAG,"I/O exception on close after exception",
468                                 ex2);
469                     }
470                 }
471 
472                 sZygoteSocket = null;
473             }
474         }
475 
476         if (sZygoteSocket == null) {
477             sPreviousZygoteOpenFailed = true;
478             throw new ZygoteStartFailedEx("connect failed");
479         }
480     }
481 
482     /**
483      * Sends an argument list to the zygote process, which starts a new child
484      * and returns the child's pid. Please note: the present implementation
485      * replaces newlines in the argument list with spaces.
486      * @param args argument list
487      * @return An object that describes the result of the attempt to start the process.
488      * @throws ZygoteStartFailedEx if process start failed for any reason
489      */
zygoteSendArgsAndGetResult(ArrayList<String> args)490     private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)
491             throws ZygoteStartFailedEx {
492         openZygoteSocketIfNeeded();
493 
494         try {
495             /**
496              * See com.android.internal.os.ZygoteInit.readArgumentList()
497              * Presently the wire format to the zygote process is:
498              * a) a count of arguments (argc, in essence)
499              * b) a number of newline-separated argument strings equal to count
500              *
501              * After the zygote process reads these it will write the pid of
502              * the child or -1 on failure, followed by boolean to
503              * indicate whether a wrapper process was used.
504              */
505 
506             sZygoteWriter.write(Integer.toString(args.size()));
507             sZygoteWriter.newLine();
508 
509             int sz = args.size();
510             for (int i = 0; i < sz; i++) {
511                 String arg = args.get(i);
512                 if (arg.indexOf('\n') >= 0) {
513                     throw new ZygoteStartFailedEx(
514                             "embedded newlines not allowed");
515                 }
516                 sZygoteWriter.write(arg);
517                 sZygoteWriter.newLine();
518             }
519 
520             sZygoteWriter.flush();
521 
522             // Should there be a timeout on this?
523             ProcessStartResult result = new ProcessStartResult();
524             result.pid = sZygoteInputStream.readInt();
525             if (result.pid < 0) {
526                 throw new ZygoteStartFailedEx("fork() failed");
527             }
528             result.usingWrapper = sZygoteInputStream.readBoolean();
529             return result;
530         } catch (IOException ex) {
531             try {
532                 if (sZygoteSocket != null) {
533                     sZygoteSocket.close();
534                 }
535             } catch (IOException ex2) {
536                 // we're going to fail anyway
537                 Log.e(LOG_TAG,"I/O exception on routine close", ex2);
538             }
539 
540             sZygoteSocket = null;
541 
542             throw new ZygoteStartFailedEx(ex);
543         }
544     }
545 
546     /**
547      * Starts a new process via the zygote mechanism.
548      *
549      * @param processClass Class name whose static main() to run
550      * @param niceName 'nice' process name to appear in ps
551      * @param uid a POSIX uid that the new process should setuid() to
552      * @param gid a POSIX gid that the new process shuold setgid() to
553      * @param gids null-ok; a list of supplementary group IDs that the
554      * new process should setgroup() to.
555      * @param debugFlags Additional flags.
556      * @param targetSdkVersion The target SDK version for the app.
557      * @param seInfo null-ok SE Android information for the new process.
558      * @param extraArgs Additional arguments to supply to the zygote process.
559      * @return An object that describes the result of the attempt to start the process.
560      * @throws ZygoteStartFailedEx if process start failed for any reason
561      */
startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String[] extraArgs)562     private static ProcessStartResult startViaZygote(final String processClass,
563                                   final String niceName,
564                                   final int uid, final int gid,
565                                   final int[] gids,
566                                   int debugFlags, int mountExternal,
567                                   int targetSdkVersion,
568                                   String seInfo,
569                                   String[] extraArgs)
570                                   throws ZygoteStartFailedEx {
571         synchronized(Process.class) {
572             ArrayList<String> argsForZygote = new ArrayList<String>();
573 
574             // --runtime-init, --setuid=, --setgid=,
575             // and --setgroups= must go first
576             argsForZygote.add("--runtime-init");
577             argsForZygote.add("--setuid=" + uid);
578             argsForZygote.add("--setgid=" + gid);
579             if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
580                 argsForZygote.add("--enable-jni-logging");
581             }
582             if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
583                 argsForZygote.add("--enable-safemode");
584             }
585             if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
586                 argsForZygote.add("--enable-debugger");
587             }
588             if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
589                 argsForZygote.add("--enable-checkjni");
590             }
591             if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
592                 argsForZygote.add("--enable-assert");
593             }
594             if (mountExternal == Zygote.MOUNT_EXTERNAL_MULTIUSER) {
595                 argsForZygote.add("--mount-external-multiuser");
596             } else if (mountExternal == Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL) {
597                 argsForZygote.add("--mount-external-multiuser-all");
598             }
599             argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
600 
601             //TODO optionally enable debuger
602             //argsForZygote.add("--enable-debugger");
603 
604             // --setgroups is a comma-separated list
605             if (gids != null && gids.length > 0) {
606                 StringBuilder sb = new StringBuilder();
607                 sb.append("--setgroups=");
608 
609                 int sz = gids.length;
610                 for (int i = 0; i < sz; i++) {
611                     if (i != 0) {
612                         sb.append(',');
613                     }
614                     sb.append(gids[i]);
615                 }
616 
617                 argsForZygote.add(sb.toString());
618             }
619 
620             if (niceName != null) {
621                 argsForZygote.add("--nice-name=" + niceName);
622             }
623 
624             if (seInfo != null) {
625                 argsForZygote.add("--seinfo=" + seInfo);
626             }
627 
628             argsForZygote.add(processClass);
629 
630             if (extraArgs != null) {
631                 for (String arg : extraArgs) {
632                     argsForZygote.add(arg);
633                 }
634             }
635 
636             return zygoteSendArgsAndGetResult(argsForZygote);
637         }
638     }
639 
640     /**
641      * Returns elapsed milliseconds of the time this process has run.
642      * @return  Returns the number of milliseconds this process has return.
643      */
getElapsedCpuTime()644     public static final native long getElapsedCpuTime();
645 
646     /**
647      * Returns the identifier of this process, which can be used with
648      * {@link #killProcess} and {@link #sendSignal}.
649      */
myPid()650     public static final native int myPid();
651 
652     /**
653      * Returns the identifier of the calling thread, which be used with
654      * {@link #setThreadPriority(int, int)}.
655      */
myTid()656     public static final native int myTid();
657 
658     /**
659      * Returns the identifier of this process's uid.  This is the kernel uid
660      * that the process is running under, which is the identity of its
661      * app-specific sandbox.  It is different from {@link #myUserHandle} in that
662      * a uid identifies a specific app sandbox in a specific user.
663      */
myUid()664     public static final native int myUid();
665 
666     /**
667      * Returns this process's user handle.  This is the
668      * user the process is running under.  It is distinct from
669      * {@link #myUid()} in that a particular user will have multiple
670      * distinct apps running under it each with their own uid.
671      */
myUserHandle()672     public static final UserHandle myUserHandle() {
673         return new UserHandle(UserHandle.getUserId(myUid()));
674     }
675 
676     /**
677      * Returns whether the current process is in an isolated sandbox.
678      * @hide
679      */
isIsolated()680     public static final boolean isIsolated() {
681         int uid = UserHandle.getAppId(myUid());
682         return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
683     }
684 
685     /**
686      * Returns the UID assigned to a particular user name, or -1 if there is
687      * none.  If the given string consists of only numbers, it is converted
688      * directly to a uid.
689      */
getUidForName(String name)690     public static final native int getUidForName(String name);
691 
692     /**
693      * Returns the GID assigned to a particular user name, or -1 if there is
694      * none.  If the given string consists of only numbers, it is converted
695      * directly to a gid.
696      */
getGidForName(String name)697     public static final native int getGidForName(String name);
698 
699     /**
700      * Returns a uid for a currently running process.
701      * @param pid the process id
702      * @return the uid of the process, or -1 if the process is not running.
703      * @hide pending API council review
704      */
getUidForPid(int pid)705     public static final int getUidForPid(int pid) {
706         String[] procStatusLabels = { "Uid:" };
707         long[] procStatusValues = new long[1];
708         procStatusValues[0] = -1;
709         Process.readProcLines("/proc/" + pid + "/status", procStatusLabels, procStatusValues);
710         return (int) procStatusValues[0];
711     }
712 
713     /**
714      * Returns the parent process id for a currently running process.
715      * @param pid the process id
716      * @return the parent process id of the process, or -1 if the process is not running.
717      * @hide
718      */
getParentPid(int pid)719     public static final int getParentPid(int pid) {
720         String[] procStatusLabels = { "PPid:" };
721         long[] procStatusValues = new long[1];
722         procStatusValues[0] = -1;
723         Process.readProcLines("/proc/" + pid + "/status", procStatusLabels, procStatusValues);
724         return (int) procStatusValues[0];
725     }
726 
727     /**
728      * Returns the thread group leader id for a currently running thread.
729      * @param tid the thread id
730      * @return the thread group leader id of the thread, or -1 if the thread is not running.
731      *         This is same as what getpid(2) would return if called by tid.
732      * @hide
733      */
getThreadGroupLeader(int tid)734     public static final int getThreadGroupLeader(int tid) {
735         String[] procStatusLabels = { "Tgid:" };
736         long[] procStatusValues = new long[1];
737         procStatusValues[0] = -1;
738         Process.readProcLines("/proc/" + tid + "/status", procStatusLabels, procStatusValues);
739         return (int) procStatusValues[0];
740     }
741 
742     /**
743      * Set the priority of a thread, based on Linux priorities.
744      *
745      * @param tid The identifier of the thread/process to change.
746      * @param priority A Linux priority level, from -20 for highest scheduling
747      * priority to 19 for lowest scheduling priority.
748      *
749      * @throws IllegalArgumentException Throws IllegalArgumentException if
750      * <var>tid</var> does not exist.
751      * @throws SecurityException Throws SecurityException if your process does
752      * not have permission to modify the given thread, or to use the given
753      * priority.
754      */
setThreadPriority(int tid, int priority)755     public static final native void setThreadPriority(int tid, int priority)
756             throws IllegalArgumentException, SecurityException;
757 
758     /**
759      * Call with 'false' to cause future calls to {@link #setThreadPriority(int)} to
760      * throw an exception if passed a background-level thread priority.  This is only
761      * effective if the JNI layer is built with GUARD_THREAD_PRIORITY defined to 1.
762      *
763      * @hide
764      */
setCanSelfBackground(boolean backgroundOk)765     public static final native void setCanSelfBackground(boolean backgroundOk);
766 
767     /**
768      * Sets the scheduling group for a thread.
769      * @hide
770      * @param tid The identifier of the thread to change.
771      * @param group The target group for this thread from THREAD_GROUP_*.
772      *
773      * @throws IllegalArgumentException Throws IllegalArgumentException if
774      * <var>tid</var> does not exist.
775      * @throws SecurityException Throws SecurityException if your process does
776      * not have permission to modify the given thread, or to use the given
777      * priority.
778      * If the thread is a thread group leader, that is it's gettid() == getpid(),
779      * then the other threads in the same thread group are _not_ affected.
780      */
setThreadGroup(int tid, int group)781     public static final native void setThreadGroup(int tid, int group)
782             throws IllegalArgumentException, SecurityException;
783 
784     /**
785      * Sets the scheduling group for a process and all child threads
786      * @hide
787      * @param pid The identifier of the process to change.
788      * @param group The target group for this process from THREAD_GROUP_*.
789      *
790      * @throws IllegalArgumentException Throws IllegalArgumentException if
791      * <var>tid</var> does not exist.
792      * @throws SecurityException Throws SecurityException if your process does
793      * not have permission to modify the given thread, or to use the given
794      * priority.
795      *
796      * group == THREAD_GROUP_DEFAULT means to move all non-background priority
797      * threads to the foreground scheduling group, but to leave background
798      * priority threads alone.  group == THREAD_GROUP_BG_NONINTERACTIVE moves all
799      * threads, regardless of priority, to the background scheduling group.
800      * group == THREAD_GROUP_FOREGROUND is not allowed.
801      */
setProcessGroup(int pid, int group)802     public static final native void setProcessGroup(int pid, int group)
803             throws IllegalArgumentException, SecurityException;
804 
805     /**
806      * Return the scheduling group of requested process.
807      *
808      * @hide
809      */
getProcessGroup(int pid)810     public static final native int getProcessGroup(int pid)
811             throws IllegalArgumentException, SecurityException;
812 
813     /**
814      * Set the priority of the calling thread, based on Linux priorities.  See
815      * {@link #setThreadPriority(int, int)} for more information.
816      *
817      * @param priority A Linux priority level, from -20 for highest scheduling
818      * priority to 19 for lowest scheduling priority.
819      *
820      * @throws IllegalArgumentException Throws IllegalArgumentException if
821      * <var>tid</var> does not exist.
822      * @throws SecurityException Throws SecurityException if your process does
823      * not have permission to modify the given thread, or to use the given
824      * priority.
825      *
826      * @see #setThreadPriority(int, int)
827      */
setThreadPriority(int priority)828     public static final native void setThreadPriority(int priority)
829             throws IllegalArgumentException, SecurityException;
830 
831     /**
832      * Return the current priority of a thread, based on Linux priorities.
833      *
834      * @param tid The identifier of the thread/process to change.
835      *
836      * @return Returns the current priority, as a Linux priority level,
837      * from -20 for highest scheduling priority to 19 for lowest scheduling
838      * priority.
839      *
840      * @throws IllegalArgumentException Throws IllegalArgumentException if
841      * <var>tid</var> does not exist.
842      */
getThreadPriority(int tid)843     public static final native int getThreadPriority(int tid)
844             throws IllegalArgumentException;
845 
846     /**
847      * Set the scheduling policy and priority of a thread, based on Linux.
848      *
849      * @param tid The identifier of the thread/process to change.
850      * @param policy A Linux scheduling policy such as SCHED_OTHER etc.
851      * @param priority A Linux priority level in a range appropriate for the given policy.
852      *
853      * @throws IllegalArgumentException Throws IllegalArgumentException if
854      * <var>tid</var> does not exist, or if <var>priority</var> is out of range for the policy.
855      * @throws SecurityException Throws SecurityException if your process does
856      * not have permission to modify the given thread, or to use the given
857      * scheduling policy or priority.
858      *
859      * {@hide}
860      */
setThreadScheduler(int tid, int policy, int priority)861     public static final native void setThreadScheduler(int tid, int policy, int priority)
862             throws IllegalArgumentException;
863 
864     /**
865      * Determine whether the current environment supports multiple processes.
866      *
867      * @return Returns true if the system can run in multiple processes, else
868      * false if everything is running in a single process.
869      *
870      * @deprecated This method always returns true.  Do not use.
871      */
872     @Deprecated
supportsProcesses()873     public static final boolean supportsProcesses() {
874         return true;
875     }
876 
877     /**
878      * Set the out-of-memory badness adjustment for a process.
879      *
880      * @param pid The process identifier to set.
881      * @param amt Adjustment value -- linux allows -16 to +15.
882      *
883      * @return Returns true if the underlying system supports this
884      *         feature, else false.
885      *
886      * {@hide}
887      */
setOomAdj(int pid, int amt)888     public static final native boolean setOomAdj(int pid, int amt);
889 
890     /**
891      * Change this process's argv[0] parameter.  This can be useful to show
892      * more descriptive information in things like the 'ps' command.
893      *
894      * @param text The new name of this process.
895      *
896      * {@hide}
897      */
setArgV0(String text)898     public static final native void setArgV0(String text);
899 
900     /**
901      * Kill the process with the given PID.
902      * Note that, though this API allows us to request to
903      * kill any process based on its PID, the kernel will
904      * still impose standard restrictions on which PIDs you
905      * are actually able to kill.  Typically this means only
906      * the process running the caller's packages/application
907      * and any additional processes created by that app; packages
908      * sharing a common UID will also be able to kill each
909      * other's processes.
910      */
killProcess(int pid)911     public static final void killProcess(int pid) {
912         sendSignal(pid, SIGNAL_KILL);
913     }
914 
915     /** @hide */
setUid(int uid)916     public static final native int setUid(int uid);
917 
918     /** @hide */
setGid(int uid)919     public static final native int setGid(int uid);
920 
921     /**
922      * Send a signal to the given process.
923      *
924      * @param pid The pid of the target process.
925      * @param signal The signal to send.
926      */
sendSignal(int pid, int signal)927     public static final native void sendSignal(int pid, int signal);
928 
929     /**
930      * @hide
931      * Private impl for avoiding a log message...  DO NOT USE without doing
932      * your own log, or the Android Illuminati will find you some night and
933      * beat you up.
934      */
killProcessQuiet(int pid)935     public static final void killProcessQuiet(int pid) {
936         sendSignalQuiet(pid, SIGNAL_KILL);
937     }
938 
939     /**
940      * @hide
941      * Private impl for avoiding a log message...  DO NOT USE without doing
942      * your own log, or the Android Illuminati will find you some night and
943      * beat you up.
944      */
sendSignalQuiet(int pid, int signal)945     public static final native void sendSignalQuiet(int pid, int signal);
946 
947     /** @hide */
getFreeMemory()948     public static final native long getFreeMemory();
949 
950     /** @hide */
getTotalMemory()951     public static final native long getTotalMemory();
952 
953     /** @hide */
readProcLines(String path, String[] reqFields, long[] outSizes)954     public static final native void readProcLines(String path,
955             String[] reqFields, long[] outSizes);
956 
957     /** @hide */
getPids(String path, int[] lastArray)958     public static final native int[] getPids(String path, int[] lastArray);
959 
960     /** @hide */
961     public static final int PROC_TERM_MASK = 0xff;
962     /** @hide */
963     public static final int PROC_ZERO_TERM = 0;
964     /** @hide */
965     public static final int PROC_SPACE_TERM = (int)' ';
966     /** @hide */
967     public static final int PROC_TAB_TERM = (int)'\t';
968     /** @hide */
969     public static final int PROC_COMBINE = 0x100;
970     /** @hide */
971     public static final int PROC_PARENS = 0x200;
972     /** @hide */
973     public static final int PROC_OUT_STRING = 0x1000;
974     /** @hide */
975     public static final int PROC_OUT_LONG = 0x2000;
976     /** @hide */
977     public static final int PROC_OUT_FLOAT = 0x4000;
978 
979     /** @hide */
readProcFile(String file, int[] format, String[] outStrings, long[] outLongs, float[] outFloats)980     public static final native boolean readProcFile(String file, int[] format,
981             String[] outStrings, long[] outLongs, float[] outFloats);
982 
983     /** @hide */
parseProcLine(byte[] buffer, int startIndex, int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats)984     public static final native boolean parseProcLine(byte[] buffer, int startIndex,
985             int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
986 
987     /** @hide */
getPidsForCommands(String[] cmds)988     public static final native int[] getPidsForCommands(String[] cmds);
989 
990     /**
991      * Gets the total Pss value for a given process, in bytes.
992      *
993      * @param pid the process to the Pss for
994      * @return the total Pss value for the given process in bytes,
995      *  or -1 if the value cannot be determined
996      * @hide
997      */
getPss(int pid)998     public static final native long getPss(int pid);
999 
1000     /**
1001      * Specifies the outcome of having started a process.
1002      * @hide
1003      */
1004     public static final class ProcessStartResult {
1005         /**
1006          * The PID of the newly started process.
1007          * Always >= 0.  (If the start failed, an exception will have been thrown instead.)
1008          */
1009         public int pid;
1010 
1011         /**
1012          * True if the process was started with a wrapper attached.
1013          */
1014         public boolean usingWrapper;
1015     }
1016 }
1017