Process.java revision bc21fdefdfbeba1754c6cd339c7dd8e8f1d6fd48
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
17package android.os;
18
19import android.net.LocalSocketAddress;
20import android.net.LocalSocket;
21import android.util.Log;
22import dalvik.system.Zygote;
23
24import java.io.BufferedWriter;
25import java.io.DataInputStream;
26import java.io.IOException;
27import java.io.OutputStreamWriter;
28import java.util.ArrayList;
29
30/*package*/ class ZygoteStartFailedEx extends Exception {
31    /**
32     * Something prevented the zygote process startup from happening normally
33     */
34
35    ZygoteStartFailedEx() {};
36    ZygoteStartFailedEx(String s) {super(s);}
37    ZygoteStartFailedEx(Throwable cause) {super(cause);}
38}
39
40/**
41 * Tools for managing OS processes.
42 */
43public 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 NFC service process.
90     * @hide
91     */
92    public static final int NFC_UID = 1022;
93
94    /**
95     * Defines the start of a range of UIDs (and GIDs), going from this
96     * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
97     * to applications.
98     */
99    public static final int FIRST_APPLICATION_UID = 10000;
100    /**
101     * Last of application-specific UIDs starting at
102     * {@link #FIRST_APPLICATION_UID}.
103     */
104    public static final int LAST_APPLICATION_UID = 99999;
105
106    /**
107     * Defines a secondary group id for access to the bluetooth hardware.
108     */
109    public static final int BLUETOOTH_GID = 2000;
110
111    /**
112     * Standard priority of application threads.
113     * Use with {@link #setThreadPriority(int)} and
114     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
115     * {@link java.lang.Thread} class.
116     */
117    public static final int THREAD_PRIORITY_DEFAULT = 0;
118
119    /*
120     * ***************************************
121     * ** Keep in sync with utils/threads.h **
122     * ***************************************
123     */
124
125    /**
126     * Lowest available thread priority.  Only for those who really, really
127     * don't want to run if anything else is happening.
128     * Use with {@link #setThreadPriority(int)} and
129     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
130     * {@link java.lang.Thread} class.
131     */
132    public static final int THREAD_PRIORITY_LOWEST = 19;
133
134    /**
135     * Standard priority background threads.  This gives your thread a slightly
136     * lower than normal priority, so that it will have less chance of impacting
137     * the responsiveness of the user interface.
138     * Use with {@link #setThreadPriority(int)} and
139     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
140     * {@link java.lang.Thread} class.
141     */
142    public static final int THREAD_PRIORITY_BACKGROUND = 10;
143
144    /**
145     * Standard priority of threads that are currently running a user interface
146     * that the user is interacting with.  Applications can not normally
147     * change to this priority; the system will automatically adjust your
148     * application threads as the user moves through the UI.
149     * Use with {@link #setThreadPriority(int)} and
150     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
151     * {@link java.lang.Thread} class.
152     */
153    public static final int THREAD_PRIORITY_FOREGROUND = -2;
154
155    /**
156     * Standard priority of system display threads, involved in updating
157     * the user interface.  Applications can not
158     * normally change to this priority.
159     * Use with {@link #setThreadPriority(int)} and
160     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
161     * {@link java.lang.Thread} class.
162     */
163    public static final int THREAD_PRIORITY_DISPLAY = -4;
164
165    /**
166     * Standard priority of the most important display threads, for compositing
167     * the screen and retrieving input events.  Applications can not normally
168     * change to this priority.
169     * Use with {@link #setThreadPriority(int)} and
170     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
171     * {@link java.lang.Thread} class.
172     */
173    public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8;
174
175    /**
176     * Standard priority of audio threads.  Applications can not normally
177     * change to this priority.
178     * Use with {@link #setThreadPriority(int)} and
179     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
180     * {@link java.lang.Thread} class.
181     */
182    public static final int THREAD_PRIORITY_AUDIO = -16;
183
184    /**
185     * Standard priority of the most important audio threads.
186     * Applications can not normally change to this priority.
187     * Use with {@link #setThreadPriority(int)} and
188     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
189     * {@link java.lang.Thread} class.
190     */
191    public static final int THREAD_PRIORITY_URGENT_AUDIO = -19;
192
193    /**
194     * Minimum increment to make a priority more favorable.
195     */
196    public static final int THREAD_PRIORITY_MORE_FAVORABLE = -1;
197
198    /**
199     * Minimum increment to make a priority less favorable.
200     */
201    public static final int THREAD_PRIORITY_LESS_FAVORABLE = +1;
202
203    /**
204     * Default thread group - gets a 'normal' share of the CPU
205     * @hide
206     */
207    public static final int THREAD_GROUP_DEFAULT = 0;
208
209    /**
210     * Background non-interactive thread group - All threads in
211     * this group are scheduled with a reduced share of the CPU.
212     * @hide
213     */
214    public static final int THREAD_GROUP_BG_NONINTERACTIVE = 1;
215
216    /**
217     * Foreground 'boost' thread group - All threads in
218     * this group are scheduled with an increased share of the CPU
219     * @hide
220     **/
221    public static final int THREAD_GROUP_FG_BOOST = 2;
222
223    public static final int SIGNAL_QUIT = 3;
224    public static final int SIGNAL_KILL = 9;
225    public static final int SIGNAL_USR1 = 10;
226
227    // State for communicating with zygote process
228
229    static LocalSocket sZygoteSocket;
230    static DataInputStream sZygoteInputStream;
231    static BufferedWriter sZygoteWriter;
232
233    /** true if previous zygote open failed */
234    static boolean sPreviousZygoteOpenFailed;
235
236    /**
237     * Start a new process.
238     *
239     * <p>If processes are enabled, a new process is created and the
240     * static main() function of a <var>processClass</var> is executed there.
241     * The process will continue running after this function returns.
242     *
243     * <p>If processes are not enabled, a new thread in the caller's
244     * process is created and main() of <var>processClass</var> called there.
245     *
246     * <p>The niceName parameter, if not an empty string, is a custom name to
247     * give to the process instead of using processClass.  This allows you to
248     * make easily identifyable processes even if you are using the same base
249     * <var>processClass</var> to start them.
250     *
251     * @param processClass The class to use as the process's main entry
252     *                     point.
253     * @param niceName A more readable name to use for the process.
254     * @param uid The user-id under which the process will run.
255     * @param gid The group-id under which the process will run.
256     * @param gids Additional group-ids associated with the process.
257     * @param enableDebugger True if debugging should be enabled for this process.
258     * @param zygoteArgs Additional arguments to supply to the zygote process.
259     *
260     * @return int If > 0 the pid of the new process; if 0 the process is
261     *         being emulated by a thread
262     * @throws RuntimeException on fatal start failure
263     *
264     * {@hide}
265     */
266    public static final int start(final String processClass,
267                                  final String niceName,
268                                  int uid, int gid, int[] gids,
269                                  int debugFlags,
270                                  String[] zygoteArgs)
271    {
272        if (supportsProcesses()) {
273            try {
274                return startViaZygote(processClass, niceName, uid, gid, gids,
275                        debugFlags, zygoteArgs);
276            } catch (ZygoteStartFailedEx ex) {
277                Log.e(LOG_TAG,
278                        "Starting VM process through Zygote failed");
279                throw new RuntimeException(
280                        "Starting VM process through Zygote failed", ex);
281            }
282        } else {
283            // Running in single-process mode
284
285            Runnable runnable = new Runnable() {
286                        public void run() {
287                            Process.invokeStaticMain(processClass);
288                        }
289            };
290
291            // Thread constructors must not be called with null names (see spec).
292            if (niceName != null) {
293                new Thread(runnable, niceName).start();
294            } else {
295                new Thread(runnable).start();
296            }
297
298            return 0;
299        }
300    }
301
302    /**
303     * Start a new process.  Don't supply a custom nice name.
304     * {@hide}
305     */
306    public static final int start(String processClass, int uid, int gid,
307            int[] gids, int debugFlags, String[] zygoteArgs) {
308        return start(processClass, "", uid, gid, gids,
309                debugFlags, zygoteArgs);
310    }
311
312    private static void invokeStaticMain(String className) {
313        Class cl;
314        Object args[] = new Object[1];
315
316        args[0] = new String[0];     //this is argv
317
318        try {
319            cl = Class.forName(className);
320            cl.getMethod("main", new Class[] { String[].class })
321                    .invoke(null, args);
322        } catch (Exception ex) {
323            // can be: ClassNotFoundException,
324            // NoSuchMethodException, SecurityException,
325            // IllegalAccessException, IllegalArgumentException
326            // InvocationTargetException
327            // or uncaught exception from main()
328
329            Log.e(LOG_TAG, "Exception invoking static main on "
330                    + className, ex);
331
332            throw new RuntimeException(ex);
333        }
334
335    }
336
337    /** retry interval for opening a zygote socket */
338    static final int ZYGOTE_RETRY_MILLIS = 500;
339
340    /**
341     * Tries to open socket to Zygote process if not already open. If
342     * already open, does nothing.  May block and retry.
343     */
344    private static void openZygoteSocketIfNeeded()
345            throws ZygoteStartFailedEx {
346
347        int retryCount;
348
349        if (sPreviousZygoteOpenFailed) {
350            /*
351             * If we've failed before, expect that we'll fail again and
352             * don't pause for retries.
353             */
354            retryCount = 0;
355        } else {
356            retryCount = 10;
357        }
358
359        /*
360         * See bug #811181: Sometimes runtime can make it up before zygote.
361         * Really, we'd like to do something better to avoid this condition,
362         * but for now just wait a bit...
363         */
364        for (int retry = 0
365                ; (sZygoteSocket == null) && (retry < (retryCount + 1))
366                ; retry++ ) {
367
368            if (retry > 0) {
369                try {
370                    Log.i("Zygote", "Zygote not up yet, sleeping...");
371                    Thread.sleep(ZYGOTE_RETRY_MILLIS);
372                } catch (InterruptedException ex) {
373                    // should never happen
374                }
375            }
376
377            try {
378                sZygoteSocket = new LocalSocket();
379
380                sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,
381                        LocalSocketAddress.Namespace.RESERVED));
382
383                sZygoteInputStream
384                        = new DataInputStream(sZygoteSocket.getInputStream());
385
386                sZygoteWriter =
387                    new BufferedWriter(
388                            new OutputStreamWriter(
389                                    sZygoteSocket.getOutputStream()),
390                            256);
391
392                Log.i("Zygote", "Process: zygote socket opened");
393
394                sPreviousZygoteOpenFailed = false;
395                break;
396            } catch (IOException ex) {
397                if (sZygoteSocket != null) {
398                    try {
399                        sZygoteSocket.close();
400                    } catch (IOException ex2) {
401                        Log.e(LOG_TAG,"I/O exception on close after exception",
402                                ex2);
403                    }
404                }
405
406                sZygoteSocket = null;
407            }
408        }
409
410        if (sZygoteSocket == null) {
411            sPreviousZygoteOpenFailed = true;
412            throw new ZygoteStartFailedEx("connect failed");
413        }
414    }
415
416    /**
417     * Sends an argument list to the zygote process, which starts a new child
418     * and returns the child's pid. Please note: the present implementation
419     * replaces newlines in the argument list with spaces.
420     * @param args argument list
421     * @return PID of new child process
422     * @throws ZygoteStartFailedEx if process start failed for any reason
423     */
424    private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
425            throws ZygoteStartFailedEx {
426
427        int pid;
428
429        openZygoteSocketIfNeeded();
430
431        try {
432            /**
433             * See com.android.internal.os.ZygoteInit.readArgumentList()
434             * Presently the wire format to the zygote process is:
435             * a) a count of arguments (argc, in essence)
436             * b) a number of newline-separated argument strings equal to count
437             *
438             * After the zygote process reads these it will write the pid of
439             * the child or -1 on failure.
440             */
441
442            sZygoteWriter.write(Integer.toString(args.size()));
443            sZygoteWriter.newLine();
444
445            int sz = args.size();
446            for (int i = 0; i < sz; i++) {
447                String arg = args.get(i);
448                if (arg.indexOf('\n') >= 0) {
449                    throw new ZygoteStartFailedEx(
450                            "embedded newlines not allowed");
451                }
452                sZygoteWriter.write(arg);
453                sZygoteWriter.newLine();
454            }
455
456            sZygoteWriter.flush();
457
458            // Should there be a timeout on this?
459            pid = sZygoteInputStream.readInt();
460
461            if (pid < 0) {
462                throw new ZygoteStartFailedEx("fork() failed");
463            }
464        } catch (IOException ex) {
465            try {
466                if (sZygoteSocket != null) {
467                    sZygoteSocket.close();
468                }
469            } catch (IOException ex2) {
470                // we're going to fail anyway
471                Log.e(LOG_TAG,"I/O exception on routine close", ex2);
472            }
473
474            sZygoteSocket = null;
475
476            throw new ZygoteStartFailedEx(ex);
477        }
478
479        return pid;
480    }
481
482    /**
483     * Starts a new process via the zygote mechanism.
484     *
485     * @param processClass Class name whose static main() to run
486     * @param niceName 'nice' process name to appear in ps
487     * @param uid a POSIX uid that the new process should setuid() to
488     * @param gid a POSIX gid that the new process shuold setgid() to
489     * @param gids null-ok; a list of supplementary group IDs that the
490     * new process should setgroup() to.
491     * @param enableDebugger True if debugging should be enabled for this process.
492     * @param extraArgs Additional arguments to supply to the zygote process.
493     * @return PID
494     * @throws ZygoteStartFailedEx if process start failed for any reason
495     */
496    private static int startViaZygote(final String processClass,
497                                  final String niceName,
498                                  final int uid, final int gid,
499                                  final int[] gids,
500                                  int debugFlags,
501                                  String[] extraArgs)
502                                  throws ZygoteStartFailedEx {
503        int pid;
504
505        synchronized(Process.class) {
506            ArrayList<String> argsForZygote = new ArrayList<String>();
507
508            // --runtime-init, --setuid=, --setgid=,
509            // and --setgroups= must go first
510            argsForZygote.add("--runtime-init");
511            argsForZygote.add("--setuid=" + uid);
512            argsForZygote.add("--setgid=" + gid);
513            if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
514                argsForZygote.add("--enable-safemode");
515            }
516            if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
517                argsForZygote.add("--enable-debugger");
518            }
519            if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
520                argsForZygote.add("--enable-checkjni");
521            }
522            if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
523                argsForZygote.add("--enable-assert");
524            }
525
526            //TODO optionally enable debuger
527            //argsForZygote.add("--enable-debugger");
528
529            // --setgroups is a comma-separated list
530            if (gids != null && gids.length > 0) {
531                StringBuilder sb = new StringBuilder();
532                sb.append("--setgroups=");
533
534                int sz = gids.length;
535                for (int i = 0; i < sz; i++) {
536                    if (i != 0) {
537                        sb.append(',');
538                    }
539                    sb.append(gids[i]);
540                }
541
542                argsForZygote.add(sb.toString());
543            }
544
545            if (niceName != null) {
546                argsForZygote.add("--nice-name=" + niceName);
547            }
548
549            argsForZygote.add(processClass);
550
551            if (extraArgs != null) {
552                for (String arg : extraArgs) {
553                    argsForZygote.add(arg);
554                }
555            }
556
557            pid = zygoteSendArgsAndGetPid(argsForZygote);
558        }
559
560        if (pid <= 0) {
561            throw new ZygoteStartFailedEx("zygote start failed:" + pid);
562        }
563
564        return pid;
565    }
566
567    /**
568     * Returns elapsed milliseconds of the time this process has run.
569     * @return  Returns the number of milliseconds this process has return.
570     */
571    public static final native long getElapsedCpuTime();
572
573    /**
574     * Returns the identifier of this process, which can be used with
575     * {@link #killProcess} and {@link #sendSignal}.
576     */
577    public static final native int myPid();
578
579    /**
580     * Returns the identifier of the calling thread, which be used with
581     * {@link #setThreadPriority(int, int)}.
582     */
583    public static final native int myTid();
584
585    /**
586     * Returns the identifier of this process's user.
587     */
588    public static final native int myUid();
589
590    /**
591     * Returns the UID assigned to a particular user name, or -1 if there is
592     * none.  If the given string consists of only numbers, it is converted
593     * directly to a uid.
594     */
595    public static final native int getUidForName(String name);
596
597    /**
598     * Returns the GID assigned to a particular user name, or -1 if there is
599     * none.  If the given string consists of only numbers, it is converted
600     * directly to a gid.
601     */
602    public static final native int getGidForName(String name);
603
604    /**
605     * Returns a uid for a currently running process.
606     * @param pid the process id
607     * @return the uid of the process, or -1 if the process is not running.
608     * @hide pending API council review
609     */
610    public static final int getUidForPid(int pid) {
611        String[] procStatusLabels = { "Uid:" };
612        long[] procStatusValues = new long[1];
613        procStatusValues[0] = -1;
614        Process.readProcLines("/proc/" + pid + "/status", procStatusLabels, procStatusValues);
615        return (int) procStatusValues[0];
616    }
617
618    /**
619     * Set the priority of a thread, based on Linux priorities.
620     *
621     * @param tid The identifier of the thread/process to change.
622     * @param priority A Linux priority level, from -20 for highest scheduling
623     * priority to 19 for lowest scheduling priority.
624     *
625     * @throws IllegalArgumentException Throws IllegalArgumentException if
626     * <var>tid</var> does not exist.
627     * @throws SecurityException Throws SecurityException if your process does
628     * not have permission to modify the given thread, or to use the given
629     * priority.
630     */
631    public static final native void setThreadPriority(int tid, int priority)
632            throws IllegalArgumentException, SecurityException;
633
634    /**
635     * Call with 'false' to cause future calls to {@link #setThreadPriority(int)} to
636     * throw an exception if passed a background-level thread priority.  This is only
637     * effective if the JNI layer is built with GUARD_THREAD_PRIORITY defined to 1.
638     *
639     * @hide
640     */
641    public static final native void setCanSelfBackground(boolean backgroundOk);
642
643    /**
644     * Sets the scheduling group for a thread.
645     * @hide
646     * @param tid The indentifier of the thread/process to change.
647     * @param group The target group for this thread/process.
648     *
649     * @throws IllegalArgumentException Throws IllegalArgumentException if
650     * <var>tid</var> does not exist.
651     * @throws SecurityException Throws SecurityException if your process does
652     * not have permission to modify the given thread, or to use the given
653     * priority.
654     */
655    public static final native void setThreadGroup(int tid, int group)
656            throws IllegalArgumentException, SecurityException;
657    /**
658     * Sets the scheduling group for a process and all child threads
659     * @hide
660     * @param pid The indentifier of the process to change.
661     * @param group The target group for this process.
662     *
663     * @throws IllegalArgumentException Throws IllegalArgumentException if
664     * <var>tid</var> does not exist.
665     * @throws SecurityException Throws SecurityException if your process does
666     * not have permission to modify the given thread, or to use the given
667     * priority.
668     */
669    public static final native void setProcessGroup(int pid, int group)
670            throws IllegalArgumentException, SecurityException;
671
672    /**
673     * Set the priority of the calling thread, based on Linux priorities.  See
674     * {@link #setThreadPriority(int, int)} for more information.
675     *
676     * @param priority A Linux priority level, from -20 for highest scheduling
677     * priority to 19 for lowest scheduling priority.
678     *
679     * @throws IllegalArgumentException Throws IllegalArgumentException if
680     * <var>tid</var> does not exist.
681     * @throws SecurityException Throws SecurityException if your process does
682     * not have permission to modify the given thread, or to use the given
683     * priority.
684     *
685     * @see #setThreadPriority(int, int)
686     */
687    public static final native void setThreadPriority(int priority)
688            throws IllegalArgumentException, SecurityException;
689
690    /**
691     * Return the current priority of a thread, based on Linux priorities.
692     *
693     * @param tid The identifier of the thread/process to change.
694     *
695     * @return Returns the current priority, as a Linux priority level,
696     * from -20 for highest scheduling priority to 19 for lowest scheduling
697     * priority.
698     *
699     * @throws IllegalArgumentException Throws IllegalArgumentException if
700     * <var>tid</var> does not exist.
701     */
702    public static final native int getThreadPriority(int tid)
703            throws IllegalArgumentException;
704
705    /**
706     * Determine whether the current environment supports multiple processes.
707     *
708     * @return Returns true if the system can run in multiple processes, else
709     * false if everything is running in a single process.
710     */
711    public static final native boolean supportsProcesses();
712
713    /**
714     * Set the out-of-memory badness adjustment for a process.
715     *
716     * @param pid The process identifier to set.
717     * @param amt Adjustment value -- linux allows -16 to +15.
718     *
719     * @return Returns true if the underlying system supports this
720     *         feature, else false.
721     *
722     * {@hide}
723     */
724    public static final native boolean setOomAdj(int pid, int amt);
725
726    /**
727     * Change this process's argv[0] parameter.  This can be useful to show
728     * more descriptive information in things like the 'ps' command.
729     *
730     * @param text The new name of this process.
731     *
732     * {@hide}
733     */
734    public static final native void setArgV0(String text);
735
736    /**
737     * Kill the process with the given PID.
738     * Note that, though this API allows us to request to
739     * kill any process based on its PID, the kernel will
740     * still impose standard restrictions on which PIDs you
741     * are actually able to kill.  Typically this means only
742     * the process running the caller's packages/application
743     * and any additional processes created by that app; packages
744     * sharing a common UID will also be able to kill each
745     * other's processes.
746     */
747    public static final void killProcess(int pid) {
748        sendSignal(pid, SIGNAL_KILL);
749    }
750
751    /** @hide */
752    public static final native int setUid(int uid);
753
754    /** @hide */
755    public static final native int setGid(int uid);
756
757    /**
758     * Send a signal to the given process.
759     *
760     * @param pid The pid of the target process.
761     * @param signal The signal to send.
762     */
763    public static final native void sendSignal(int pid, int signal);
764
765    /**
766     * @hide
767     * Private impl for avoiding a log message...  DO NOT USE without doing
768     * your own log, or the Android Illuminati will find you some night and
769     * beat you up.
770     */
771    public static final void killProcessQuiet(int pid) {
772        sendSignalQuiet(pid, SIGNAL_KILL);
773    }
774
775    /**
776     * @hide
777     * Private impl for avoiding a log message...  DO NOT USE without doing
778     * your own log, or the Android Illuminati will find you some night and
779     * beat you up.
780     */
781    public static final native void sendSignalQuiet(int pid, int signal);
782
783    /** @hide */
784    public static final native long getFreeMemory();
785
786    /** @hide */
787    public static final native void readProcLines(String path,
788            String[] reqFields, long[] outSizes);
789
790    /** @hide */
791    public static final native int[] getPids(String path, int[] lastArray);
792
793    /** @hide */
794    public static final int PROC_TERM_MASK = 0xff;
795    /** @hide */
796    public static final int PROC_ZERO_TERM = 0;
797    /** @hide */
798    public static final int PROC_SPACE_TERM = (int)' ';
799    /** @hide */
800    public static final int PROC_TAB_TERM = (int)'\t';
801    /** @hide */
802    public static final int PROC_COMBINE = 0x100;
803    /** @hide */
804    public static final int PROC_PARENS = 0x200;
805    /** @hide */
806    public static final int PROC_OUT_STRING = 0x1000;
807    /** @hide */
808    public static final int PROC_OUT_LONG = 0x2000;
809    /** @hide */
810    public static final int PROC_OUT_FLOAT = 0x4000;
811
812    /** @hide */
813    public static final native boolean readProcFile(String file, int[] format,
814            String[] outStrings, long[] outLongs, float[] outFloats);
815
816    /** @hide */
817    public static final native boolean parseProcLine(byte[] buffer, int startIndex,
818            int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
819
820    /**
821     * Gets the total Pss value for a given process, in bytes.
822     *
823     * @param pid the process to the Pss for
824     * @return the total Pss value for the given process in bytes,
825     *  or -1 if the value cannot be determined
826     * @hide
827     */
828    public static final native long getPss(int pid);
829}
830