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