/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.system.StructPollfd; import android.util.Pair; import android.webkit.WebViewZygote; import dalvik.system.VMRuntime; import libcore.io.IoUtils; import java.io.FileDescriptor; import java.util.Map; import java.util.concurrent.TimeoutException; /** * Tools for managing OS processes. */ public class Process { private static final String LOG_TAG = "Process"; /** * An invalid UID value. */ public static final int INVALID_UID = -1; /** * Defines the root UID. */ public static final int ROOT_UID = 0; /** * Defines the UID/GID under which system code runs. */ public static final int SYSTEM_UID = 1000; /** * Defines the UID/GID under which the telephony code runs. */ public static final int PHONE_UID = 1001; /** * Defines the UID/GID for the user shell. */ public static final int SHELL_UID = 2000; /** * Defines the UID/GID for the log group. * @hide */ @UnsupportedAppUsage public static final int LOG_UID = 1007; /** * Defines the UID/GID for the WIFI native processes like wificond, supplicant, hostapd, * vendor HAL, etc. */ public static final int WIFI_UID = 1010; /** * Defines the UID/GID for the mediaserver process. * @hide */ @UnsupportedAppUsage public static final int MEDIA_UID = 1013; /** * Defines the UID/GID for the DRM process. * @hide */ @UnsupportedAppUsage public static final int DRM_UID = 1019; /** * Defines the GID for the group that allows write access to the internal media storage. * @hide */ public static final int SDCARD_RW_GID = 1015; /** * Defines the UID/GID for the group that controls VPN services. * @hide */ @UnsupportedAppUsage public static final int VPN_UID = 1016; /** * Defines the UID/GID for keystore. * @hide */ public static final int KEYSTORE_UID = 1017; /** * Defines the UID/GID for credstore. * @hide */ public static final int CREDSTORE_UID = 1076; /** * Defines the UID/GID for the NFC service process. * @hide */ @UnsupportedAppUsage public static final int NFC_UID = 1027; /** * Defines the UID/GID for the clatd process. * @hide * */ public static final int CLAT_UID = 1029; /** * Defines the UID/GID for the Bluetooth service process. */ public static final int BLUETOOTH_UID = 1002; /** * Defines the GID for the group that allows write access to the internal media storage. * @hide */ public static final int MEDIA_RW_GID = 1023; /** * Access to installed package details * @hide */ public static final int PACKAGE_INFO_GID = 1032; /** * Defines the UID/GID for the shared RELRO file updater process. * @hide */ public static final int SHARED_RELRO_UID = 1037; /** * Defines the UID/GID for the audioserver process. * @hide */ public static final int AUDIOSERVER_UID = 1041; /** * Defines the UID/GID for the cameraserver process * @hide */ public static final int CAMERASERVER_UID = 1047; /** * Defines the UID/GID for the tethering DNS resolver (currently dnsmasq). * @hide */ public static final int DNS_TETHER_UID = 1052; /** * Defines the UID/GID for the WebView zygote process. * @hide */ public static final int WEBVIEW_ZYGOTE_UID = 1053; /** * Defines the UID used for resource tracking for OTA updates. * @hide */ public static final int OTA_UPDATE_UID = 1061; /** * Defines the UID used for statsd * @hide */ public static final int STATSD_UID = 1066; /** * Defines the UID used for incidentd. * @hide */ public static final int INCIDENTD_UID = 1067; /** * Defines the UID/GID for the Secure Element service process. * @hide */ public static final int SE_UID = 1068; /** * Defines the UID/GID for the NetworkStack app. * @hide */ public static final int NETWORK_STACK_UID = 1073; /** * Defines the UID/GID for fs-verity certificate ownership in keystore. * @hide */ public static final int FSVERITY_CERT_UID = 1075; /** * GID that gives write access to app-private data directories on external * storage (used on devices without sdcardfs only). * @hide */ public static final int EXT_DATA_RW_GID = 1078; /** * GID that gives write access to app-private OBB directories on external * storage (used on devices without sdcardfs only). * @hide */ public static final int EXT_OBB_RW_GID = 1079; /** {@hide} */ public static final int NOBODY_UID = 9999; /** * Defines the start of a range of UIDs (and GIDs), going from this * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning * to applications. */ public static final int FIRST_APPLICATION_UID = 10000; /** * Last of application-specific UIDs starting at * {@link #FIRST_APPLICATION_UID}. */ public static final int LAST_APPLICATION_UID = 19999; /** * First uid used for fully isolated sandboxed processes spawned from an app zygote * @hide */ @TestApi public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; /** * Number of UIDs we allocate per application zygote * @hide */ @TestApi public static final int NUM_UIDS_PER_APP_ZYGOTE = 100; /** * Last uid used for fully isolated sandboxed processes spawned from an app zygote * @hide */ @TestApi public static final int LAST_APP_ZYGOTE_ISOLATED_UID = 98999; /** * First uid used for fully isolated sandboxed processes (with no permissions of their own) * @hide */ @UnsupportedAppUsage @TestApi public static final int FIRST_ISOLATED_UID = 99000; /** * Last uid used for fully isolated sandboxed processes (with no permissions of their own) * @hide */ @UnsupportedAppUsage @TestApi public static final int LAST_ISOLATED_UID = 99999; /** * Defines the gid shared by all applications running under the same profile. * @hide */ public static final int SHARED_USER_GID = 9997; /** * First gid for applications to share resources. Used when forward-locking * is enabled but all UserHandles need to be able to read the resources. * @hide */ public static final int FIRST_SHARED_APPLICATION_GID = 50000; /** * Last gid for applications to share resources. Used when forward-locking * is enabled but all UserHandles need to be able to read the resources. * @hide */ public static final int LAST_SHARED_APPLICATION_GID = 59999; /** {@hide} */ public static final int FIRST_APPLICATION_CACHE_GID = 20000; /** {@hide} */ public static final int LAST_APPLICATION_CACHE_GID = 29999; /** * Standard priority of application threads. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_DEFAULT = 0; /* * *************************************** * ** Keep in sync with utils/threads.h ** * *************************************** */ /** * Lowest available thread priority. Only for those who really, really * don't want to run if anything else is happening. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_LOWEST = 19; /** * Standard priority background threads. This gives your thread a slightly * lower than normal priority, so that it will have less chance of impacting * the responsiveness of the user interface. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_BACKGROUND = 10; /** * Standard priority of threads that are currently running a user interface * that the user is interacting with. Applications can not normally * change to this priority; the system will automatically adjust your * application threads as the user moves through the UI. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_FOREGROUND = -2; /** * Standard priority of system display threads, involved in updating * the user interface. Applications can not * normally change to this priority. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_DISPLAY = -4; /** * Standard priority of the most important display threads, for compositing * the screen and retrieving input events. Applications can not normally * change to this priority. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8; /** * Standard priority of video threads. Applications can not normally * change to this priority. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_VIDEO = -10; /** * Standard priority of audio threads. Applications can not normally * change to this priority. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_AUDIO = -16; /** * Standard priority of the most important audio threads. * Applications can not normally change to this priority. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, not with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_URGENT_AUDIO = -19; /** * Minimum increment to make a priority more favorable. */ public static final int THREAD_PRIORITY_MORE_FAVORABLE = -1; /** * Minimum increment to make a priority less favorable. */ public static final int THREAD_PRIORITY_LESS_FAVORABLE = +1; /** * Default scheduling policy * @hide */ public static final int SCHED_OTHER = 0; /** * First-In First-Out scheduling policy * @hide */ public static final int SCHED_FIFO = 1; /** * Round-Robin scheduling policy * @hide */ public static final int SCHED_RR = 2; /** * Batch scheduling policy * @hide */ public static final int SCHED_BATCH = 3; /** * Idle scheduling policy * @hide */ public static final int SCHED_IDLE = 5; /** * Reset scheduler choice on fork. * @hide */ public static final int SCHED_RESET_ON_FORK = 0x40000000; // Keep in sync with SP_* constants of enum type SchedPolicy // declared in system/core/include/cutils/sched_policy.h, // except THREAD_GROUP_DEFAULT does not correspond to any SP_* value. /** * Default thread group - * has meaning with setProcessGroup() only, cannot be used with setThreadGroup(). * When used with setProcessGroup(), the group of each thread in the process * is conditionally changed based on that thread's current priority, as follows: * threads with priority numerically less than THREAD_PRIORITY_BACKGROUND * are moved to foreground thread group. All other threads are left unchanged. * @hide */ public static final int THREAD_GROUP_DEFAULT = -1; /** * Background thread group - All threads in * this group are scheduled with a reduced share of the CPU. * Value is same as constant SP_BACKGROUND of enum SchedPolicy. * @hide */ public static final int THREAD_GROUP_BACKGROUND = 0; /** * Foreground thread group - All threads in * this group are scheduled with a normal share of the CPU. * Value is same as constant SP_FOREGROUND of enum SchedPolicy. * Not used at this level. * @hide **/ private static final int THREAD_GROUP_FOREGROUND = 1; /** * System thread group. * @hide **/ public static final int THREAD_GROUP_SYSTEM = 2; /** * Application audio thread group. * @hide **/ public static final int THREAD_GROUP_AUDIO_APP = 3; /** * System audio thread group. * @hide **/ public static final int THREAD_GROUP_AUDIO_SYS = 4; /** * Thread group for top foreground app. * @hide **/ public static final int THREAD_GROUP_TOP_APP = 5; /** * Thread group for RT app. * @hide **/ public static final int THREAD_GROUP_RT_APP = 6; /** * Thread group for bound foreground services that should * have additional CPU restrictions during screen off * @hide **/ public static final int THREAD_GROUP_RESTRICTED = 7; public static final int SIGNAL_QUIT = 3; public static final int SIGNAL_KILL = 9; public static final int SIGNAL_USR1 = 10; private static long sStartElapsedRealtime; private static long sStartUptimeMillis; private static final int PIDFD_UNKNOWN = 0; private static final int PIDFD_SUPPORTED = 1; private static final int PIDFD_UNSUPPORTED = 2; /** * Whether or not the underlying OS supports pidfd */ private static int sPidFdSupported = PIDFD_UNKNOWN; /** * Value used to indicate that there is no special information about an application launch. App * launches with this policy will occur through the primary or secondary Zygote with no special * treatment. * * @hide */ public static final int ZYGOTE_POLICY_FLAG_EMPTY = 0; /** * Flag used to indicate that an application launch is user-visible and latency sensitive. Any * launch with this policy will use a Unspecialized App Process Pool if the target Zygote * supports it. * * @hide */ public static final int ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE = 1 << 0; /** * Flag used to indicate that the launch is one in a series of app launches that will be * performed in quick succession. For future use. * * @hide */ public static final int ZYGOTE_POLICY_FLAG_BATCH_LAUNCH = 1 << 1; /** * Flag used to indicate that the current launch event is for a system process. All system * processes are equally important, so none of them should be prioritized over the others. * * @hide */ public static final int ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS = 1 << 2; /** * State associated with the zygote process. * @hide */ public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess(); /** * Start a new process. * *
If processes are enabled, a new process is created and the * static main() function of a processClass is executed there. * The process will continue running after this function returns. * *
If processes are not enabled, a new thread in the caller's * process is created and main() of processClass called there. * *
The niceName parameter, if not an empty string, is a custom name to
* give to the process instead of using processClass. This allows you to
* make easily identifyable processes even if you are using the same base
* processClass to start them.
*
* When invokeWith is not null, the process will be started as a fresh app
* and not a zygote fork. Note that this is only allowed for uid 0 or when
* runtimeFlags contains DEBUG_ENABLE_DEBUGGER.
*
* @param processClass The class to use as the process's main entry
* point.
* @param niceName A more readable name to use for the process.
* @param uid The user-id under which the process will run.
* @param gid The group-id under which the process will run.
* @param gids Additional group-ids associated with the process.
* @param runtimeFlags Additional flags for the runtime.
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
* @param abi non-null the ABI this app should be started with.
* @param instructionSet null-ok the instruction set to use.
* @param appDataDir null-ok the data directory of the app.
* @param invokeWith null-ok the command to invoke with.
* @param packageName null-ok the name of the package this process belongs to.
* @param zygotePolicyFlags Flags used to determine how to launch the application
* @param isTopApp whether the process starts for high priority application.
* @param disabledCompatChanges null-ok list of disabled compat changes for the process being
* started.
* @param pkgDataInfoMap Map from related package names to private data directory
* volume UUID and inode number.
* @param whitelistedDataInfoMap Map from whitelisted package names to private data directory
* volume UUID and inode number.
* @param bindMountAppsData whether zygote needs to mount CE and DE data.
* @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
* @param zygoteArgs Additional arguments to supply to the zygote process.
* @return An object that describes the result of the attempt to start the process.
* @throws RuntimeException on fatal start failure
*
* {@hide}
*/
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map The format is a list of integers, where every integer describes a variable in the file. It
* specifies how the variable is syntactically terminated (e.g. {@link Process#PROC_SPACE_TERM},
* {@link Process#PROC_TAB_TERM}, {@link Process#PROC_ZERO_TERM}, {@link
* Process#PROC_NEWLINE_TERM}).
*
* If the variable should be parsed and returned to the caller, the termination type should
* be binary OR'd with the type of output (e.g. {@link Process#PROC_OUT_STRING}, {@link
* Process#PROC_OUT_LONG}, {@link Process#PROC_OUT_FLOAT}.
*
* If the variable is wrapped in quotation marks it should be binary OR'd with {@link
* Process#PROC_QUOTES}. If the variable is wrapped in parentheses it should be binary OR'd with
* {@link Process#PROC_PARENS}.
*
* If the variable is not formatted as a string and should be cast directly from characters
* to a long, the {@link Process#PROC_CHAR} integer should be binary OR'd.
*
* If the terminating character can be repeated, the {@link Process#PROC_COMBINE} integer
* should be binary OR'd.
*
* @param file the path of the {@code proc} file to read
* @param format the format of the file
* @param outStrings the parsed {@code String}s from the file
* @param outLongs the parsed {@code long}s from the file
* @param outFloats the parsed {@code float}s from the file
* @hide
*/
@UnsupportedAppUsage
public static final native boolean readProcFile(String file, int[] format,
String[] outStrings, long[] outLongs, float[] outFloats);
/** @hide */
@UnsupportedAppUsage
public static final native boolean parseProcLine(byte[] buffer, int startIndex,
int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
/** @hide */
@UnsupportedAppUsage
public static final native int[] getPidsForCommands(String[] cmds);
/**
* Gets the total Pss value for a given process, in bytes.
*
* @param pid the process to the Pss for
* @return the total Pss value for the given process in bytes,
* or -1 if the value cannot be determined
* @hide
*/
@UnsupportedAppUsage
public static final native long getPss(int pid);
/** @hide */
public static final native long[] getRss(int pid);
/**
* Specifies the outcome of having started a process.
* @hide
*/
public static final class ProcessStartResult {
/**
* The PID of the newly started process.
* Always >= 0. (If the start failed, an exception will have been thrown instead.)
*/
public int pid;
/**
* True if the process was started with a wrapper attached.
*/
public boolean usingWrapper;
}
/**
* Kill all processes in a process group started for the given
* pid.
* @hide
*/
public static final native int killProcessGroup(int uid, int pid);
/**
* Remove all process groups. Expected to be called when ActivityManager
* is restarted.
* @hide
*/
public static final native void removeAllProcessGroups();
/**
* Check to see if a thread belongs to a given process. This may require
* more permissions than apps generally have.
* @return true if this thread belongs to a process
* @hide
*/
public static final boolean isThreadInProcess(int tid, int pid) {
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
if (Os.access("/proc/" + tid + "/task/" + pid, OsConstants.F_OK)) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
}
/**
* Wait for the death of the given process.
*
* @param pid The process ID to be waited on
* @param timeout The maximum time to wait in milliseconds, or -1 to wait forever
* @hide
*/
public static void waitForProcessDeath(int pid, int timeout)
throws InterruptedException, TimeoutException {
FileDescriptor pidfd = null;
if (sPidFdSupported == PIDFD_UNKNOWN) {
int fd = -1;
try {
fd = nativePidFdOpen(pid, 0);
sPidFdSupported = PIDFD_SUPPORTED;
} catch (ErrnoException e) {
sPidFdSupported = e.errno != OsConstants.ENOSYS
? PIDFD_SUPPORTED : PIDFD_UNSUPPORTED;
} finally {
if (fd >= 0) {
pidfd = new FileDescriptor();
pidfd.setInt$(fd);
}
}
}
boolean fallback = sPidFdSupported == PIDFD_UNSUPPORTED;
if (!fallback) {
try {
if (pidfd == null) {
int fd = nativePidFdOpen(pid, 0);
if (fd >= 0) {
pidfd = new FileDescriptor();
pidfd.setInt$(fd);
} else {
fallback = true;
}
}
if (pidfd != null) {
StructPollfd[] fds = new StructPollfd[] {
new StructPollfd()
};
fds[0].fd = pidfd;
fds[0].events = (short) OsConstants.POLLIN;
fds[0].revents = 0;
fds[0].userData = null;
int res = Os.poll(fds, timeout);
if (res > 0) {
return;
} else if (res == 0) {
throw new TimeoutException();
} else {
// We should get an ErrnoException now
}
}
} catch (ErrnoException e) {
if (e.errno == OsConstants.EINTR) {
throw new InterruptedException();
}
fallback = true;
} finally {
if (pidfd != null) {
IoUtils.closeQuietly(pidfd);
}
}
}
if (fallback) {
boolean infinity = timeout < 0;
long now = System.currentTimeMillis();
final long end = now + timeout;
while (infinity || now < end) {
try {
Os.kill(pid, 0);
} catch (ErrnoException e) {
if (e.errno == OsConstants.ESRCH) {
return;
}
}
Thread.sleep(1);
now = System.currentTimeMillis();
}
}
throw new TimeoutException();
}
private static native int nativePidFdOpen(int pid, int flags) throws ErrnoException;
}