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