Home | History | Annotate | Download | only in os
      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 
     35     ZygoteStartFailedEx() {};
     36     ZygoteStartFailedEx(String s) {super(s);}
     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 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