2 * Copyright (C) 2006 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import android.annotation.TestApi;
20 import android.net.LocalSocket;
21 import android.net.LocalSocketAddress;
22 import android.system.Os;
23 import android.system.OsConstants;
24 import android.util.Log;
25 import com.android.internal.os.Zygote;
26 import dalvik.system.VMRuntime;
27 import java.io.BufferedWriter;
28 import java.io.DataInputStream;
29 import java.io.IOException;
30 import java.io.OutputStreamWriter;
31 import java.nio.charset.StandardCharsets;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
36 /*package*/ class ZygoteStartFailedEx extends Exception {
37 ZygoteStartFailedEx(String s) {
41 ZygoteStartFailedEx(Throwable cause) {
45 ZygoteStartFailedEx(String s, Throwable cause) {
51 * Tools for managing OS processes.
53 public class Process {
54 private static final String LOG_TAG = "Process";
57 * @hide for internal use only.
59 public static final String ZYGOTE_SOCKET = "zygote";
62 * @hide for internal use only.
64 public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary";
67 * Defines the root UID.
70 public static final int ROOT_UID = 0;
73 * Defines the UID/GID under which system code runs.
75 public static final int SYSTEM_UID = 1000;
78 * Defines the UID/GID under which the telephony code runs.
80 public static final int PHONE_UID = 1001;
83 * Defines the UID/GID for the user shell.
86 public static final int SHELL_UID = 2000;
89 * Defines the UID/GID for the log group.
92 public static final int LOG_UID = 1007;
95 * Defines the UID/GID for the WIFI supplicant process.
98 public static final int WIFI_UID = 1010;
101 * Defines the UID/GID for the mediaserver process.
104 public static final int MEDIA_UID = 1013;
107 * Defines the UID/GID for the DRM process.
110 public static final int DRM_UID = 1019;
113 * Defines the UID/GID for the group that controls VPN services.
116 public static final int VPN_UID = 1016;
119 * Defines the UID/GID for the NFC service process.
122 public static final int NFC_UID = 1027;
125 * Defines the UID/GID for the Bluetooth service process.
128 public static final int BLUETOOTH_UID = 1002;
131 * Defines the GID for the group that allows write access to the internal media storage.
134 public static final int MEDIA_RW_GID = 1023;
137 * Access to installed package details
140 public static final int PACKAGE_INFO_GID = 1032;
143 * Defines the UID/GID for the shared RELRO file updater process.
146 public static final int SHARED_RELRO_UID = 1037;
149 * Defines the UID/GID for the audioserver process.
152 public static final int AUDIOSERVER_UID = 1041;
155 * Defines the UID/GID for the cameraserver process
158 public static final int CAMERASERVER_UID = 1047;
161 * Defines the start of a range of UIDs (and GIDs), going from this
162 * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
165 public static final int FIRST_APPLICATION_UID = 10000;
168 * Last of application-specific UIDs starting at
169 * {@link #FIRST_APPLICATION_UID}.
171 public static final int LAST_APPLICATION_UID = 19999;
174 * First uid used for fully isolated sandboxed processes (with no permissions of their own)
177 public static final int FIRST_ISOLATED_UID = 99000;
180 * Last uid used for fully isolated sandboxed processes (with no permissions of their own)
183 public static final int LAST_ISOLATED_UID = 99999;
186 * Defines the gid shared by all applications running under the same profile.
189 public static final int SHARED_USER_GID = 9997;
192 * First gid for applications to share resources. Used when forward-locking
193 * is enabled but all UserHandles need to be able to read the resources.
196 public static final int FIRST_SHARED_APPLICATION_GID = 50000;
199 * Last gid for applications to share resources. Used when forward-locking
200 * is enabled but all UserHandles need to be able to read the resources.
203 public static final int LAST_SHARED_APPLICATION_GID = 59999;
206 * Standard priority of application threads.
207 * Use with {@link #setThreadPriority(int)} and
208 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
209 * {@link java.lang.Thread} class.
211 public static final int THREAD_PRIORITY_DEFAULT = 0;
214 * ***************************************
215 * ** Keep in sync with utils/threads.h **
216 * ***************************************
220 * Lowest available thread priority. Only for those who really, really
221 * don't want to run if anything else is happening.
222 * Use with {@link #setThreadPriority(int)} and
223 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
224 * {@link java.lang.Thread} class.
226 public static final int THREAD_PRIORITY_LOWEST = 19;
229 * Standard priority background threads. This gives your thread a slightly
230 * lower than normal priority, so that it will have less chance of impacting
231 * the responsiveness of the user interface.
232 * Use with {@link #setThreadPriority(int)} and
233 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
234 * {@link java.lang.Thread} class.
236 public static final int THREAD_PRIORITY_BACKGROUND = 10;
239 * Standard priority of threads that are currently running a user interface
240 * that the user is interacting with. Applications can not normally
241 * change to this priority; the system will automatically adjust your
242 * application threads as the user moves through the UI.
243 * Use with {@link #setThreadPriority(int)} and
244 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
245 * {@link java.lang.Thread} class.
247 public static final int THREAD_PRIORITY_FOREGROUND = -2;
250 * Standard priority of system display threads, involved in updating
251 * the user interface. Applications can not
252 * normally change to this priority.
253 * Use with {@link #setThreadPriority(int)} and
254 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
255 * {@link java.lang.Thread} class.
257 public static final int THREAD_PRIORITY_DISPLAY = -4;
260 * Standard priority of the most important display threads, for compositing
261 * the screen and retrieving input events. Applications can not normally
262 * change to this priority.
263 * Use with {@link #setThreadPriority(int)} and
264 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
265 * {@link java.lang.Thread} class.
267 public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8;
270 * Standard priority of audio threads. Applications can not normally
271 * change to this priority.
272 * Use with {@link #setThreadPriority(int)} and
273 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
274 * {@link java.lang.Thread} class.
276 public static final int THREAD_PRIORITY_AUDIO = -16;
279 * Standard priority of the most important audio threads.
280 * Applications can not normally change to this priority.
281 * Use with {@link #setThreadPriority(int)} and
282 * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
283 * {@link java.lang.Thread} class.
285 public static final int THREAD_PRIORITY_URGENT_AUDIO = -19;
288 * Minimum increment to make a priority more favorable.
290 public static final int THREAD_PRIORITY_MORE_FAVORABLE = -1;
293 * Minimum increment to make a priority less favorable.
295 public static final int THREAD_PRIORITY_LESS_FAVORABLE = +1;
298 * Default scheduling policy
301 public static final int SCHED_OTHER = 0;
304 * First-In First-Out scheduling policy
307 public static final int SCHED_FIFO = 1;
310 * Round-Robin scheduling policy
313 public static final int SCHED_RR = 2;
316 * Batch scheduling policy
319 public static final int SCHED_BATCH = 3;
322 * Idle scheduling policy
325 public static final int SCHED_IDLE = 5;
328 * Reset scheduler choice on fork.
331 public static final int SCHED_RESET_ON_FORK = 0x40000000;
333 // Keep in sync with SP_* constants of enum type SchedPolicy
334 // declared in system/core/include/cutils/sched_policy.h,
335 // except THREAD_GROUP_DEFAULT does not correspond to any SP_* value.
338 * Default thread group -
339 * has meaning with setProcessGroup() only, cannot be used with setThreadGroup().
340 * When used with setProcessGroup(), the group of each thread in the process
341 * is conditionally changed based on that thread's current priority, as follows:
342 * threads with priority numerically less than THREAD_PRIORITY_BACKGROUND
343 * are moved to foreground thread group. All other threads are left unchanged.
346 public static final int THREAD_GROUP_DEFAULT = -1;
349 * Background thread group - All threads in
350 * this group are scheduled with a reduced share of the CPU.
351 * Value is same as constant SP_BACKGROUND of enum SchedPolicy.
352 * FIXME rename to THREAD_GROUP_BACKGROUND.
355 public static final int THREAD_GROUP_BG_NONINTERACTIVE = 0;
358 * Foreground thread group - All threads in
359 * this group are scheduled with a normal share of the CPU.
360 * Value is same as constant SP_FOREGROUND of enum SchedPolicy.
361 * Not used at this level.
364 private static final int THREAD_GROUP_FOREGROUND = 1;
367 * System thread group.
370 public static final int THREAD_GROUP_SYSTEM = 2;
373 * Application audio thread group.
376 public static final int THREAD_GROUP_AUDIO_APP = 3;
379 * System audio thread group.
382 public static final int THREAD_GROUP_AUDIO_SYS = 4;
385 * Thread group for top foreground app.
388 public static final int THREAD_GROUP_TOP_APP = 5;
390 public static final int SIGNAL_QUIT = 3;
391 public static final int SIGNAL_KILL = 9;
392 public static final int SIGNAL_USR1 = 10;
394 private static long sStartElapsedRealtime;
395 private static long sStartUptimeMillis;
398 * State for communicating with the zygote process.
400 * @hide for internal use only.
402 public static class ZygoteState {
403 final LocalSocket socket;
404 final DataInputStream inputStream;
405 final BufferedWriter writer;
406 final List<String> abiList;
410 private ZygoteState(LocalSocket socket, DataInputStream inputStream,
411 BufferedWriter writer, List<String> abiList) {
412 this.socket = socket;
413 this.inputStream = inputStream;
414 this.writer = writer;
415 this.abiList = abiList;
418 public static ZygoteState connect(String socketAddress) throws IOException {
419 DataInputStream zygoteInputStream = null;
420 BufferedWriter zygoteWriter = null;
421 final LocalSocket zygoteSocket = new LocalSocket();
424 zygoteSocket.connect(new LocalSocketAddress(socketAddress,
425 LocalSocketAddress.Namespace.RESERVED));
427 zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
429 zygoteWriter = new BufferedWriter(new OutputStreamWriter(
430 zygoteSocket.getOutputStream()), 256);
431 } catch (IOException ex) {
433 zygoteSocket.close();
434 } catch (IOException ignore) {
440 String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
441 Log.i("Zygote", "Process: zygote socket opened, supported ABIS: " + abiListString);
443 return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
444 Arrays.asList(abiListString.split(",")));
447 boolean matches(String abi) {
448 return abiList.contains(abi);
451 public void close() {
454 } catch (IOException ex) {
455 Log.e(LOG_TAG,"I/O exception on routine close", ex);
467 * The state of the connection to the primary zygote.
469 static ZygoteState primaryZygoteState;
472 * The state of the connection to the secondary zygote.
474 static ZygoteState secondaryZygoteState;
477 * Start a new process.
479 * <p>If processes are enabled, a new process is created and the
480 * static main() function of a <var>processClass</var> is executed there.
481 * The process will continue running after this function returns.
483 * <p>If processes are not enabled, a new thread in the caller's
484 * process is created and main() of <var>processClass</var> called there.
486 * <p>The niceName parameter, if not an empty string, is a custom name to
487 * give to the process instead of using processClass. This allows you to
488 * make easily identifyable processes even if you are using the same base
489 * <var>processClass</var> to start them.
491 * @param processClass The class to use as the process's main entry
493 * @param niceName A more readable name to use for the process.
494 * @param uid The user-id under which the process will run.
495 * @param gid The group-id under which the process will run.
496 * @param gids Additional group-ids associated with the process.
497 * @param debugFlags Additional flags.
498 * @param targetSdkVersion The target SDK version for the app.
499 * @param seInfo null-ok SELinux information for the new process.
500 * @param abi non-null the ABI this app should be started with.
501 * @param instructionSet null-ok the instruction set to use.
502 * @param appDataDir null-ok the data directory of the app.
503 * @param zygoteArgs Additional arguments to supply to the zygote process.
505 * @return An object that describes the result of the attempt to start the process.
506 * @throws RuntimeException on fatal start failure
510 public static final ProcessStartResult start(final String processClass,
511 final String niceName,
512 int uid, int gid, int[] gids,
513 int debugFlags, int mountExternal,
514 int targetSdkVersion,
517 String instructionSet,
519 String[] zygoteArgs) {
521 return startViaZygote(processClass, niceName, uid, gid, gids,
522 debugFlags, mountExternal, targetSdkVersion, seInfo,
523 abi, instructionSet, appDataDir, zygoteArgs);
524 } catch (ZygoteStartFailedEx ex) {
526 "Starting VM process through Zygote failed");
527 throw new RuntimeException(
528 "Starting VM process through Zygote failed", ex);
532 /** retry interval for opening a zygote socket */
533 static final int ZYGOTE_RETRY_MILLIS = 500;
536 * Queries the zygote for the list of ABIS it supports.
538 * @throws ZygoteStartFailedEx if the query failed.
540 private static String getAbiList(BufferedWriter writer, DataInputStream inputStream)
542 // Each query starts with the argument count (1 in this case)
544 // ... followed by a new-line.
546 // ... followed by our only argument.
547 writer.write("--query-abi-list");
551 // The response is a length prefixed stream of ASCII bytes.
552 int numBytes = inputStream.readInt();
553 byte[] bytes = new byte[numBytes];
554 inputStream.readFully(bytes);
556 return new String(bytes, StandardCharsets.US_ASCII);
560 * Sends an argument list to the zygote process, which starts a new child
561 * and returns the child's pid. Please note: the present implementation
562 * replaces newlines in the argument list with spaces.
564 * @throws ZygoteStartFailedEx if process start failed for any reason
566 private static ProcessStartResult zygoteSendArgsAndGetResult(
567 ZygoteState zygoteState, ArrayList<String> args)
568 throws ZygoteStartFailedEx {
570 // Throw early if any of the arguments are malformed. This means we can
571 // avoid writing a partial response to the zygote.
572 int sz = args.size();
573 for (int i = 0; i < sz; i++) {
574 if (args.get(i).indexOf('\n') >= 0) {
575 throw new ZygoteStartFailedEx("embedded newlines not allowed");
580 * See com.android.internal.os.ZygoteInit.readArgumentList()
581 * Presently the wire format to the zygote process is:
582 * a) a count of arguments (argc, in essence)
583 * b) a number of newline-separated argument strings equal to count
585 * After the zygote process reads these it will write the pid of
586 * the child or -1 on failure, followed by boolean to
587 * indicate whether a wrapper process was used.
589 final BufferedWriter writer = zygoteState.writer;
590 final DataInputStream inputStream = zygoteState.inputStream;
592 writer.write(Integer.toString(args.size()));
595 for (int i = 0; i < sz; i++) {
596 String arg = args.get(i);
603 // Should there be a timeout on this?
604 ProcessStartResult result = new ProcessStartResult();
606 // Always read the entire result from the input stream to avoid leaving
607 // bytes in the stream for future process starts to accidentally stumble
609 result.pid = inputStream.readInt();
610 result.usingWrapper = inputStream.readBoolean();
612 if (result.pid < 0) {
613 throw new ZygoteStartFailedEx("fork() failed");
616 } catch (IOException ex) {
618 throw new ZygoteStartFailedEx(ex);
623 * Starts a new process via the zygote mechanism.
625 * @param processClass Class name whose static main() to run
626 * @param niceName 'nice' process name to appear in ps
627 * @param uid a POSIX uid that the new process should setuid() to
628 * @param gid a POSIX gid that the new process shuold setgid() to
629 * @param gids null-ok; a list of supplementary group IDs that the
630 * new process should setgroup() to.
631 * @param debugFlags Additional flags.
632 * @param targetSdkVersion The target SDK version for the app.
633 * @param seInfo null-ok SELinux information for the new process.
634 * @param abi the ABI the process should use.
635 * @param instructionSet null-ok the instruction set to use.
636 * @param appDataDir null-ok the data directory of the app.
637 * @param extraArgs Additional arguments to supply to the zygote process.
638 * @return An object that describes the result of the attempt to start the process.
639 * @throws ZygoteStartFailedEx if process start failed for any reason
641 private static ProcessStartResult startViaZygote(final String processClass,
642 final String niceName,
643 final int uid, final int gid,
645 int debugFlags, int mountExternal,
646 int targetSdkVersion,
649 String instructionSet,
652 throws ZygoteStartFailedEx {
653 synchronized(Process.class) {
654 ArrayList<String> argsForZygote = new ArrayList<String>();
656 // --runtime-args, --setuid=, --setgid=,
657 // and --setgroups= must go first
658 argsForZygote.add("--runtime-args");
659 argsForZygote.add("--setuid=" + uid);
660 argsForZygote.add("--setgid=" + gid);
661 if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
662 argsForZygote.add("--enable-jni-logging");
664 if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
665 argsForZygote.add("--enable-safemode");
667 if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
668 argsForZygote.add("--enable-debugger");
670 if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
671 argsForZygote.add("--enable-checkjni");
673 if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
674 argsForZygote.add("--generate-debug-info");
676 if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {
677 argsForZygote.add("--always-jit");
679 if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {
680 argsForZygote.add("--native-debuggable");
682 if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
683 argsForZygote.add("--enable-assert");
685 if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
686 argsForZygote.add("--mount-external-default");
687 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
688 argsForZygote.add("--mount-external-read");
689 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
690 argsForZygote.add("--mount-external-write");
692 argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
694 //TODO optionally enable debuger
695 //argsForZygote.add("--enable-debugger");
697 // --setgroups is a comma-separated list
698 if (gids != null && gids.length > 0) {
699 StringBuilder sb = new StringBuilder();
700 sb.append("--setgroups=");
702 int sz = gids.length;
703 for (int i = 0; i < sz; i++) {
710 argsForZygote.add(sb.toString());
713 if (niceName != null) {
714 argsForZygote.add("--nice-name=" + niceName);
717 if (seInfo != null) {
718 argsForZygote.add("--seinfo=" + seInfo);
721 if (instructionSet != null) {
722 argsForZygote.add("--instruction-set=" + instructionSet);
725 if (appDataDir != null) {
726 argsForZygote.add("--app-data-dir=" + appDataDir);
729 argsForZygote.add(processClass);
731 if (extraArgs != null) {
732 for (String arg : extraArgs) {
733 argsForZygote.add(arg);
737 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
742 * Tries to establish a connection to the zygote that handles a given {@code abi}. Might block and retry if the
743 * zygote is unresponsive. This method is a no-op if a connection is already open.
747 public static void establishZygoteConnectionForAbi(String abi) {
749 openZygoteSocketIfNeeded(abi);
750 } catch (ZygoteStartFailedEx ex) {
751 throw new RuntimeException("Unable to connect to zygote for abi: " + abi, ex);
756 * Tries to open socket to Zygote process if not already open. If
757 * already open, does nothing. May block and retry.
759 private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
760 if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
762 primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
763 } catch (IOException ioe) {
764 throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
768 if (primaryZygoteState.matches(abi)) {
769 return primaryZygoteState;
772 // The primary zygote didn't match. Try the secondary.
773 if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
775 secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
776 } catch (IOException ioe) {
777 throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
781 if (secondaryZygoteState.matches(abi)) {
782 return secondaryZygoteState;
785 throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
789 * Returns elapsed milliseconds of the time this process has run.
790 * @return Returns the number of milliseconds this process has return.
792 public static final native long getElapsedCpuTime();
795 * Return the {@link SystemClock#elapsedRealtime()} at which this process was started.
797 public static final long getStartElapsedRealtime() {
798 return sStartElapsedRealtime;
802 * Return the {@link SystemClock#uptimeMillis()} at which this process was started.
804 public static final long getStartUptimeMillis() {
805 return sStartUptimeMillis;
809 public static final void setStartTimes(long elapsedRealtime, long uptimeMillis) {
810 sStartElapsedRealtime = elapsedRealtime;
811 sStartUptimeMillis = uptimeMillis;
815 * Returns true if the current process is a 64-bit runtime.
817 public static final boolean is64Bit() {
818 return VMRuntime.getRuntime().is64Bit();
822 * Returns the identifier of this process, which can be used with
823 * {@link #killProcess} and {@link #sendSignal}.
825 public static final int myPid() {
830 * Returns the identifier of this process' parent.
833 public static final int myPpid() {
838 * Returns the identifier of the calling thread, which be used with
839 * {@link #setThreadPriority(int, int)}.
841 public static final int myTid() {
846 * Returns the identifier of this process's uid. This is the kernel uid
847 * that the process is running under, which is the identity of its
848 * app-specific sandbox. It is different from {@link #myUserHandle} in that
849 * a uid identifies a specific app sandbox in a specific user.
851 public static final int myUid() {
856 * Returns this process's user handle. This is the
857 * user the process is running under. It is distinct from
858 * {@link #myUid()} in that a particular user will have multiple
859 * distinct apps running under it each with their own uid.
861 public static UserHandle myUserHandle() {
862 return UserHandle.of(UserHandle.getUserId(myUid()));
866 * Returns whether the given uid belongs to an application.
867 * @param uid A kernel uid.
868 * @return Whether the uid corresponds to an application sandbox running in
871 public static boolean isApplicationUid(int uid) {
872 return UserHandle.isApp(uid);
876 * Returns whether the current process is in an isolated sandbox.
879 public static final boolean isIsolated() {
880 return isIsolated(myUid());
884 public static final boolean isIsolated(int uid) {
885 uid = UserHandle.getAppId(uid);
886 return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
890 * Returns the UID assigned to a particular user name, or -1 if there is
891 * none. If the given string consists of only numbers, it is converted
894 public static final native int getUidForName(String name);
897 * Returns the GID assigned to a particular user name, or -1 if there is
898 * none. If the given string consists of only numbers, it is converted
901 public static final native int getGidForName(String name);
904 * Returns a uid for a currently running process.
905 * @param pid the process id
906 * @return the uid of the process, or -1 if the process is not running.
907 * @hide pending API council review
909 public static final int getUidForPid(int pid) {
910 String[] procStatusLabels = { "Uid:" };
911 long[] procStatusValues = new long[1];
912 procStatusValues[0] = -1;
913 Process.readProcLines("/proc/" + pid + "/status", procStatusLabels, procStatusValues);
914 return (int) procStatusValues[0];
918 * Returns the parent process id for a currently running process.
919 * @param pid the process id
920 * @return the parent process id of the process, or -1 if the process is not running.
923 public static final int getParentPid(int pid) {
924 String[] procStatusLabels = { "PPid:" };
925 long[] procStatusValues = new long[1];
926 procStatusValues[0] = -1;
927 Process.readProcLines("/proc/" + pid + "/status", procStatusLabels, procStatusValues);
928 return (int) procStatusValues[0];
932 * Returns the thread group leader id for a currently running thread.
933 * @param tid the thread id
934 * @return the thread group leader id of the thread, or -1 if the thread is not running.
935 * This is same as what getpid(2) would return if called by tid.
938 public static final int getThreadGroupLeader(int tid) {
939 String[] procStatusLabels = { "Tgid:" };
940 long[] procStatusValues = new long[1];
941 procStatusValues[0] = -1;
942 Process.readProcLines("/proc/" + tid + "/status", procStatusLabels, procStatusValues);
943 return (int) procStatusValues[0];
947 * Set the priority of a thread, based on Linux priorities.
949 * @param tid The identifier of the thread/process to change.
950 * @param priority A Linux priority level, from -20 for highest scheduling
951 * priority to 19 for lowest scheduling priority.
953 * @throws IllegalArgumentException Throws IllegalArgumentException if
954 * <var>tid</var> does not exist.
955 * @throws SecurityException Throws SecurityException if your process does
956 * not have permission to modify the given thread, or to use the given
959 public static final native void setThreadPriority(int tid, int priority)
960 throws IllegalArgumentException, SecurityException;
963 * Call with 'false' to cause future calls to {@link #setThreadPriority(int)} to
964 * throw an exception if passed a background-level thread priority. This is only
965 * effective if the JNI layer is built with GUARD_THREAD_PRIORITY defined to 1.
969 public static final native void setCanSelfBackground(boolean backgroundOk);
972 * Sets the scheduling group for a thread.
974 * @param tid The identifier of the thread to change.
975 * @param group The target group for this thread from THREAD_GROUP_*.
977 * @throws IllegalArgumentException Throws IllegalArgumentException if
978 * <var>tid</var> does not exist.
979 * @throws SecurityException Throws SecurityException if your process does
980 * not have permission to modify the given thread, or to use the given
982 * If the thread is a thread group leader, that is it's gettid() == getpid(),
983 * then the other threads in the same thread group are _not_ affected.
985 * Does not set cpuset for some historical reason, just calls
986 * libcutils::set_sched_policy().
988 public static final native void setThreadGroup(int tid, int group)
989 throws IllegalArgumentException, SecurityException;
992 * Sets the scheduling group for a process and all child threads
994 * @param pid The identifier of the process to change.
995 * @param group The target group for this process from THREAD_GROUP_*.
997 * @throws IllegalArgumentException Throws IllegalArgumentException if
998 * <var>tid</var> does not exist.
999 * @throws SecurityException Throws SecurityException if your process does
1000 * not have permission to modify the given thread, or to use the given
1003 * group == THREAD_GROUP_DEFAULT means to move all non-background priority
1004 * threads to the foreground scheduling group, but to leave background
1005 * priority threads alone. group == THREAD_GROUP_BG_NONINTERACTIVE moves all
1006 * threads, regardless of priority, to the background scheduling group.
1007 * group == THREAD_GROUP_FOREGROUND is not allowed.
1009 * Always sets cpusets.
1011 public static final native void setProcessGroup(int pid, int group)
1012 throws IllegalArgumentException, SecurityException;
1015 * Return the scheduling group of requested process.
1019 public static final native int getProcessGroup(int pid)
1020 throws IllegalArgumentException, SecurityException;
1023 * On some devices, the foreground process may have one or more CPU
1024 * cores exclusively reserved for it. This method can be used to
1025 * retrieve which cores that are (if any), so the calling process
1026 * can then use sched_setaffinity() to lock a thread to these cores.
1027 * Note that the calling process must currently be running in the
1028 * foreground for this method to return any cores.
1030 * The CPU core(s) exclusively reserved for the foreground process will
1031 * stay reserved for as long as the process stays in the foreground.
1033 * As soon as a process leaves the foreground, those CPU cores will
1034 * no longer be reserved for it, and will most likely be reserved for
1035 * the new foreground process. It's not necessary to change the affinity
1036 * of your process when it leaves the foreground (if you had previously
1037 * set it to use a reserved core); the OS will automatically take care
1038 * of resetting the affinity at that point.
1040 * @return an array of integers, indicating the CPU cores exclusively
1041 * reserved for this process. The array will have length zero if no
1042 * CPU cores are exclusively reserved for this process at this point
1045 public static final native int[] getExclusiveCores();
1048 * Set the priority of the calling thread, based on Linux priorities. See
1049 * {@link #setThreadPriority(int, int)} for more information.
1051 * @param priority A Linux priority level, from -20 for highest scheduling
1052 * priority to 19 for lowest scheduling priority.
1054 * @throws IllegalArgumentException Throws IllegalArgumentException if
1055 * <var>tid</var> does not exist.
1056 * @throws SecurityException Throws SecurityException if your process does
1057 * not have permission to modify the given thread, or to use the given
1060 * @see #setThreadPriority(int, int)
1062 public static final native void setThreadPriority(int priority)
1063 throws IllegalArgumentException, SecurityException;
1066 * Return the current priority of a thread, based on Linux priorities.
1068 * @param tid The identifier of the thread/process to change.
1070 * @return Returns the current priority, as a Linux priority level,
1071 * from -20 for highest scheduling priority to 19 for lowest scheduling
1074 * @throws IllegalArgumentException Throws IllegalArgumentException if
1075 * <var>tid</var> does not exist.
1077 public static final native int getThreadPriority(int tid)
1078 throws IllegalArgumentException;
1081 * Return the current scheduling policy of a thread, based on Linux.
1083 * @param tid The identifier of the thread/process to get the scheduling policy.
1085 * @throws IllegalArgumentException Throws IllegalArgumentException if
1086 * <var>tid</var> does not exist, or if <var>priority</var> is out of range for the policy.
1087 * @throws SecurityException Throws SecurityException if your process does
1088 * not have permission to modify the given thread, or to use the given
1089 * scheduling policy or priority.
1095 public static final native int getThreadScheduler(int tid)
1096 throws IllegalArgumentException;
1099 * Set the scheduling policy and priority of a thread, based on Linux.
1101 * @param tid The identifier of the thread/process to change.
1102 * @param policy A Linux scheduling policy such as SCHED_OTHER etc.
1103 * @param priority A Linux priority level in a range appropriate for the given policy.
1105 * @throws IllegalArgumentException Throws IllegalArgumentException if
1106 * <var>tid</var> does not exist, or if <var>priority</var> is out of range for the policy.
1107 * @throws SecurityException Throws SecurityException if your process does
1108 * not have permission to modify the given thread, or to use the given
1109 * scheduling policy or priority.
1114 public static final native void setThreadScheduler(int tid, int policy, int priority)
1115 throws IllegalArgumentException;
1118 * Determine whether the current environment supports multiple processes.
1120 * @return Returns true if the system can run in multiple processes, else
1121 * false if everything is running in a single process.
1123 * @deprecated This method always returns true. Do not use.
1126 public static final boolean supportsProcesses() {
1131 * Adjust the swappiness level for a process.
1133 * @param pid The process identifier to set.
1134 * @param is_increased Whether swappiness should be increased or default.
1136 * @return Returns true if the underlying system supports this
1137 * feature, else false.
1141 public static final native boolean setSwappiness(int pid, boolean is_increased);
1144 * Change this process's argv[0] parameter. This can be useful to show
1145 * more descriptive information in things like the 'ps' command.
1147 * @param text The new name of this process.
1151 public static final native void setArgV0(String text);
1154 * Kill the process with the given PID.
1155 * Note that, though this API allows us to request to
1156 * kill any process based on its PID, the kernel will
1157 * still impose standard restrictions on which PIDs you
1158 * are actually able to kill. Typically this means only
1159 * the process running the caller's packages/application
1160 * and any additional processes created by that app; packages
1161 * sharing a common UID will also be able to kill each
1162 * other's processes.
1164 public static final void killProcess(int pid) {
1165 sendSignal(pid, SIGNAL_KILL);
1169 public static final native int setUid(int uid);
1172 public static final native int setGid(int uid);
1175 * Send a signal to the given process.
1177 * @param pid The pid of the target process.
1178 * @param signal The signal to send.
1180 public static final native void sendSignal(int pid, int signal);
1184 * Private impl for avoiding a log message... DO NOT USE without doing
1185 * your own log, or the Android Illuminati will find you some night and
1188 public static final void killProcessQuiet(int pid) {
1189 sendSignalQuiet(pid, SIGNAL_KILL);
1194 * Private impl for avoiding a log message... DO NOT USE without doing
1195 * your own log, or the Android Illuminati will find you some night and
1198 public static final native void sendSignalQuiet(int pid, int signal);
1201 public static final native long getFreeMemory();
1204 public static final native long getTotalMemory();
1207 public static final native void readProcLines(String path,
1208 String[] reqFields, long[] outSizes);
1211 public static final native int[] getPids(String path, int[] lastArray);
1214 public static final int PROC_TERM_MASK = 0xff;
1216 public static final int PROC_ZERO_TERM = 0;
1218 public static final int PROC_SPACE_TERM = (int)' ';
1220 public static final int PROC_TAB_TERM = (int)'\t';
1222 public static final int PROC_COMBINE = 0x100;
1224 public static final int PROC_PARENS = 0x200;
1226 public static final int PROC_QUOTES = 0x400;
1228 public static final int PROC_CHAR = 0x800;
1230 public static final int PROC_OUT_STRING = 0x1000;
1232 public static final int PROC_OUT_LONG = 0x2000;
1234 public static final int PROC_OUT_FLOAT = 0x4000;
1237 public static final native boolean readProcFile(String file, int[] format,
1238 String[] outStrings, long[] outLongs, float[] outFloats);
1241 public static final native boolean parseProcLine(byte[] buffer, int startIndex,
1242 int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
1245 public static final native int[] getPidsForCommands(String[] cmds);
1248 * Gets the total Pss value for a given process, in bytes.
1250 * @param pid the process to the Pss for
1251 * @return the total Pss value for the given process in bytes,
1252 * or -1 if the value cannot be determined
1255 public static final native long getPss(int pid);
1258 * Specifies the outcome of having started a process.
1261 public static final class ProcessStartResult {
1263 * The PID of the newly started process.
1264 * Always >= 0. (If the start failed, an exception will have been thrown instead.)
1269 * True if the process was started with a wrapper attached.
1271 public boolean usingWrapper;
1275 * Kill all processes in a process group started for the given
1279 public static final native int killProcessGroup(int uid, int pid);
1282 * Remove all process groups. Expected to be called when ActivityManager
1286 public static final native void removeAllProcessGroups();
1289 * Check to see if a thread belongs to a given process. This may require
1290 * more permissions than apps generally have.
1291 * @return true if this thread belongs to a process
1294 public static final boolean isThreadInProcess(int tid, int pid) {
1295 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1297 if (Os.access("/proc/" + tid + "/task/" + pid, OsConstants.F_OK)) {
1302 } catch (Exception e) {
1305 StrictMode.setThreadPolicy(oldPolicy);