diff --git a/README.md b/README.md index 3d17f2e..50e93b8 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,9 @@ -

AndroidProcesses

+

Android Processes

A small Android library to get the current running processes

API License - Maven Central - -

- -

@@ -17,7 +12,7 @@ ___ What is this library for? ------------------------- -This small library can get a list of running apps and does not require any permissions. +This small library can get a list of running processes using root access on an Android device. Why would I need this? ---------------------- @@ -32,76 +27,31 @@ Google has significantly restricted access to `/proc` in Android Nougat. This li Usage ----- -**Get a list of running apps:** - -```java -List processes = AndroidProcesses.getRunningAppProcesses(); -``` - -**Get some information about a process:** - ```java -AndroidAppProcess process = processes.get(location); -String processName = process.name; - -Stat stat = process.stat(); -int pid = stat.getPid(); -int parentProcessId = stat.ppid(); -long startTime = stat.stime(); -int policy = stat.policy(); -char state = stat.state(); - -Statm statm = process.statm(); -long totalSizeOfProcess = statm.getSize(); -long residentSetSize = statm.getResidentSetSize(); - -PackageInfo packageInfo = process.getPackageInfo(context, 0); -String appName = packageInfo.applicationInfo.loadLabel(pm).toString(); -``` - -**Check if your app is in the foreground:** - -```java -if (AndroidProcesses.isMyProcessInTheForeground()) { - // do stuff +// Runs "toolbox ps" in a root shell. This should be run on a background thread. +List processes = ps.run(); +for (ProcessStatusInfo process : processes) { + String processName = process.name; + int pid = process.pid; + long rssSize = process.rss; + // etc. } ``` -**Get a list of application processes that are running on the device:** - -```java -List processes = AndroidProcesses.getRunningAppProcessInfo(ctx); -``` - -Limitations ------------ - -* System apps will not be included on some Android versions because they have a higher SELinux context. -* This is not a full replacement of [getRunningAppProcesses()](http://developer.android.com/intl/zh-cn/reference/android/app/ActivityManager.html#getRunningAppProcesses()). The library does not provide a processes' [pkgList](http://developer.android.com/reference/android/app/ActivityManager.RunningAppProcessInfo.html#pkgList), [lru](http://developer.android.com/intl/zh-cn/reference/android/app/ActivityManager.RunningAppProcessInfo.html#lru), or [importance](http://developer.android.com/intl/zh-cn/reference/android/app/ActivityManager.RunningAppProcessInfo.html#importance). -* This is currently not working on the N developer preview. - Download -------- -Download [the latest AAR](https://repo1.maven.org/maven2/com/jaredrummler/android-processes/1.0.9/android-processes-1.0.9.aar) or grab via Gradle: +Download [the latest AAR](https://repo1.maven.org/maven2/com/jaredrummler/sups/0.0.1/sups-0.0.1.aar) or +grab via Gradle: ```groovy -compile 'com.jaredrummler:android-processes:1.0.9' -``` -or Maven: -```xml - - com.jaredrummler - android-processes - 1.0.9 - aar - +compile 'com.jaredrummler:sups:0.0.1' ``` License -------- - Copyright (C) 2015 Jared Rummler + Copyright (C) 2017 Jared Rummler Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/demo/build.gradle b/demo/build.gradle index c4e5efa..cfbb6fe 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -22,6 +22,5 @@ android { dependencies { compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.jaredrummler:html-builder:1.0.0' - compile project(':library-main') - compile project(':library-sups') + compile project(':library') } diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/App.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/App.java index 0d1693d..f9e5c50 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/App.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/App.java @@ -18,19 +18,28 @@ package com.jaredrummler.android.processes.sample; import android.app.Application; - -import com.jaredrummler.android.processes.AndroidProcesses; import com.jaredrummler.android.processes.sample.picasso.AppIconRequestHandler; +import com.jaredrummler.android.sups.ProcessStatusInfo; +import com.jaredrummler.android.sups.ps; import com.squareup.picasso.Picasso; +import java.util.List; public class App extends Application { @Override public void onCreate() { super.onCreate(); - AndroidProcesses.setLoggingEnabled(true); Picasso.setSingletonInstance(new Picasso.Builder(this) .addRequestHandler(new AppIconRequestHandler(this)) .build()); + +// Runs "toolbox ps" in a root shell. This should be run on a background thread. +List processes = ps.run(); +for (ProcessStatusInfo process : processes) { + String processName = process.name; + int pid = process.pid; + long rssSize = process.rss; + // etc. +} } } diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/activities/MainActivity.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/activities/MainActivity.java index e8cf9d8..2358763 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/activities/MainActivity.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/activities/MainActivity.java @@ -18,13 +18,8 @@ package com.jaredrummler.android.processes.sample.activities; import android.app.Activity; -import android.os.AsyncTask; import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; - import com.jaredrummler.android.processes.sample.fragments.ProcessListFragment; -import com.jaredrummler.android.processes.sample.utils.PsTask; public class MainActivity extends Activity { @@ -35,19 +30,4 @@ public class MainActivity extends Activity { } } - @Override public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, Menu.FIRST, 0, "Run as root"); - return super.onCreateOptionsMenu(menu); - } - - @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case Menu.FIRST: - new PsTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - } diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/adapter/ProcessListAdapter.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/adapter/ProcessListAdapter.java index 59747da..f322df2 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/adapter/ProcessListAdapter.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/adapter/ProcessListAdapter.java @@ -26,25 +26,23 @@ import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; - -import com.jaredrummler.android.processes.models.AndroidAppProcess; import com.jaredrummler.android.processes.sample.R; import com.jaredrummler.android.processes.sample.utils.Utils; +import com.jaredrummler.android.sups.ProcessStatusInfo; import com.squareup.picasso.Picasso; - import java.util.List; import static com.jaredrummler.android.processes.sample.picasso.AppIconRequestHandler.SCHEME_PNAME; public class ProcessListAdapter extends BaseAdapter { - private final List processes; + private final List processes; private final LayoutInflater inflater; private final Context context; private final Picasso picasso; private final int iconSize; - public ProcessListAdapter(Context context, List processes) { + public ProcessListAdapter(Context context, List processes) { this.context = context.getApplicationContext(); this.inflater = LayoutInflater.from(context); this.iconSize = Utils.toPx(context, 46); @@ -56,7 +54,7 @@ public ProcessListAdapter(Context context, List processes) { return processes.size(); } - @Override public AndroidAppProcess getItem(int position) { + @Override public ProcessStatusInfo getItem(int position) { return processes.get(position); } @@ -73,12 +71,12 @@ public ProcessListAdapter(Context context, List processes) { holder = (ViewHolder) convertView.getTag(); } - AndroidAppProcess process = getItem(position); + ProcessStatusInfo process = getItem(position); ImageView imageView = holder.find(R.id.imageView); TextView textView = holder.find(R.id.textView); - picasso.load(Uri.parse(SCHEME_PNAME + ":" + process.getPackageName())) + picasso.load(Uri.parse(SCHEME_PNAME + ":" + process.name)) .placeholder(android.R.drawable.sym_def_app_icon) .resize(iconSize, iconSize) .centerInside() diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/dialogs/ProcessInfoDialog.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/dialogs/ProcessInfoDialog.java index 837fe4f..2bb553f 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/dialogs/ProcessInfoDialog.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/dialogs/ProcessInfoDialog.java @@ -22,26 +22,19 @@ import android.app.DialogFragment; import android.content.DialogInterface; import android.os.Bundle; -import android.os.SystemClock; import android.text.Spanned; -import android.text.format.Formatter; -import android.util.Log; -import com.jaredrummler.android.processes.models.AndroidAppProcess; -import com.jaredrummler.android.processes.models.Stat; -import com.jaredrummler.android.processes.models.Statm; -import com.jaredrummler.android.processes.models.Status; import com.jaredrummler.android.processes.sample.utils.Utils; +import com.jaredrummler.android.sups.ProcessStatusInfo; import com.jaredrummler.android.util.HtmlBuilder; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Locale; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; public class ProcessInfoDialog extends DialogFragment { private static final String TAG = "ProcessInfoDialog"; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - AndroidAppProcess process = getArguments().getParcelable("process"); + ProcessStatusInfo process = getArguments().getParcelable("process"); return new AlertDialog.Builder(getActivity()) .setTitle(Utils.getName(getActivity(), process)) .setMessage(getProcessInfo(process)) @@ -54,76 +47,19 @@ public class ProcessInfoDialog extends DialogFragment { .create(); } - private Spanned getProcessInfo(AndroidAppProcess process) { + private Spanned getProcessInfo(ProcessStatusInfo process) { HtmlBuilder html = new HtmlBuilder(); - - html.p().strong("NAME: ").append(process.name).close(); - html.p().strong("POLICY: ").append(process.foreground ? "fg" : "bg").close(); - html.p().strong("PID: ").append(process.pid).close(); - - try { - Status status = process.status(); - html.p().strong("UID/GID: ").append(status.getUid()).append('/').append(status.getGid()).close(); - } catch (IOException e) { - Log.d(TAG, String.format("Error reading /proc/%d/status.", process.pid)); - } - - // should probably be run in a background thread. - try { - Stat stat = process.stat(); - html.p().strong("PPID: ").append(stat.ppid()).close(); - long bootTime = System.currentTimeMillis() - SystemClock.elapsedRealtime(); - long startTime = bootTime + (10 * stat.starttime()); - SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy KK:mm:ss a", Locale.getDefault()); - html.p().strong("START TIME: ").append(sdf.format(startTime)).close(); - html.p().strong("CPU TIME: ").append((stat.stime() + stat.utime()) / 100).close(); - html.p().strong("NICE: ").append(stat.nice()).close(); - int rtPriority = stat.rt_priority(); - if (rtPriority == 0) { - html.p().strong("SCHEDULING PRIORITY: ").append("non-real-time").close(); - } else if (rtPriority >= 1 && rtPriority <= 99) { - html.p().strong("SCHEDULING PRIORITY: ").append("real-time").close(); + for (Field field : ProcessStatusInfo.class.getDeclaredFields()) { + if (!Modifier.isStatic(field.getModifiers())) { + try { + field.setAccessible(true); + Object value = field.get(process); + html.strong(field.getName()).append(' ').append(value).br(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } } - long userModeTicks = stat.utime(); - long kernelModeTicks = stat.stime(); - long percentOfTimeUserMode; - long percentOfTimeKernelMode; - if ((kernelModeTicks + userModeTicks) > 0) { - percentOfTimeUserMode = (userModeTicks * 100) / (userModeTicks + kernelModeTicks); - percentOfTimeKernelMode = (kernelModeTicks * 100) / (userModeTicks + kernelModeTicks); - html.p().strong("TIME EXECUTED IN USER MODE: ").append(percentOfTimeUserMode + "%").close(); - html.p().strong("TIME EXECUTED IN KERNEL MODE: ").append(percentOfTimeKernelMode + "%").close(); - } - } catch (IOException e) { - Log.d(TAG, String.format("Error reading /proc/%d/stat.", process.pid)); - } - - try { - Statm statm = process.statm(); - html.p().strong("SIZE: ").append(Formatter.formatFileSize(getActivity(), statm.getSize())).close(); - html.p().strong("RSS: ").append(Formatter.formatFileSize(getActivity(), statm.getResidentSetSize())).close(); - } catch (IOException e) { - Log.d(TAG, String.format("Error reading /proc/%d/statm.", process.pid)); } - - try { - html.p().strong("OOM SCORE: ").append(process.oom_score()).close(); - } catch (IOException e) { - Log.d(TAG, String.format("Error reading /proc/%d/oom_score.", process.pid)); - } - - try { - html.p().strong("OOM ADJ: ").append(process.oom_adj()).close(); - } catch (IOException e) { - Log.d(TAG, String.format("Error reading /proc/%d/oom_adj.", process.pid)); - } - - try { - html.p().strong("OOM SCORE ADJ: ").append(process.oom_score_adj()).close(); - } catch (IOException e) { - Log.d(TAG, String.format("Error reading /proc/%d/oom_score_adj.", process.pid)); - } - return html.build(); } } diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/fragments/ProcessListFragment.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/fragments/ProcessListFragment.java index cea9893..67cba5d 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/fragments/ProcessListFragment.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/fragments/ProcessListFragment.java @@ -22,15 +22,15 @@ import android.os.Bundle; import android.view.View; import android.widget.ListView; - -import com.jaredrummler.android.processes.models.AndroidAppProcess; +import android.widget.Toast; import com.jaredrummler.android.processes.sample.adapter.ProcessListAdapter; import com.jaredrummler.android.processes.sample.dialogs.ProcessInfoDialog; import com.jaredrummler.android.processes.sample.utils.AndroidAppProcessLoader; - +import com.jaredrummler.android.processes.sample.utils.RootChecker; +import com.jaredrummler.android.sups.ProcessStatusInfo; import java.util.List; -public class ProcessListFragment extends ListFragment implements AndroidAppProcessLoader.Listener { +public class ProcessListFragment extends ListFragment implements AndroidAppProcessLoader.Listener, RootChecker.Listener { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -39,17 +39,29 @@ public class ProcessListFragment extends ListFragment implements AndroidAppProce new AndroidAppProcessLoader(getActivity(), this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - @Override public void onComplete(List processes) { + @Override public void onComplete(List processes) { setListAdapter(new ProcessListAdapter(getActivity(), processes)); + if (processes.isEmpty()) { + new RootChecker(this).execute(); + } + } + + @Override public void onRootCheckFinished(boolean accessGranted) { + Toast toast; + if (accessGranted) { + toast = Toast.makeText(getActivity(), "Error getting processes. Empty list.", Toast.LENGTH_LONG); + } else { + toast = Toast.makeText(getActivity(), "No root access. Cannot get list of processes.", Toast.LENGTH_LONG); + } + toast.show(); } @Override public void onListItemClick(ListView l, View v, int position, long id) { - AndroidAppProcess process = (AndroidAppProcess) getListAdapter().getItem(position); + ProcessStatusInfo process = (ProcessStatusInfo) getListAdapter().getItem(position); ProcessInfoDialog dialog = new ProcessInfoDialog(); Bundle args = new Bundle(); args.putParcelable("process", process); dialog.setArguments(args); dialog.show(getActivity().getFragmentManager(), "ProcessInfoDialog"); } - } diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/picasso/AppIconRequestHandler.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/picasso/AppIconRequestHandler.java index 7ce3918..77e730b 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/picasso/AppIconRequestHandler.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/picasso/AppIconRequestHandler.java @@ -26,10 +26,8 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.text.TextUtils; - import com.squareup.picasso.Request; import com.squareup.picasso.RequestHandler; - import java.io.IOException; import static com.jaredrummler.android.processes.sample.utils.Utils.drawableToBitmap; diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AndroidAppProcessLoader.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AndroidAppProcessLoader.java index 9fb9975..1716903 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AndroidAppProcessLoader.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AndroidAppProcessLoader.java @@ -19,15 +19,14 @@ import android.content.Context; import android.os.AsyncTask; - -import com.jaredrummler.android.processes.AndroidProcesses; -import com.jaredrummler.android.processes.models.AndroidAppProcess; - +import com.jaredrummler.android.sups.ProcessStatusInfo; +import com.jaredrummler.android.sups.ps; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; -public class AndroidAppProcessLoader extends AsyncTask> { +public class AndroidAppProcessLoader extends AsyncTask> { private final Listener listener; private final Context context; @@ -37,13 +36,21 @@ public AndroidAppProcessLoader(Context context, Listener listener) { this.listener = listener; } - @Override protected List doInBackground(Void... params) { - List processes = AndroidProcesses.getRunningAppProcesses(); + @Override protected List doInBackground(Void... params) { + List processes = ps.run(); + + // remove processes that aren't apps + for (Iterator iterator = processes.iterator(); iterator.hasNext(); ) { + ProcessStatusInfo process = iterator.next(); + if (!process.isApp()) { + iterator.remove(); + } + } // sort by app name - Collections.sort(processes, new Comparator() { + Collections.sort(processes, new Comparator() { - @Override public int compare(AndroidAppProcess lhs, AndroidAppProcess rhs) { + @Override public int compare(ProcessStatusInfo lhs, ProcessStatusInfo rhs) { return Utils.getName(context, lhs).compareToIgnoreCase(Utils.getName(context, rhs)); } }); @@ -51,13 +58,13 @@ public AndroidAppProcessLoader(Context context, Listener listener) { return processes; } - @Override protected void onPostExecute(List androidAppProcesses) { + @Override protected void onPostExecute(List androidAppProcesses) { listener.onComplete(androidAppProcesses); } public interface Listener { - void onComplete(List processes); + void onComplete(List processes); } } diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AppNames.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AppNames.java index 35117b9..41f4cf7 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AppNames.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/AppNames.java @@ -19,7 +19,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; - import java.util.Hashtable; public class AppNames { diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/PsTask.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/PsTask.java deleted file mode 100644 index 50aedf9..0000000 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/PsTask.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.sample.utils; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.graphics.Color; -import android.os.AsyncTask; -import com.jaredrummler.android.sups.ProcessStatusInfo; -import com.jaredrummler.android.sups.ps; -import com.jaredrummler.android.util.HtmlBuilder; -import java.lang.ref.WeakReference; -import java.util.List; - -/** - * Runs ps in a root shell and shows a dialog of processes. Application processes are in green. - */ -public class PsTask extends AsyncTask> { - - private final WeakReference weakActivity; - private ProgressDialog dialog; - - public PsTask(Activity activity) { - weakActivity = new WeakReference<>(activity); - } - - @Override protected void onPreExecute() { - dialog = new ProgressDialog(weakActivity.get()); - dialog.setMessage("Please wait..."); - dialog.show(); - } - - @Override protected List doInBackground(Void... params) { - return ps.run(); - } - - @Override protected void onPostExecute(List infos) { - dialog.dismiss(); - Activity activity = weakActivity.get(); - if (activity != null && !activity.isFinishing()) { - HtmlBuilder html = new HtmlBuilder(); - for (ProcessStatusInfo info : infos) { - if (info.isApp()) { - // app processes are in green - html.font(Color.GREEN, info.name); - } else { - html.append(info.name); - } - html.br(); - } - new AlertDialog.Builder(activity) - .setTitle("Processes") - .setMessage(html.build()) - .show(); - } - } - -} diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/RootChecker.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/RootChecker.java new file mode 100644 index 0000000..2e6ff23 --- /dev/null +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/RootChecker.java @@ -0,0 +1,30 @@ +package com.jaredrummler.android.processes.sample.utils; + +import android.os.AsyncTask; +import com.jaredrummler.android.shell.Shell; +import java.lang.ref.WeakReference; + +public class RootChecker extends AsyncTask { + + private final WeakReference listener; + + public RootChecker(Listener listener) { + this.listener = new WeakReference<>(listener); + } + + @Override protected Boolean doInBackground(Void... params) { + return Shell.SU.available(); + } + + @Override protected void onPostExecute(Boolean result) { + Listener listener = this.listener.get(); + if (listener != null) { + listener.onRootCheckFinished(result); + } + } + + public interface Listener { + + void onRootCheckFinished(boolean accessGranted); + } +} diff --git a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/Utils.java b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/Utils.java index ee3b51e..28b7c8e 100644 --- a/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/Utils.java +++ b/demo/src/main/java/com/jaredrummler/android/processes/sample/utils/Utils.java @@ -27,8 +27,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.PictureDrawable; import android.util.TypedValue; - -import com.jaredrummler.android.processes.models.AndroidAppProcess; +import com.jaredrummler.android.sups.ProcessStatusInfo; public class Utils { @@ -60,10 +59,10 @@ public static int toPx(Context context, float dp) { return Math.round(px); } - public static String getName(Context context, AndroidAppProcess process) { + public static String getName(Context context, ProcessStatusInfo process) { try { PackageManager pm = context.getPackageManager(); - PackageInfo packageInfo = process.getPackageInfo(context, 0); + PackageInfo packageInfo = pm.getPackageInfo(process.name, 0); return AppNames.getLabel(pm, packageInfo); } catch (PackageManager.NameNotFoundException e) { return process.name; diff --git a/gradle/gradle-mvn-push.gradle b/gradle/gradle-mvn-push.gradle index a4e69f6..e9f3fcb 100644 --- a/gradle/gradle-mvn-push.gradle +++ b/gradle/gradle-mvn-push.gradle @@ -92,14 +92,22 @@ afterEvaluate { project -> sign configurations.archives } - task androidJavadocs(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + android.libraryVariants.all { variant -> + task("${variant.name}Javadoc", type: Javadoc) { + description "Generates Javadoc for $variant.name." + source = variant.javaCompile.source + classpath = files(variant.javaCompile.classpath.files, + project.android.getBootClasspath()) + exclude '**/BuildConfig.java' + exclude '**/R.java' + } } - task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { + task javadocJar(type: Jar, dependsOn: 'releaseJavadoc') { classifier = 'javadoc' - from androidJavadocs.destinationDir + from { + releaseJavadoc.destinationDir + } } task androidSourcesJar(type: Jar) { @@ -109,6 +117,6 @@ afterEvaluate { project -> artifacts { archives androidSourcesJar - archives androidJavadocsJar + archives javadocJar } } \ No newline at end of file diff --git a/library-main/build.gradle b/library-main/build.gradle deleted file mode 100644 index 594db00..0000000 --- a/library-main/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" - defaultConfig { - minSdkVersion 4 - targetSdkVersion 25 - } -} - -apply from: rootProject.file('gradle/gradle-mvn-push.gradle') \ No newline at end of file diff --git a/library-main/gradle.properties b/library-main/gradle.properties deleted file mode 100644 index e8e1d2f..0000000 --- a/library-main/gradle.properties +++ /dev/null @@ -1,21 +0,0 @@ -VERSION_NAME=1.1.0 -VERSION_CODE=110 -GROUP=com.jaredrummler - -POM_NAME=Android Processes -POM_ARTIFACT_ID=android-processes -POM_PACKAGING=aar - -POM_DESCRIPTION=A small library to get the current running processes on Android -POM_URL=https://github.com/jaredrummler/AndroidProcesses -POM_SCM_URL=https://github.com/jaredrummler/AndroidProcesses -POM_SCM_CONNECTION=scm:git@github.com:jaredrummler/AndroidProcesses.git -POM_SCM_DEV_CONNECTION=scm:git@github.com:jaredrummler/AndroidProcesses.git -POM_LICENCE_NAME=The Apache Software License, Version 2.0 -POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt -POM_LICENCE_DIST=repo -POM_DEVELOPER_ID=jaredrummler -POM_DEVELOPER_NAME=Jared Rummler - -SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots -RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2 diff --git a/library-main/src/main/AndroidManifest.xml b/library-main/src/main/AndroidManifest.xml deleted file mode 100644 index e66bea7..0000000 --- a/library-main/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/AndroidProcesses.java b/library-main/src/main/java/com/jaredrummler/android/processes/AndroidProcesses.java deleted file mode 100644 index 80ae4c9..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/AndroidProcesses.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (C) 2016. Jared Rummler - * - * 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 com.jaredrummler.android.processes; - -import android.app.ActivityManager; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.Build; -import android.util.Log; - -import com.jaredrummler.android.processes.models.AndroidAppProcess; -import com.jaredrummler.android.processes.models.AndroidProcess; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - -/** - *

Helper class to get a list of processes on Android.

- *
- *

Usage:

- * - *

Get a list of running apps:

- *
- * List<AndroidAppProcess> processes = AndroidProcesses.getRunningAppProcesses();
- * 
- * - *

Get some information about a process:

- *
- * AndroidAppProcess process = processes.get(location);
- * String processName = process.name;
- *
- * Stat stat = process.stat();
- * int pid = stat.getPid();
- * int parentProcessId = stat.ppid();
- * long startTime = stat.stime();
- * int policy = stat.policy();
- * char state = stat.state();
- *
- * Statm statm = process.statm();
- * long totalSizeOfProcess = statm.getSize();
- * long residentSetSize = statm.getResidentSetSize();
- *
- * PackageInfo packageInfo = process.getPackageInfo(context, 0);
- * String appName = packageInfo.applicationInfo.loadLabel(pm).toString();
- * 
- * - *

Check if your app is in the foreground:

- *
- * if (AndroidProcesses.isMyProcessInTheForeground()) {
- *   // do stuff
- * }
- * 
- * - *

Get a list of application processes that are running on the device:

- *
- * List<ActivityManager.RunningAppProcessInfo> processes = AndroidProcesses.getRunningAppProcessInfo(context);
- * 
- * - *
- *

Limitations

- * - *

System apps may not be visible because they have a higher SELinux context than third party apps.

- *

Some information that was available through {@link ActivityManager#getRunningAppProcesses()} is not available - * using this library - * ({@link RunningAppProcessInfo#pkgList}, - * {@link RunningAppProcessInfo#lru}, - * {@link RunningAppProcessInfo#importance}, - * etc.).

- *

This is currently not working on the N developer preview.

- *
- *

Note: You should avoid running methods from this class on the UI thread.

- */ -public class AndroidProcesses { - - public static final String TAG = "AndroidProcesses"; - - private static final int AID_READPROC = 3009; - - private static boolean loggingEnabled; - - /** - * Toggle whether debug logging is enabled. - * - * @param enabled - * {@code true} to enable logging. This should be only be used for debugging purposes. - * @see #isLoggingEnabled() - * @see #log(String, Object...) - * @see #log(Throwable, String, Object...) - */ - public static void setLoggingEnabled(boolean enabled) { - loggingEnabled = enabled; - } - - /** - * @return {@code true} if logging is enabled. - * @see #setLoggingEnabled(boolean) - */ - public static boolean isLoggingEnabled() { - return loggingEnabled; - } - - /** - * Send a log message if logging is enabled. - * - * @param message - * the message to log - * @param args - * list of arguments to pass to the formatter - */ - public static void log(String message, Object... args) { - if (loggingEnabled) { - Log.d(TAG, args.length == 0 ? message : String.format(message, args)); - } - } - - /** - * Send a log message if logging is enabled. - * - * @param error - * An exception to log - * @param message - * the message to log - * @param args - * list of arguments to pass to the formatter - */ - public static void log(Throwable error, String message, Object... args) { - if (loggingEnabled) { - Log.d(TAG, args.length == 0 ? message : String.format(message, args), error); - } - } - - /** - * On Android 7.0+ the procfs filesystem is now mounted with hidepid=2, eliminating access to the /proc/PID - * directories of other users. There's a group ("readproc") for making exceptions but it's not exposed as a - * permission. To get a list of processes on Android 7.0+ you must use {@link android.app.usage.UsageStatsManager} - * or have root access. - * - * @return {@code true} if procfs is mounted with hidepid=2 - */ - public static boolean isProcessInfoHidden() { - BufferedReader reader = null; - try { - reader = new BufferedReader(new FileReader("/proc/mounts")); - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - String[] columns = line.split("\\s+"); - if (columns.length == 6 && columns[1].equals("/proc")) { - return columns[3].contains("hidepid=1") || columns[3].contains("hidepid=2"); - } - } - } catch (IOException e) { - Log.d(TAG, "Error reading /proc/mounts. Checking if UID 'readproc' exists."); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ignored) { - } - } - } - return android.os.Process.getUidForName("readproc") == AID_READPROC; - } - - /** - * @return a list of all processes running on the device. - */ - public static List getRunningProcesses() { - List processes = new ArrayList<>(); - File[] files = new File("/proc").listFiles(); - for (File file : files) { - if (file.isDirectory()) { - int pid; - try { - pid = Integer.parseInt(file.getName()); - } catch (NumberFormatException e) { - continue; - } - try { - processes.add(new AndroidProcess(pid)); - } catch (IOException e) { - log(e, "Error reading from /proc/%d.", pid); - // System apps will not be readable on Android 5.0+ if SELinux is enforcing. - // You will need root access or an elevated SELinux context to read all files under /proc. - } - } - } - return processes; - } - - /** - * @return a list of all running app processes on the device. - */ - public static List getRunningAppProcesses() { - List processes = new ArrayList<>(); - File[] files = new File("/proc").listFiles(); - for (File file : files) { - if (file.isDirectory()) { - int pid; - try { - pid = Integer.parseInt(file.getName()); - } catch (NumberFormatException e) { - continue; - } - try { - processes.add(new AndroidAppProcess(pid)); - } catch (AndroidAppProcess.NotAndroidAppProcessException ignored) { - } catch (IOException e) { - log(e, "Error reading from /proc/%d.", pid); - // System apps will not be readable on Android 5.0+ if SELinux is enforcing. - // You will need root access or an elevated SELinux context to read all files under /proc. - } - } - } - return processes; - } - - /** - * Get a list of user apps running in the foreground. - * - * @param context - * the application context - * @return a list of user apps that are in the foreground. - */ - public static List getRunningForegroundApps(Context context) { - List processes = new ArrayList<>(); - File[] files = new File("/proc").listFiles(); - PackageManager pm = context.getPackageManager(); - for (File file : files) { - if (file.isDirectory()) { - int pid; - try { - pid = Integer.parseInt(file.getName()); - } catch (NumberFormatException e) { - continue; - } - try { - AndroidAppProcess process = new AndroidAppProcess(pid); - if (process.foreground - // ignore system processes. First app user starts at 10000. - && (process.uid < 1000 || process.uid > 9999) - // ignore processes that are not running in the default app process. - && !process.name.contains(":") - // Ignore processes that the user cannot launch. - && pm.getLaunchIntentForPackage(process.getPackageName()) != null) { - processes.add(process); - } - } catch (AndroidAppProcess.NotAndroidAppProcessException ignored) { - } catch (IOException e) { - log(e, "Error reading from /proc/%d.", pid); - // System apps will not be readable on Android 5.0+ if SELinux is enforcing. - // You will need root access or an elevated SELinux context to read all files under /proc. - } - } - } - return processes; - } - - /** - * @return {@code true} if this process is in the foreground. - */ - public static boolean isMyProcessInTheForeground() { - try { - return new AndroidAppProcess(android.os.Process.myPid()).foreground; - } catch (Exception e) { - log(e, "Error finding our own process"); - } - return false; - } - - /** - * Returns a list of application processes that are running on the device. - * - *

NOTE: On Lollipop (SDK 22) this does not provide - * {@link RunningAppProcessInfo#pkgList}, - * {@link RunningAppProcessInfo#importance}, - * {@link RunningAppProcessInfo#lru}, - * {@link RunningAppProcessInfo#importanceReasonCode}, - * {@link RunningAppProcessInfo#importanceReasonComponent}, - * {@link RunningAppProcessInfo#importanceReasonPid}, - * etc. If you need more process information try using - * {@link #getRunningAppProcesses()} or {@link android.app.usage.UsageStatsManager}

- * - * @param context - * the application context - * @return a list of RunningAppProcessInfo records, or null if there are no - * running processes (it will not return an empty list). This list ordering is not - * specified. - */ - public static List getRunningAppProcessInfo(Context context) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { - List runningAppProcesses = AndroidProcesses.getRunningAppProcesses(); - List appProcessInfos = new ArrayList<>(); - for (AndroidAppProcess process : runningAppProcesses) { - RunningAppProcessInfo info = new RunningAppProcessInfo(process.name, process.pid, null); - info.uid = process.uid; - appProcessInfos.add(info); - } - return appProcessInfos; - } - ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - return am.getRunningAppProcesses(); - } - - /* package */ AndroidProcesses() { - throw new AssertionError("no instances"); - } - - /** - * A {@link Comparator} to list processes by name - */ - public static final class ProcessComparator implements Comparator { - - @Override public int compare(AndroidProcess p1, AndroidProcess p2) { - return p1.name.compareToIgnoreCase(p2.name); - } - - } - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/AndroidAppProcess.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/AndroidAppProcess.java deleted file mode 100644 index c51d755..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/AndroidAppProcess.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Parcel; - -import com.jaredrummler.android.processes.AndroidProcesses; - -import java.io.File; -import java.io.IOException; -import java.util.regex.Pattern; - -public class AndroidAppProcess extends AndroidProcess { - - private static final boolean SYS_SUPPORTS_SCHEDGROUPS = new File("/dev/cpuctl/tasks").exists(); - - // The name may contain uppercase or lowercase letters ('A' through 'Z'), numbers, and underscores ('_'). - // However, individual package name parts may only start with letters. - // A process name can contain a colon. - private static final Pattern PROCESS_NAME_PATTERN = Pattern.compile( - "^([A-Za-z]{1}[A-Za-z0-9_]*[\\.|:])*[A-Za-z][A-Za-z0-9_]*$"); - - /** {@code true} if the process is in the foreground */ - public final boolean foreground; - - /** The user id of this process. */ - public final int uid; - - public AndroidAppProcess(int pid) throws IOException, NotAndroidAppProcessException { - super(pid); - if (name == null || !PROCESS_NAME_PATTERN.matcher(name).matches() || - !new File("/data/data", getPackageName()).exists()) { - throw new NotAndroidAppProcessException(pid); - } - - final boolean foreground; - int uid; - - if (SYS_SUPPORTS_SCHEDGROUPS) { - Cgroup cgroup = cgroup(); - ControlGroup cpuacct = cgroup.getGroup("cpuacct"); - ControlGroup cpu = cgroup.getGroup("cpu"); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - if (cpu == null || cpuacct == null || !cpuacct.group.contains("pid_")) { - throw new NotAndroidAppProcessException(pid); - } - foreground = !cpu.group.contains("bg_non_interactive"); - try { - uid = Integer.parseInt(cpuacct.group.split("/")[1].replace("uid_", "")); - } catch (Exception e) { - uid = status().getUid(); - } - AndroidProcesses.log("name=%s, pid=%d, uid=%d, foreground=%b, cpuacct=%s, cpu=%s", - name, pid, uid, foreground, cpuacct.toString(), cpu.toString()); - } else { - if (cpu == null || cpuacct == null || !cpu.group.contains("apps")) { - throw new NotAndroidAppProcessException(pid); - } - foreground = !cpu.group.contains("bg_non_interactive"); - try { - uid = Integer.parseInt(cpuacct.group.substring(cpuacct.group.lastIndexOf("/") + 1)); - } catch (Exception e) { - uid = status().getUid(); - } - AndroidProcesses.log("name=%s, pid=%d, uid=%d foreground=%b, cpuacct=%s, cpu=%s", - name, pid, uid, foreground, cpuacct.toString(), cpu.toString()); - } - } else { - Stat stat = stat(); - Status status = status(); - // https://github.com/android/platform_system_core/blob/jb-mr1-release/libcutils/sched_policy.c#L245-256 - foreground = stat.policy() == 0; // SCHED_NORMAL - uid = status.getUid(); - AndroidProcesses.log("name=%s, pid=%d, uid=%d foreground=%b", name, pid, uid, foreground); - } - - this.foreground = foreground; - this.uid = uid; - } - - protected AndroidAppProcess(Parcel in) { - super(in); - foreground = in.readByte() != 0x00; - uid = in.readInt(); - } - - /** - * @return the app's package name - * @see #name - */ - public String getPackageName() { - return name.split(":")[0]; - } - - /** - * Retrieve overall information about the application package. - * - *

Throws {@link PackageManager.NameNotFoundException} if a package with the given name can - * not be found on the system.

- * - * @param context - * the application context - * @param flags - * Additional option flags. Use any combination of - * {@link PackageManager#GET_ACTIVITIES}, {@link PackageManager#GET_GIDS}, - * {@link PackageManager#GET_CONFIGURATIONS}, {@link PackageManager#GET_INSTRUMENTATION}, - * {@link PackageManager#GET_PERMISSIONS}, {@link PackageManager#GET_PROVIDERS}, - * {@link PackageManager#GET_RECEIVERS}, {@link PackageManager#GET_SERVICES}, - * {@link PackageManager#GET_SIGNATURES}, {@link PackageManager#GET_UNINSTALLED_PACKAGES} - * to modify the data returned. - * @return a PackageInfo object containing information about the package. - */ - public PackageInfo getPackageInfo(Context context, int flags) - throws PackageManager.NameNotFoundException { - return context.getPackageManager().getPackageInfo(getPackageName(), flags); - } - - @Override public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeByte((byte) (foreground ? 0x01 : 0x00)); - dest.writeInt(uid); - } - - public static final Creator CREATOR = new Creator() { - - @Override public AndroidAppProcess createFromParcel(Parcel source) { - return new AndroidAppProcess(source); - } - - @Override public AndroidAppProcess[] newArray(int size) { - return new AndroidAppProcess[size]; - } - }; - - public static final class NotAndroidAppProcessException extends Exception { - - public NotAndroidAppProcessException(int pid) { - super(String.format("The process %d does not belong to any application", pid)); - } - } - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/AndroidProcess.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/AndroidProcess.java deleted file mode 100644 index f955186..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/AndroidProcess.java +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; - -import java.io.IOException; -import java.util.Locale; - -public class AndroidProcess implements Parcelable { - - /** the process name */ - public final String name; - - /** the process id */ - public final int pid; - - /** - * AndroidProcess constructor - * - * @param pid - * the process id - * @throws IOException - * if /proc/[pid] does not exist or we don't have read access. - */ - public AndroidProcess(int pid) throws IOException { - this.pid = pid; - this.name = getProcessName(pid); - } - - protected AndroidProcess(Parcel in) { - this.name = in.readString(); - this.pid = in.readInt(); - } - - /** - * Read the contents of a file in /proc/[pid]/[filename]. - * - * @param filename - * the relative path to the file. - * @return the contents of the file. - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public String read(String filename) throws IOException { - return ProcFile.readFile(String.format(Locale.ENGLISH, "/proc/%d/%s", pid, filename)); - } - - /** - *

/proc/[pid]/attr/current (since Linux 2.6.0)

- * - *

The contents of this file represent the current security attributes of the process.

- * - *

In SELinux, this file is used to get the security context of a process. Prior to Linux - * 2.6.11, this file could not be used to set the security context (a write was always denied), - * since SELinux limited process security transitions to execve(2) (see the description of - * /proc/[pid]/attr/exec, below). ince Linux 2.6.11, SELinux lifted this restriction and began - * supporting "set" operations via writes to this node if authorized by policy, although use of - * this operation is only suitable for applications that are trusted to maintain any desired - * separation between the old and new security contexts. Prior to Linux 2.6.28, SELinux did not - * allow threads within a multi- threaded process to set their security context via this node as - * it would yield an inconsistency among the security contexts of the threads sharing the same - * memory space. Since Linux 2.6.28, SELinux lifted this restriction and began supporting "set" - * operations for threads within a multithreaded process if the new security context is bounded - * by the old security context, where the bounded relation is defined in policy and guarantees - * that the new security context has a subset of the permissions of the old security context. - * Other security modules may choose to support "set" operations via writes to this node.

- * - * @return the contents of /proc/[pid]/attr/current - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public String attr_current() throws IOException { - return read("attr/current"); - } - - /** - *

/proc/[pid]/cmdline

- * - *

This read-only file holds the complete command line for the process, unless the process is - * a zombie. In the latter case, there is nothing in this file: that is, a read on this file will - * return 0 characters. The command-line arguments appear in this file as a set of strings - * separated by null bytes ('\0'), with a further null byte after the last string.

- * - * @return the name of the process. (note: process name may be empty. In case it is empty get - * the process name from /proc/[pid]/stat). - * @throws IOException - * if the file does not exist or we don't have read permissions. - * @see #name - */ - public String cmdline() throws IOException { - return read("cmdline"); - } - - /** - *

/proc/[pid]/cgroup (since Linux 2.6.24)

- * - *

This file describes control groups to which the process/task belongs. For each cgroup - * hierarchy there is one entry containing colon-separated fields of the form:

- * - *

5:cpuacct,cpu,cpuset:/daemons

- * - *

The colon-separated fields are, from left to right:

- * - *
    - *
  1. hierarchy ID number
  2. - *
  3. set of subsystems bound to the hierarchy
  4. - *
  5. control group in the hierarchy to which the process belongs
  6. - *
- * - *

This file is present only if the CONFIG_CGROUPS kernel configuration option is enabled.

- * - * @return the {@link Cgroup} for this process - * @throws IOException - */ - public Cgroup cgroup() throws IOException { - return Cgroup.get(pid); - } - - /** - *

/proc/[pid]/oom_score (since Linux 2.6.11)

- * - *

This file displays the current score that the kernel gives to this process for the - * purpose of selecting a process for the OOM-killer. A higher score means that the - * process is more likely to be selected by the OOM-killer.

- * - *

The basis for this score is the amount of memory used by the process, with - * increases (+) or decreases (-) for factors including:

- * - *
    - *
  • whether the process creates a lot of children using fork(2)(+);
  • - *
  • whether the process has been running a long time, or has used a lot of CPU time (-);
  • - *
  • whether the process has a low nice value (i.e., > 0) (+);
  • - *
  • whether the process is privileged (-); and
  • - *
  • whether the process is making direct hardware access (-).
  • - *
- * - *

The oom_score also reflects the adjustment specified by the oom_score_adj - * or oom_adj setting for the process.

- * - * @return the oom_score value for this process - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public int oom_score() throws IOException { - return Integer.parseInt(read("oom_score")); - } - - /** - *

/proc/[pid]/oom_adj (since Linux 2.6.11)

- * - *

This file can be used to adjust the score used to select which process should be killed in - * an out-of-memory (OOM) situation. The kernel uses this value for a bit-shift operation of the - * process's oom_score value: valid values are in the* range -16 to +15, plus the special value - * -17, which disables OOM-killing altogether for this process. A positive score increases the - * likelihood of this process being killed by the OOM-killer; a negative score decreases the - * likelihood.

- * - *

The default value for this file is 0; a new process inherits its parent's oom_adj setting. - * A process must be privileged (CAP_SYS_RESOURCE) to update this file.

- * - *

Since Linux 2.6.36, use of this file is deprecated in favor of - * /proc/[pid]/oom_score_adj.

- * - * @return the oom_adj value for this process - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public int oom_adj() throws IOException { - return Integer.parseInt(read("oom_adj")); - } - - /** - *

/proc/[pid]/oom_score_adj (since Linux 2.6.36)

- * - *

This file can be used to adjust the badness heuristic used to select which process gets - * killed in out-of-memory conditions.

- * - *

The badness heuristic assigns a value to each candidate task ranging from 0 (never kill) to - * 1000 (always kill) to determine which process is targeted. The units are roughly a proportion - * along that range of allowed memory the process may allocate from, based on an estimation of - * its current memory and swap use. For example, if a task is using all allowed memory, its - * badness score will be 1000. If it is using half of its allowed memory, its score will be - * 500.

- * - *

There is an additional factor included in the badness score: root processes are given 3% - * extra memory over other tasks.

- * - *

The amount of "allowed" memory depends on the context in which the OOM-killer was called. - * If it is due to the memory assigned to the allocating task's cpuset being exhausted, the - * allowed memory represents the set of mems assigned to that cpuset (see cpuset(7)). If it is - * due to a mempolicy's node(s) being exhausted, the allowed memory represents the set of - * mempolicy nodes. If it is due to a memory limit (or swap limit) being reached, the allowed - * memory is that configured limit. Finally, if it is due to the entire system being out of - * memory, the allowed memory represents all allocatable resources.

- * - *

The value of oom_score_adj is added to the badness score before it is used to determine - * which task to kill. Acceptable values range from -1000 (OOM_SCORE_ADJ_MIN) to +1000 - * (OOM_SCORE_ADJ_MAX). This allows user space to control the preference for OOM-killing, ranging - * from always preferring a certain task or completely disabling it from OOM killing. The lowest - * possible value, -1000, is equivalent to disabling OOM- killing entirely for that task, since - * it will always report a badness score of 0.

- * - *

Consequently, it is very simple for user space to define the amount of memory to consider - * for each task. Setting a oom_score_adj value of +500, for example, is roughly equivalent to - * allowing the remainder of tasks sharing the same system, cpuset, mempolicy, or memory - * controller resources to use at least 50% more memory. A value of -500, on the other hand, - * would be roughly equivalent to discounting 50% of the task's allowed memory from being - * considered as scoring against the task.

- * - *

For backward compatibility with previous kernels, /proc/[pid]/oom_adj can still be used to - * tune the badness score. Its value is scaled linearly with oom_score_adj.

- * - *

Writing to /proc/[pid]/oom_score_adj or /proc/[pid]/oom_adj will change the other with its - * scaled value.

- * - * @return the oom_score_adj value for this process - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public int oom_score_adj() throws IOException { - return Integer.parseInt(read("oom_score_adj")); - } - - /** - *

/proc/[pid]/stat

- * - *

Status information about the process. This is used by ps(1). It is defined in the kernel - * source file fs/proc/array.c.

- * - *

The fields, in order, with their proper scanf(3) format specifiers, are:

- * - *
    - * - *
  1. pid %d The process ID.
  2. - * - *
  3. comm %s The filename of the executable, in parentheses. This is visible whether or not - * the executable is swapped out.
  4. - * - *
  5. state %c One of the following characters, indicating process state: - *
      - *
    • R Running
    • - *
    • S Sleeping in an interruptible wait
    • - *
    • D Waiting in uninterruptible disk sleep
    • - *
    • Z Zombie
    • - *
    • T Stopped (on a signal) or (before Linux 2.6.33) trace stopped
    • - *
    • t Tracing stop (Linux 2.6.33 onward)
    • - *
    • W Paging (only before Linux 2.6.0)
    • - *
    • X Dead (from Linux 2.6.0 onward)
    • - *
    • x Dead (Linux 2.6.33 to 3.13 only)
    • - *
    • K Wakekill (Linux 2.6.33 to 3.13 only)
    • - *
    • W Waking (Linux 2.6.33 to 3.13 only)
    • - *
    • P Parked (Linux 3.9 to 3.13 only)
    • - *
    - *
  6. - * - *
  7. ppid %d The PID of the parent of this process.
  8. - * - *
  9. pgrp %d The process group ID of the process.
  10. - * - *
  11. session %d The session ID of the process.
  12. - * - *
  13. tty_nr %d The controlling terminal of the process. (The minor device number is contained - * in the combination of bits 31 to 20 and 7 to 0; the major device number is in bits 15 to 8.) - *
  14. - * - *
  15. tpgid %d The ID of the foreground process group of the controlling terminal of the - * process.
  16. - * - *
  17. flags %u The kernel flags word of the process. For bit meanings, see the PF_* defines in - * the Linux kernel source file include/linux/sched.h. Details depend on the kernel version. - * The format for this field was %lu before Linux 2.6.
  18. - * - *
  19. minflt %lu The number of minor faults the process has made which have not required - * loading a memory page from disk.
  20. - * - *
  21. cminflt %lu The number of minor faults that the process's waited-for children have - * made
  22. - * - *
  23. majflt %lu The number of major faults the process has made which have required loading a - * memory page from disk.
  24. - * - *
  25. cmajflt %lu The number of major faults that the process's waited-for children have - * made
  26. - * - *
  27. utime %lu Amount of time that this process has been scheduled in user mode, measured in - * clock ticks (divide by sysconf(_SC_CLK_TCK)). This includes guest time, guest_time (time - * spent running a virtual CPU, see below), so that applications that are not aware of the guest - * time field do not lose that time from their calculations.
  28. - * - *
  29. stime %lu Amount of time that this process has been scheduled in kernel mode, measured - * in clock ticks (divide by sysconf(_SC_CLK_TCK)).
  30. - * - *
  31. cutime %ld Amount of time that this process's waited-for children have been scheduled in - * user mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK)). (See also times(2).) - * This includes guest time, cguest_time (time spent running a virtual CPU, see below).
  32. - * - *
  33. cstime %ld Amount of time that this process's waited-for children have been scheduled in - * kernel mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK)).
  34. - * - *
  35. priority %ld (Explanation for Linux 2.6) For processes running a real-time scheduling - * policy (policy below; see sched_setscheduler(2)), this is the negated scheduling priority, - * minus one; that is, a number in the range -2 to -100, corresponding to real-time priorities 1 - * to 99. For processes running under a non-real-time scheduling policy, this is the raw nice - * value (setpriority(2)) as represented in the kernel. The kernel stores nice values as numbers - * in the range 0 (high) to 39 (low), corresponding to the user-visible nice range of -20 to 19. - * Before Linux 2.6, this was a scaled value based on the scheduler weighting given to this - * process
  36. - * - *
  37. nice %ld The nice value (see setpriority(2)), a value in the range 19 (low priority) to - * -20 (high priority).
  38. - * - *
  39. num_threads %ld Number of threads in this process (since Linux 2.6). Before kernel 2.6, - * this field was hard coded to 0 as a placeholder for an earlier removed field.
  40. - * - *
  41. itrealvalue %ld The time in jiffies before the next SIGALRM is sent to the process due - * to an interval timer. Since kernel 2.6.17, this field is no longer maintained, and is hard - * coded as 0.
  42. - * - *
  43. starttime %llu The time the process started after system boot. In kernels before Linux - * 2.6, this value was expressed in jiffies. Since Linux 2.6, the value is expressed in clock - * ticks (divide by sysconf(_SC_CLK_TCK)).
  44. - * - *
  45. The format for this field was %lu before Linux 2.6. (23) vsize %lu Virtual memory size - * in bytes.
  46. - * - *
  47. rss %ld Resident Set Size: number of pages the process has in real memory. This is just - * the pages which count toward text, data, or stack space. This does not include pages which - * have not been demand-loaded in, or which are swapped out.
  48. - * - *
  49. rsslim %lu Current soft limit in bytes on the rss of the process; see the description of - * RLIMIT_RSS in getrlimit(2).
  50. - * - *
  51. startcode %lu The address above which program text can run.
  52. - * - *
  53. endcode %lu The address below which program text can run.
  54. - * - *
  55. startstack %lu The address of the start (i.e., bottom) of the stack.
  56. - * - *
  57. kstkesp %lu The current value of ESP (stack pointer), as found in the kernel stack page - * for the process.
  58. - * - *
  59. kstkeip %lu The current EIP (instruction pointer).
  60. - * - *
  61. signal %lu The bitmap of pending signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead
  62. - * - *
  63. blocked %lu The bitmap of blocked signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead
  64. - * - *
  65. sigignore %lu The bitmap of ignored signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead
  66. - * - *
  67. sigcatch %lu The bitmap of caught signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead.
  68. - * - *
  69. wchan %lu This is the "channel" in which the process is waiting. It is the address of a - * location in the kernel where the process is sleeping. The corresponding symbolic name can be - * found in /proc/[pid]/wchan.
  70. - * - *
  71. nswap %lu Number of pages swapped (not maintained).
  72. - * - *
  73. cnswap %lu Cumulative nswap for child processes (not maintained).
  74. - * - *
  75. exit_signal %d (since Linux 2.1.22) Signal to be sent to parent when we die.
  76. - * - *
  77. processor %d (since Linux 2.2.8) CPU number last executed on.
  78. - * - *
  79. rt_priority %u (since Linux 2.5.19) Real-time scheduling priority, a number in the - * range 1 to 99 for processes scheduled under a real-time policy, or 0, for non-real-time - * processes (see sched_setscheduler(2)).
  80. - * - *
  81. policy %u (since Linux 2.5.19) Scheduling policy (see sched_setscheduler(2)). Decode - * using the SCHED_* constants in linux/sched.h. The format for this field was %lu before Linux - * 2.6.22.
  82. - * - *
  83. delayacct_blkio_ticks %llu (since Linux 2.6.18) Aggregated block I/O delays, measured - * in clock ticks (centiseconds).
  84. - * - *
  85. guest_time %lu (since Linux 2.6.24) Guest time of the process (time spent running a - * virtual CPU for a guest operating system), measured in clock ticks (divide by - * sysconf(_SC_CLK_TCK)).
  86. - * - *
  87. cguest_time %ld (since Linux 2.6.24) Guest time of the process's children, measured in - * clock ticks (divide by sysconf(_SC_CLK_TCK)).
  88. - * - *
  89. start_data %lu (since Linux 3.3) Address above which program initialized and - * uninitialized (BSS) data are placed.
  90. - * - *
  91. end_data %lu (since Linux 3.3) Address below which program initialized and - * uninitialized (BSS) data are placed.
  92. - * - *
  93. start_brk %lu (since Linux 3.3) Address above which program heap can be expanded with - * brk(2).
  94. - * - *
  95. arg_start %lu (since Linux 3.5) Address above which program command-line arguments - * (argv) are placed.
  96. - * - *
  97. arg_end %lu (since Linux 3.5) Address below program command-line arguments (argv) are - * placed.
  98. - * - *
  99. env_start %lu (since Linux 3.5) Address above which program environment is placed.
  100. - * - *
  101. env_end %lu (since Linux 3.5) Address below which program environment is placed.
  102. - * - *
  103. exit_code %d (since Linux 3.5) The thread's exit status in the form reported by - * waitpid(2).
  104. - * - *
- * - * @return the {@link Stat} for this process - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public Stat stat() throws IOException { - return Stat.get(pid); - } - - /** - *

Provides information about memory usage, measured in pages.

- * - *

The columns are:

- * - *
    - *
  • size (1) total program size (same as VmSize in /proc/[pid]/status)
  • - *
  • resident (2) resident set size (same as VmRSS in /proc/[pid]/status)
  • - *
  • share (3) shared pages (i.e., backed by a file)
  • - *
  • text (4) text (code)
  • - *
  • lib (5) library (unused in Linux 2.6)
  • - *
  • data (6) data + stack
  • - *
  • dt (7) dirty pages (unused in Linux 2.6)
  • - *
- * - * @return the {@link Statm} for this process - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public Statm statm() throws IOException { - return Statm.get(pid); - } - - /** - *

/proc/[pid]/status

- * - *

Provides much of the information in /proc/[pid]/stat and /proc/[pid]/statm in a format - * that's - * easier for humans to parse.

- * - *

Here's an example:

- * - *
-   * $ cat /proc/$$/status
-   * Name:   bash
-   * State:  S (sleeping)
-   * Tgid:   3515
-   * Pid:    3515
-   * PPid:   3452
-   * TracerPid:      0
-   * Uid:    1000    1000    1000    1000
-   * Gid:    100     100     100     100
-   * FDSize: 256
-   * Groups: 16 33 100
-   * VmPeak:     9136 kB
-   * VmSize:     7896 kB
-   * VmLck:         0 kB
-   * VmPin:         0 kB
-   * VmHWM:      7572 kB
-   * VmRSS:      6316 kB
-   * VmData:     5224 kB
-   * VmStk:        88 kB
-   * VmExe:       572 kB
-   * VmLib:      1708 kB
-   * VmPMD:         4 kB
-   * VmPTE:        20 kB
-   * VmSwap:        0 kB
-   * Threads:        1
-   * SigQ:   0/3067
-   * SigPnd: 0000000000000000
-   * ShdPnd: 0000000000000000
-   * SigBlk: 0000000000010000
-   * SigIgn: 0000000000384004
-   * SigCgt: 000000004b813efb
-   * CapInh: 0000000000000000
-   * CapPrm: 0000000000000000
-   * CapEff: 0000000000000000
-   * CapBnd: ffffffffffffffff
-   * Seccomp:        0
-   * Cpus_allowed:   00000001
-   * Cpus_allowed_list:      0
-   * Mems_allowed:   1
-   * Mems_allowed_list:      0
-   * voluntary_ctxt_switches:        150
-   * nonvoluntary_ctxt_switches:     545
-   * 
- * - *

The fields are as follows:

- * - *
    - *
  1. Name: Command run by this process.
  2. - *
  3. State: Current state of the process. One of "R (running)", "S (sleeping)", "D (disk - * sleep)", - * "T (stopped)", "T (tracing stop)", "Z (zombie)", or "X (dead)".
  4. - *
  5. Tgid: Thread group ID (i.e., Process ID).
  6. - *
  7. Pid: Thread ID (see gettid(2)).
  8. - *
  9. PPid: PID of parent process.
  10. - *
  11. TracerPid: PID of process tracing this process (0 if not being traced).
  12. - *
  13. Uid, Gid: Real, effective, saved set, and filesystem UIDs (GIDs).
  14. - *
  15. FDSize: Number of file descriptor slots currently allocated.
  16. - *
  17. Groups: Supplementary group list.
  18. - *
  19. VmPeak: Peak virtual memory size.
  20. - *
  21. VmSize: Virtual memory size.
  22. - *
  23. VmLck: Locked memory size (see mlock(3)).
  24. - *
  25. VmPin: Pinned memory size (since Linux 3.2). These are pages that can't be moved because - * something needs to directly access physical memory.
  26. - *
  27. VmHWM: Peak resident set size ("high water mark").
  28. - *
  29. VmRSS: Resident set size.
  30. - *
  31. VmData, VmStk, VmExe: Size of data, stack, and text segments.
  32. - *
  33. VmLib: Shared library code size.
  34. - *
  35. VmPTE: Page table entries size (since Linux 2.6.10).
  36. - *
  37. VmPMD: Size of second-level page tables (since Linux 4.0).
  38. - *
  39. VmSwap: Swapped-out virtual memory size by anonymous private pages; shmem swap usage is - * not - * included (since Linux 2.6.34).
  40. - *
  41. Threads: Number of threads in process containing this thread.
  42. - *
  43. SigQ: This field contains two slash-separated numbers that relate to queued signals for - * the - * real user ID of this process. The first of these is the number of currently queued signals - * for - * this real user ID, and the second is the resource limit on the number of queued signals for - * this - * process (see the description of RLIMIT_SIGPENDING in getrlimit(2)).
  44. - *
  45. SigPnd, ShdPnd: Number of signals pending for thread and for process as a whole (see - * pthreads(7) and signal(7)).
  46. - *
  47. SigBlk, SigIgn, SigCgt: Masks indicating signals being blocked, ignored, and caught (see - * signal(7)).
  48. - *
  49. CapInh, CapPrm, CapEff: Masks of capabilities enabled in inheritable, permitted, and - * effective sets (see capabilities(7)).
  50. - *
  51. CapBnd: Capability Bounding set (since Linux 2.6.26, see capabilities(7)).
  52. - *
  53. Seccomp: Seccomp mode of the process (since Linux 3.8, see seccomp(2)). 0 means - * SECCOMP_MODE_DISABLED; 1 means SECCOMP_MODE_STRICT; 2 means SECCOMP_MODE_FILTER. This field is - * provided only if the kernel was built with the CONFIG_SECCOMP kernel configuration option - * enabled.
  54. - *
  55. Cpus_allowed: Mask of CPUs on which this process may run (since Linux 2.6.24, see - * cpuset(7)).
  56. - *
  57. Cpus_allowed_list: Same as previous, but in "list format" (since Linux 2.6.26, see - * cpuset(7)).
  58. - *
  59. Mems_allowed: Mask of memory nodes allowed to this process (since Linux 2.6.24, see - * cpuset(7)).
  60. - *
  61. Mems_allowed_list: Same as previous, but in "list format" (since Linux 2.6.26, see - * cpuset(7)). - * voluntary_ctxt_switches, nonvoluntary_ctxt_switches: Number of voluntary and involuntary - * context - * switches (since Linux 2.6.23).
  62. - *
- * - * @return the {@link Status} for this process - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public Status status() throws IOException { - return Status.get(pid); - } - - /** - * The symbolic name corresponding to the location in the kernel where the process is sleeping. - * - * @return the contents of /proc/[pid]/wchan - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public String wchan() throws IOException { - return read("wchan"); - } - - /** - * Get the name of a running process. - * - * @param pid - * the process id. - * @return the name of the process. - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - private String getProcessName(int pid) throws IOException { - String cmdline = null; - try { - cmdline = ProcFile.readFile(String.format(Locale.ENGLISH, "/proc/%d/cmdline", pid)).trim(); - } catch (IOException ignored) { - } - if (TextUtils.isEmpty(cmdline)) { - try { - return Stat.get(pid).getComm(); - } catch (Exception e) { - throw new IOException(String.format(Locale.ENGLISH, "Error reading /proc/%d/stat", pid)); - } - } - return cmdline; - } - - @Override public int describeContents() { - return 0; - } - - @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(this.name); - dest.writeInt(this.pid); - } - - public static final Creator CREATOR = new Creator() { - - @Override public AndroidProcess createFromParcel(Parcel source) { - return new AndroidProcess(source); - } - - @Override public AndroidProcess[] newArray(int size) { - return new AndroidProcess[size]; - } - }; - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/Cgroup.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/Cgroup.java deleted file mode 100644 index 98742b7..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/Cgroup.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.os.Parcel; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Locale; - -/** - *

/proc/[pid]/cgroup (since Linux 2.6.24)

- * - *

This file describes control groups to which the process/task belongs. For each cgroup - * hierarchy there is one entry containing colon-separated fields of the form:

- * - *

5:cpuacct,cpu,cpuset:/daemons

- * - *

The colon-separated fields are, from left to right:

- * - *
    - *
  1. hierarchy ID number
  2. - *
  3. set of subsystems bound to the hierarchy
  4. - *
  5. control group in the hierarchy to which the process belongs
  6. - *
- * - *

This file is present only if the CONFIG_CGROUPS kernel configuration option is enabled.

- * - * @see ControlGroup - */ -public final class Cgroup extends ProcFile { - - /** - * Read /proc/[pid]/cgroup. - * - * @param pid - * the processes id. - * @return the {@link Cgroup} - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public static Cgroup get(int pid) throws IOException { - return new Cgroup(String.format(Locale.ENGLISH, "/proc/%d/cgroup", pid)); - } - - /** the process' control groups */ - public final ArrayList groups; - - private Cgroup(String path) throws IOException { - super(path); - String[] lines = content.split("\n"); - groups = new ArrayList<>(); - for (String line : lines) { - try { - groups.add(new ControlGroup(line)); - } catch (Exception ignored) { - } - } - } - - private Cgroup(Parcel in) { - super(in); - this.groups = in.createTypedArrayList(ControlGroup.CREATOR); - } - - public ControlGroup getGroup(String subsystem) { - for (ControlGroup group : groups) { - String[] systems = group.subsystems.split(","); - for (String name : systems) { - if (name.equals(subsystem)) { - return group; - } - } - } - return null; - } - - @Override public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeTypedList(groups); - } - - public static final Creator CREATOR = new Creator() { - - @Override public Cgroup createFromParcel(Parcel source) { - return new Cgroup(source); - } - - @Override public Cgroup[] newArray(int size) { - return new Cgroup[size]; - } - }; - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/ControlGroup.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/ControlGroup.java deleted file mode 100644 index 7a99753..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/ControlGroup.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.os.Parcel; -import android.os.Parcelable; -import java.util.Locale; - -public class ControlGroup implements Parcelable { - - /** hierarchy ID number */ - public final int id; - - /** set of subsystems bound to the hierarchy */ - public final String subsystems; - - /** control group in the hierarchy to which the process belongs */ - public final String group; - - protected ControlGroup(String line) throws NumberFormatException, IndexOutOfBoundsException { - String[] fields = line.split(":"); - id = Integer.parseInt(fields[0]); - subsystems = fields[1]; - group = fields[2]; - } - - protected ControlGroup(Parcel in) { - this.id = in.readInt(); - this.subsystems = in.readString(); - this.group = in.readString(); - } - - @Override public int describeContents() { - return 0; - } - - @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(this.id); - dest.writeString(this.subsystems); - dest.writeString(this.group); - } - - @Override public String toString() { - return String.format(Locale.ENGLISH, "%d:%s:%s", id, subsystems, group); - } - - public static final Creator CREATOR = new Creator() { - - @Override public ControlGroup createFromParcel(Parcel source) { - return new ControlGroup(source); - } - - @Override public ControlGroup[] newArray(int size) { - return new ControlGroup[size]; - } - }; - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/ProcFile.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/ProcFile.java deleted file mode 100644 index 6e12c31..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/ProcFile.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; - -public class ProcFile extends File implements Parcelable { - - /** - * Read the contents of a file. - * - * @param path - * the absolute path to the file. - * @return the contents of the file. - * @throws IOException - * if an error occurred while reading. - */ - static String readFile(String path) throws IOException { - BufferedReader reader = null; - try { - StringBuilder output = new StringBuilder(); - reader = new BufferedReader(new FileReader(path)); - for (String line = reader.readLine(), newLine = ""; line != null; line = reader.readLine()) { - output.append(newLine).append(line); - newLine = "\n"; - } - return output.toString(); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ignored) { - } - } - } - } - - public final String content; - - protected ProcFile(String path) throws IOException { - super(path); - content = readFile(path); - } - - protected ProcFile(Parcel in) { - super(in.readString()); - this.content = in.readString(); - } - - @Override public long length() { - return content.length(); - } - - @Override public int describeContents() { - return 0; - } - - @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(getAbsolutePath()); - dest.writeString(this.content); - } - - public static final Creator CREATOR = new Creator() { - - @Override public ProcFile createFromParcel(Parcel in) { - return new ProcFile(in); - } - - @Override public ProcFile[] newArray(int size) { - return new ProcFile[size]; - } - }; - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/Stat.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/Stat.java deleted file mode 100644 index 07eeaae..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/Stat.java +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.os.Parcel; -import java.io.IOException; -import java.util.Locale; - -/** - *

/proc/[pid]/stat

- * - *

Status information about the process. This is used by ps(1). It is defined in the kernel - * source file fs/proc/array.c.

- * - *

The fields, in order, with their proper scanf(3) format specifiers, are:

- * - *
    - *
  1. pid %d The process ID.
  2. - *
  3. comm %s The filename of the executable, in parentheses. This is visible whether or not - * the executable is swapped out.
  4. - *
  5. state %c One of the following characters, indicating process state: - *
      - *
    • R Running
    • - *
    • S Sleeping in an interruptible wait
    • - *
    • D Waiting in uninterruptible disk sleep
    • - *
    • Z Zombie
    • - *
    • T Stopped (on a signal) or (before Linux 2.6.33) trace stopped
    • - *
    • t Tracing stop (Linux 2.6.33 onward)
    • - *
    • W Paging (only before Linux 2.6.0)
    • - *
    • X Dead (from Linux 2.6.0 onward)
    • - *
    • x Dead (Linux 2.6.33 to 3.13 only)
    • - *
    • K Wakekill (Linux 2.6.33 to 3.13 only)
    • - *
    • W Waking (Linux 2.6.33 to 3.13 only)
    • - *
    • P Parked (Linux 3.9 to 3.13 only)
    • - *
    - *
  6. - *
  7. ppid %d The PID of the parent of this process.
  8. - *
  9. pgrp %d The process group ID of the process.
  10. - *
  11. session %d The session ID of the process.
  12. - *
  13. tty_nr %d The controlling terminal of the process. (The minor device number is contained - * in the combination of bits 31 to 20 and 7 to 0; the major device number is in bits 15 to 8.) - *
  14. - *
  15. tpgid %d The ID of the foreground process group of the controlling terminal of the - * process.
  16. - *
  17. flags %u The kernel flags word of the process. For bit meanings, see the PF_* defines in - * the Linux kernel source file include/linux/sched.h. Details depend on the kernel version. - * The format for this field was %lu before Linux 2.6.
  18. - *
  19. minflt %lu The number of minor faults the process has made which have not required - * loading a memory page from disk.
  20. - *
  21. cminflt %lu The number of minor faults that the process's waited-for children have - * made
  22. - *
  23. majflt %lu The number of major faults the process has made which have required loading a - * memory page from disk.
  24. - *
  25. cmajflt %lu The number of major faults that the process's waited-for children have - * made
  26. - *
  27. utime %lu Amount of time that this process has been scheduled in user mode, measured in - * clock ticks (divide by sysconf(_SC_CLK_TCK)). This includes guest time, guest_time (time - * spent running a virtual CPU, see below), so that applications that are not aware of the guest - * time field do not lose that time from their calculations.
  28. - *
  29. stime %lu Amount of time that this process has been scheduled in kernel mode, measured - * in clock ticks (divide by sysconf(_SC_CLK_TCK)).
  30. - *
  31. cutime %ld Amount of time that this process's waited-for children have been scheduled in - * user mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK)). (See also times(2).) - * This includes guest time, cguest_time (time spent running a virtual CPU, see below).
  32. - *
  33. cstime %ld Amount of time that this process's waited-for children have been scheduled in - * kernel mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK)).
  34. - *
  35. priority %ld (Explanation for Linux 2.6) For processes running a real-time scheduling - * policy (policy below; see sched_setscheduler(2)), this is the negated scheduling priority, - * minus one; that is, a number in the range -2 to -100, corresponding to real-time priorities 1 - * to 99. For processes running under a non-real-time scheduling policy, this is the raw nice - * value (setpriority(2)) as represented in the kernel. The kernel stores nice values as numbers - * in the range 0 (high) to 39 (low), corresponding to the user-visible nice range of -20 to 19. - * Before Linux 2.6, this was a scaled value based on the scheduler weighting given to this - * process
  36. - *
  37. nice %ld The nice value (see setpriority(2)), a value in the range 19 (low priority) to - * -20 (high priority).
  38. - *
  39. num_threads %ld Number of threads in this process (since Linux 2.6). Before kernel 2.6, - * this field was hard coded to 0 as a placeholder for an earlier removed field.
  40. - *
  41. itrealvalue %ld The time in jiffies before the next SIGALRM is sent to the process due - * to an interval timer. Since kernel 2.6.17, this field is no longer maintained, and is hard - * coded as 0.
  42. - *
  43. starttime %llu The time the process started after system boot. In kernels before Linux - * 2.6, this value was expressed in jiffies. Since Linux 2.6, the value is expressed in clock - * ticks (divide by sysconf(_SC_CLK_TCK)).
  44. - *
  45. The format for this field was %lu before Linux 2.6. (23) vsize %lu Virtual memory size - * in bytes.
  46. - *
  47. rss %ld Resident Set Size: number of pages the process has in real memory. This is just - * the pages which count toward text, data, or stack space. This does not include pages which - * have not been demand-loaded in, or which are swapped out.
  48. - *
  49. rsslim %lu Current soft limit in bytes on the rss of the process; see the description of - * RLIMIT_RSS in getrlimit(2).
  50. - *
  51. startcode %lu The address above which program text can run.
  52. - *
  53. endcode %lu The address below which program text can run.
  54. - *
  55. startstack %lu The address of the start (i.e., bottom) of the stack.
  56. - *
  57. kstkesp %lu The current value of ESP (stack pointer), as found in the kernel stack page - * for the process.
  58. - *
  59. kstkeip %lu The current EIP (instruction pointer).
  60. - *
  61. signal %lu The bitmap of pending signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead
  62. - *
  63. blocked %lu The bitmap of blocked signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead
  64. - *
  65. sigignore %lu The bitmap of ignored signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead
  66. - *
  67. sigcatch %lu The bitmap of caught signals, displayed as a decimal number. Obsolete, - * because it does not provide information on real-time signals; use /proc/[pid]/status - * instead.
  68. - *
  69. wchan %lu This is the "channel" in which the process is waiting. It is the address of a - * location in the kernel where the process is sleeping. The corresponding symbolic name can be - * found in /proc/[pid]/wchan.
  70. - *
  71. nswap %lu Number of pages swapped (not maintained).
  72. - *
  73. cnswap %lu Cumulative nswap for child processes (not maintained).
  74. - *
  75. exit_signal %d (since Linux 2.1.22) Signal to be sent to parent when we die.
  76. - *
  77. processor %d (since Linux 2.2.8) CPU number last executed on.
  78. - *
  79. rt_priority %u (since Linux 2.5.19) Real-time scheduling priority, a number in the - * range 1 to 99 for processes scheduled under a real-time policy, or 0, for non-real-time - * processes (see sched_setscheduler(2)).
  80. - *
  81. policy %u (since Linux 2.5.19) Scheduling policy (see sched_setscheduler(2)). Decode - * using the SCHED_* constants in linux/sched.h. The format for this field was %lu before Linux - * 2.6.22.
  82. - *
  83. delayacct_blkio_ticks %llu (since Linux 2.6.18) Aggregated block I/O delays, measured - * in clock ticks (centiseconds).
  84. - *
  85. guest_time %lu (since Linux 2.6.24) Guest time of the process (time spent running a - * virtual CPU for a guest operating system), measured in clock ticks (divide by - * sysconf(_SC_CLK_TCK)).
  86. - *
  87. cguest_time %ld (since Linux 2.6.24) Guest time of the process's children, measured in - * clock ticks (divide by sysconf(_SC_CLK_TCK)).
  88. - *
  89. start_data %lu (since Linux 3.3) Address above which program initialized and - * uninitialized (BSS) data are placed.
  90. - *
  91. end_data %lu (since Linux 3.3) Address below which program initialized and - * uninitialized (BSS) data are placed.
  92. - *
  93. start_brk %lu (since Linux 3.3) Address above which program heap can be expanded with - * brk(2).
  94. - *
  95. arg_start %lu (since Linux 3.5) Address above which program command-line arguments - * (argv) are placed.
  96. - *
  97. arg_end %lu (since Linux 3.5) Address below program command-line arguments (argv) are - * placed.
  98. - *
  99. env_start %lu (since Linux 3.5) Address above which program environment is placed.
  100. - *
  101. env_end %lu (since Linux 3.5) Address below which program environment is placed.
  102. - *
  103. exit_code %d (since Linux 3.5) The thread's exit status in the form reported by - * waitpid(2).
  104. - *
- */ -public final class Stat extends ProcFile { - - /** - * Read /proc/[pid]/stat. - * - * @param pid - * the process id. - * @return the {@link Stat} - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public static Stat get(int pid) throws IOException { - return new Stat(String.format(Locale.ENGLISH, "/proc/%d/stat", pid)); - } - - private final String[] fields; - - private Stat(String path) throws IOException { - super(path); - fields = content.split("\\s+"); - } - - private Stat(Parcel in) { - super(in); - this.fields = in.createStringArray(); - } - - /** The process ID. */ - public int getPid() { - return Integer.parseInt(fields[0]); - } - - /** - * The filename of the executable, in parentheses. This is visible whether or not the - * executable is swapped out. - */ - public String getComm() { - return fields[1].replace("(", "").replace(")", ""); - } - - /** - *

One of the following characters, indicating process state:

- * - *
    - *
  • 'R' Running
  • - *
  • 'S' Sleeping in an interruptible wait
  • - *
  • 'D' Waiting in uninterruptible disk sleep
  • - *
  • 'Z' Zombie
  • - *
  • 'T' Stopped (on a signal) or (before Linux 2.6.33) trace stopped
  • - *
  • 't' Tracing stop (Linux 2.6.33 onward)
  • - *
  • 'W' Paging (only before Linux 2.6.0)
  • - *
  • 'X' Dead (from Linux 2.6.0 onward)
  • - *
  • 'x' Dead (Linux 2.6.33 to 3.13 only)
  • - *
  • 'K' Wakekill (Linux 2.6.33 to 3.13 only)
  • - *
  • 'W' Waking (Linux 2.6.33 to 3.13 only)
  • - *
  • 'P' Parked (Linux 3.9 to 3.13 only)
  • - *
- */ - public char state() { - return fields[2].charAt(0); - } - - /** - * The PID of the parent of this process. - */ - public int ppid() { - return Integer.parseInt(fields[3]); - } - - /** - * The process group ID of the process. - */ - public int pgrp() { - return Integer.parseInt(fields[4]); - } - - /** - * The session ID of the process. - */ - public int session() { - return Integer.parseInt(fields[5]); - } - - /** - * The controlling terminal of the process. (The minor device number is contained in the - * combination of bits 31 to 20 and 7 to 0; the major device number is in bits 15 to 8.) - */ - public int tty_nr() { - return Integer.parseInt(fields[6]); - } - - /** - * The ID of the foreground process group of the controlling terminal of the process. - */ - public int tpgid() { - return Integer.parseInt(fields[7]); - } - - /** - *

The kernel flags word of the process. For bit meanings, see the PF_* defines in the Linux - * kernel source file include/linux/sched.h. Details depend on the kernel version.

- * - *

The format for this field was %lu before Linux 2.6.

- */ - public int flags() { - return Integer.parseInt(fields[8]); - } - - /** - * The number of minor faults the process has made which have not required loading a memory - * page from disk. - */ - public long minflt() { - return Long.parseLong(fields[9]); - } - - /** - * The number of minor faults that the process's waited-for children have made. - */ - public long cminflt() { - return Long.parseLong(fields[10]); - } - - /** - * The number of major faults the process has made which have required loading a memory page - * from disk. - */ - public long majflt() { - return Long.parseLong(fields[11]); - } - - /** - * The number of major faults that the process's waited-for children have made. - */ - public long cmajflt() { - return Long.parseLong(fields[12]); - } - - /** - * Amount of time that this process has been scheduled in user mode, measured in clock ticks - * (divide by sysconf(_SC_CLK_TCK)). This includes guest time, guest_time (time spent running - * a virtual CPU, see below), so that applications that are not aware of the guest time field - * do not lose that time from their calculations. - */ - public long utime() { - return Long.parseLong(fields[13]); - } - - /** - * Amount of time that this process has been scheduled in kernel mode, measured in clock ticks - * (divide by sysconf(_SC_CLK_TCK)). - */ - public long stime() { - return Long.parseLong(fields[14]); - } - - /** - * Amount of time that this process's waited-for children have been scheduled in user mode, - * measured in clock ticks (divide by sysconf(_SC_CLK_TCK)). (See also times(2).) This - * includes guest time, cguest_time (time spent running a virtual CPU, see below). - */ - public long cutime() { - return Long.parseLong(fields[15]); - } - - /** - * Amount of time that this process's waited-for children have been scheduled in kernel mode, - * measured in clock ticks (divide by sysconf(_SC_CLK_TCK)). - */ - public long cstime() { - return Long.parseLong(fields[16]); - } - - /** - *

(Explanation for Linux 2.6) For processes running a real-time scheduling policy (policy - * below; see sched_setscheduler(2)), this is the negated scheduling priority, minus one; that - * is, - * a number in the range -2 to -100, corresponding to real-time priorities 1 to 99. For - * processes - * running under a non-real-time scheduling policy, this is the raw nice value (setpriority(2)) - * as - * represented in the kernel. The kernel stores nice values as numbers in the range 0 (high) to - * 39 (low), corresponding to the user-visible nice range of -20 to 19.

- * - *

Before Linux 2.6, this was a scaled value based on the scheduler weighting given to this - * process.

- */ - public long priority() { - return Long.parseLong(fields[17]); - } - - /** - * The nice value (see setpriority(2)), a value in the range 19 (low priority) to -20 (high - * priority). - */ - public int nice() { - return Integer.parseInt(fields[18]); - } - - /** - * Number of threads in this process (since Linux 2.6). Before kernel 2.6, this field was hard - * coded to 0 as a placeholder for an earlier removed field. - */ - public long num_threads() { - return Long.parseLong(fields[19]); - } - - /** - * The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. - * Since kernel 2.6.17, this field is no longer maintained, and is hard coded as 0. - */ - public long itrealvalue() { - return Long.parseLong(fields[20]); - } - - /** - *

The time the process started after system boot. In kernels before Linux 2.6, this value was - * expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks (divide by - * sysconf(_SC_CLK_TCK)).

- * - *

The format for this field was %lu before Linux 2.6.

- */ - public long starttime() { - return Long.parseLong(fields[21]); - } - - /** - * Virtual memory size in bytes. - */ - public long vsize() { - return Long.parseLong(fields[22]); - } - - /** - * Resident Set Size: number of pages the process has in real memory. This is just the pages - * which count toward text, data, or stack space. This does not include pages which have not - * been demand-loaded in, or which are swapped out. - */ - public long rss() { - return Long.parseLong(fields[23]); - } - - /** - * Current soft limit in bytes on the rss of the process; see the description of RLIMIT_RSS in - * getrlimit(2). - */ - public long rsslim() { - return Long.parseLong(fields[24]); - } - - /** - * The address above which program text can run. - */ - public long startcode() { - return Long.parseLong(fields[25]); - } - - /** - * The address below which program text can run. - */ - public long endcode() { - return Long.parseLong(fields[26]); - } - - /** - * The address of the start (i.e., bottom) of the stack. - */ - public long startstack() { - return Long.parseLong(fields[27]); - } - - /** - * The current value of ESP (stack pointer), as found in the kernel stack page for the process. - */ - public long kstkesp() { - return Long.parseLong(fields[28]); - } - - /** - * The current EIP (instruction pointer). - */ - public long kstkeip() { - return Long.parseLong(fields[29]); - } - - /** - * The bitmap of pending signals, displayed as a decimal number. Obsolete, because it does not - * provide information on real-time signals; use /proc/[pid]/status instead. - */ - public long signal() { - return Long.parseLong(fields[30]); - } - - /** - * The bitmap of blocked signals, displayed as a decimal number. Obsolete, because it does not - * provide information on real-time signals; use /proc/[pid]/status instead. - */ - public long blocked() { - return Long.parseLong(fields[31]); - } - - /** - * The bitmap of ignored signals, displayed as a decimal number. Obsolete, because it does not - * provide information on real-time signals; use /proc/[pid]/status instead. - */ - public long sigignore() { - return Long.parseLong(fields[32]); - } - - /** - * The bitmap of caught signals, displayed as a decimal number. Obsolete, because it does not - * provide information on real-time signals; use /proc/[pid]/status instead. - */ - public long sigcatch() { - return Long.parseLong(fields[33]); - } - - /** - * This is the "channel" in which the process is waiting. It is the address of a location in the - * kernel where the process is sleeping. The corresponding symbolic name can be found in - * /proc/[pid]/wchan. - */ - public long wchan() { - return Long.parseLong(fields[34]); - } - - /** - * Number of pages swapped (not maintained). - */ - public long nswap() { - return Long.parseLong(fields[35]); - } - - /** - * Cumulative nswap for child processes (not maintained). - */ - public long cnswap() { - return Long.parseLong(fields[36]); - } - - /** - * (since Linux 2.1.22) - * Signal to be sent to parent when we die. - */ - public int exit_signal() { - return Integer.parseInt(fields[37]); - } - - /** - * (since Linux 2.2.8) - * CPU number last executed on. - */ - public int processor() { - return Integer.parseInt(fields[38]); - } - - /** - * (since Linux 2.5.19) - * Real-time scheduling priority, a number in the range 1 to 99 for processes scheduled under a - * real-time policy, or 0, for non-real-time processes (see sched_setscheduler(2)). - */ - public int rt_priority() { - return Integer.parseInt(fields[39]); - } - - /** - *

(since Linux 2.5.19) Scheduling policy (see sched_setscheduler(2)). Decode using the - * SCHED_* - * constants in linux/sched.h.

- * - *

The format for this field was %lu before Linux 2.6.22.

- */ - public int policy() { - return Integer.parseInt(fields[40]); - } - - /** - * (since Linux 2.6.18) - * Aggregated block I/O delays, measured in clock ticks (centiseconds). - */ - public long delayacct_blkio_ticks() { - return Long.parseLong(fields[41]); - } - - /** - * (since Linux 2.6.24) - * Guest time of the process (time spent running a virtual CPU for a guest operating system), - * measured in clock ticks (divide by sysconf(_SC_CLK_TCK)). - */ - public long guest_time() { - return Long.parseLong(fields[42]); - } - - /** - * (since Linux 2.6.24) - * Guest time of the process's children, measured in clock ticks (divide by - * sysconf(_SC_CLK_TCK)). - */ - public long cguest_time() { - return Long.parseLong(fields[43]); - } - - /** - * (since Linux 3.3) - * Address above which program initialized and uninitialized (BSS) data are placed. - */ - public long start_data() { - return Long.parseLong(fields[44]); - } - - /** - * (since Linux 3.3) - * Address below which program initialized and uninitialized (BSS) data are placed. - */ - public long end_data() { - return Long.parseLong(fields[45]); - } - - /** - * (since Linux 3.3) - * Address above which program heap can be expanded with brk(2). - */ - public long start_brk() { - return Long.parseLong(fields[46]); - } - - /** - * (since Linux 3.5) - * Address above which program command-line arguments (argv) are placed. - */ - public long arg_start() { - return Long.parseLong(fields[47]); - } - - /** - * (since Linux 3.5) - * Address below program command-line arguments (argv) are placed. - */ - public long arg_end() { - return Long.parseLong(fields[48]); - } - - /** - * (since Linux 3.5) - * Address above which program environment is placed. - */ - public long env_start() { - return Long.parseLong(fields[49]); - } - - /** - * (since Linux 3.5) - * Address below which program environment is placed. - */ - public long env_end() { - return Long.parseLong(fields[50]); - } - - /** - * (since Linux 3.5) - * The thread's exit status in the form reported by waitpid(2). - */ - public int exit_code() { - return Integer.parseInt(fields[51]); - } - - @Override public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeStringArray(fields); - } - - public static final Creator CREATOR = new Creator() { - - @Override public Stat createFromParcel(Parcel source) { - return new Stat(source); - } - - @Override public Stat[] newArray(int size) { - return new Stat[size]; - } - }; - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/Statm.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/Statm.java deleted file mode 100644 index 6f9f9b9..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/Statm.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.os.Parcel; -import java.io.IOException; -import java.util.Locale; - -/** - *

Provides information about memory usage, measured in pages.

- * - *

The columns are:

- * - *
    - *
  • size (1) total program size (same as VmSize in /proc/[pid]/status)
  • - *
  • resident (2) resident set size (same as VmRSS in /proc/[pid]/status)
  • - *
  • share (3) shared pages (i.e., backed by a file)
  • - *
  • text (4) text (code)
  • - *
  • lib (5) library (unused in Linux 2.6)
  • - *
  • data (6) data + stack
  • - *
  • dt (7) dirty pages (unused in Linux 2.6)
  • - *
- */ -public final class Statm extends ProcFile { - - /** - * Read /proc/[pid]/statm. - * - * @param pid - * the process id. - * @return the {@link Statm} - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public static Statm get(int pid) throws IOException { - return new Statm(String.format(Locale.ENGLISH, "/proc/%d/statm", pid)); - } - - public final String[] fields; - - private Statm(String path) throws IOException { - super(path); - fields = content.split("\\s+"); - } - - private Statm(Parcel in) { - super(in); - this.fields = in.createStringArray(); - } - - /** - * @return the total program size in bytes - */ - public long getSize() { - return Long.parseLong(fields[0]) * 1024; - } - - /** - * @return the resident set size in bytes - */ - public long getResidentSetSize() { - return Long.parseLong(fields[1]) * 1024; - } - - @Override public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeStringArray(this.fields); - } - - public static final Creator CREATOR = new Creator() { - - @Override public Statm createFromParcel(Parcel source) { - return new Statm(source); - } - - @Override public Statm[] newArray(int size) { - return new Statm[size]; - } - }; - -} diff --git a/library-main/src/main/java/com/jaredrummler/android/processes/models/Status.java b/library-main/src/main/java/com/jaredrummler/android/processes/models/Status.java deleted file mode 100644 index f150525..0000000 --- a/library-main/src/main/java/com/jaredrummler/android/processes/models/Status.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2015. Jared Rummler - * - * 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 com.jaredrummler.android.processes.models; - -import android.os.Parcel; -import java.io.IOException; -import java.util.Locale; - -/** - *

/proc/[pid]/status

- * - *

Provides much of the information in /proc/[pid]/stat and /proc/[pid]/statm in a format that's - * easier for humans to parse.

- * - *

Here's an example:

- * - *
- * $ cat /proc/$$/status
- * Name:   bash
- * State:  S (sleeping)
- * Tgid:   3515
- * Pid:    3515
- * PPid:   3452
- * TracerPid:      0
- * Uid:    1000    1000    1000    1000
- * Gid:    100     100     100     100
- * FDSize: 256
- * Groups: 16 33 100
- * VmPeak:     9136 kB
- * VmSize:     7896 kB
- * VmLck:         0 kB
- * VmPin:         0 kB
- * VmHWM:      7572 kB
- * VmRSS:      6316 kB
- * VmData:     5224 kB
- * VmStk:        88 kB
- * VmExe:       572 kB
- * VmLib:      1708 kB
- * VmPMD:         4 kB
- * VmPTE:        20 kB
- * VmSwap:        0 kB
- * Threads:        1
- * SigQ:   0/3067
- * SigPnd: 0000000000000000
- * ShdPnd: 0000000000000000
- * SigBlk: 0000000000010000
- * SigIgn: 0000000000384004
- * SigCgt: 000000004b813efb
- * CapInh: 0000000000000000
- * CapPrm: 0000000000000000
- * CapEff: 0000000000000000
- * CapBnd: ffffffffffffffff
- * Seccomp:        0
- * Cpus_allowed:   00000001
- * Cpus_allowed_list:      0
- * Mems_allowed:   1
- * Mems_allowed_list:      0
- * voluntary_ctxt_switches:        150
- * nonvoluntary_ctxt_switches:     545
- * 
- * - *

The fields are as follows:

- * - *
    - *
  1. Name: Command run by this process.
  2. - *
  3. State: Current state of the process. One of "R (running)", "S (sleeping)", "D (disk - * sleep)", - * "T (stopped)", "T (tracing stop)", "Z (zombie)", or "X (dead)".
  4. - *
  5. Tgid: Thread group ID (i.e., Process ID).
  6. - *
  7. Pid: Thread ID (see gettid(2)).
  8. - *
  9. PPid: PID of parent process.
  10. - *
  11. TracerPid: PID of process tracing this process (0 if not being traced).
  12. - *
  13. Uid, Gid: Real, effective, saved set, and filesystem UIDs (GIDs).
  14. - *
  15. FDSize: Number of file descriptor slots currently allocated.
  16. - *
  17. Groups: Supplementary group list.
  18. - *
  19. VmPeak: Peak virtual memory size.
  20. - *
  21. VmSize: Virtual memory size.
  22. - *
  23. VmLck: Locked memory size (see mlock(3)).
  24. - *
  25. VmPin: Pinned memory size (since Linux 3.2). These are pages that can't be moved because - * something needs to directly access physical memory.
  26. - *
  27. VmHWM: Peak resident set size ("high water mark").
  28. - *
  29. VmRSS: Resident set size.
  30. - *
  31. VmData, VmStk, VmExe: Size of data, stack, and text segments.
  32. - *
  33. VmLib: Shared library code size.
  34. - *
  35. VmPTE: Page table entries size (since Linux 2.6.10).
  36. - *
  37. VmPMD: Size of second-level page tables (since Linux 4.0).
  38. - *
  39. VmSwap: Swapped-out virtual memory size by anonymous private pages; shmem swap usage is not - * included (since Linux 2.6.34).
  40. - *
  41. Threads: Number of threads in process containing this thread.
  42. - *
  43. SigQ: This field contains two slash-separated numbers that relate to queued signals for the - * real user ID of this process. The first of these is the number of currently queued signals for - * this real user ID, and the second is the resource limit on the number of queued signals for this - * process (see the description of RLIMIT_SIGPENDING in getrlimit(2)).
  44. - *
  45. SigPnd, ShdPnd: Number of signals pending for thread and for process as a whole (see - * pthreads(7) and signal(7)).
  46. - *
  47. SigBlk, SigIgn, SigCgt: Masks indicating signals being blocked, ignored, and caught (see - * signal(7)).
  48. - *
  49. CapInh, CapPrm, CapEff: Masks of capabilities enabled in inheritable, permitted, and - * effective sets (see capabilities(7)).
  50. - *
  51. CapBnd: Capability Bounding set (since Linux 2.6.26, see capabilities(7)).
  52. - *
  53. Seccomp: Seccomp mode of the process (since Linux 3.8, see seccomp(2)). 0 means - * SECCOMP_MODE_DISABLED; 1 means SECCOMP_MODE_STRICT; 2 means SECCOMP_MODE_FILTER. This field is - * provided only if the kernel was built with the CONFIG_SECCOMP kernel configuration option - * enabled.
  54. - *
  55. Cpus_allowed: Mask of CPUs on which this process may run (since Linux 2.6.24, see - * cpuset(7)).
  56. - *
  57. Cpus_allowed_list: Same as previous, but in "list format" (since Linux 2.6.26, see - * cpuset(7)).
  58. - *
  59. Mems_allowed: Mask of memory nodes allowed to this process (since Linux 2.6.24, see - * cpuset(7)).
  60. - *
  61. Mems_allowed_list: Same as previous, but in "list format" (since Linux 2.6.26, see - * cpuset(7)). - * voluntary_ctxt_switches, nonvoluntary_ctxt_switches: Number of voluntary and involuntary context - * switches (since Linux 2.6.23).
  62. - *
- */ -public final class Status extends ProcFile { - - /** - * Read /proc/[pid]/status. - * - * @param pid - * the process id. - * @return the {@link Status} - * @throws IOException - * if the file does not exist or we don't have read permissions. - */ - public static Status get(int pid) throws IOException { - return new Status(String.format(Locale.ENGLISH, "/proc/%d/status", pid)); - } - - private Status(String path) throws IOException { - super(path); - } - - private Status(Parcel in) { - super(in); - } - - /** - * Get the value of one of the fields. - * - * @param fieldName - * the field name. E.g "PPid", "Uid", "Groups". - * @return The value of the field or {@code null}. - */ - public String getValue(String fieldName) { - String[] lines = content.split("\n"); - for (String line : lines) { - if (line.startsWith(fieldName + ":")) { - return line.split(fieldName + ":")[1].trim(); - } - } - return null; - } - - /** - * @return The process' UID or -1 if parsing the UID failed. - */ - public int getUid() { - try { - return Integer.parseInt(getValue("Uid").split("\\s+")[0]); - } catch (Exception e) { - return -1; - } - } - - /** - * @return The process' GID or -1 if parsing the GID failed. - */ - public int getGid() { - try { - return Integer.parseInt(getValue("Gid").split("\\s+")[0]); - } catch (Exception e) { - return -1; - } - } - - public static final Creator CREATOR = new Creator() { - - @Override public Status createFromParcel(Parcel source) { - return new Status(source); - } - - @Override public Status[] newArray(int size) { - return new Status[size]; - } - }; - -} diff --git a/library-sups/.gitignore b/library-sups/.gitignore deleted file mode 100644 index d0b97c6..0000000 --- a/library-sups/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -*.iml \ No newline at end of file diff --git a/library-main/.gitignore b/library/.gitignore similarity index 100% rename from library-main/.gitignore rename to library/.gitignore diff --git a/library-sups/build.gradle b/library/build.gradle similarity index 100% rename from library-sups/build.gradle rename to library/build.gradle diff --git a/library-sups/gradle.properties b/library/gradle.properties similarity index 95% rename from library-sups/gradle.properties rename to library/gradle.properties index 1ec5c19..9a623cb 100644 --- a/library-sups/gradle.properties +++ b/library/gradle.properties @@ -1,5 +1,5 @@ -VERSION_NAME=0.0.1 -VERSION_CODE=1 +VERSION_NAME=0.0.2 +VERSION_CODE=2 GROUP=com.jaredrummler POM_NAME=Android Processes diff --git a/library-sups/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml similarity index 100% rename from library-sups/src/main/AndroidManifest.xml rename to library/src/main/AndroidManifest.xml diff --git a/library-sups/src/main/java/com/jaredrummler/android/sups/LineParseError.java b/library/src/main/java/com/jaredrummler/android/sups/LineParseError.java similarity index 100% rename from library-sups/src/main/java/com/jaredrummler/android/sups/LineParseError.java rename to library/src/main/java/com/jaredrummler/android/sups/LineParseError.java diff --git a/library-sups/src/main/java/com/jaredrummler/android/sups/ProcessStatusInfo.java b/library/src/main/java/com/jaredrummler/android/sups/ProcessStatusInfo.java similarity index 90% rename from library-sups/src/main/java/com/jaredrummler/android/sups/ProcessStatusInfo.java rename to library/src/main/java/com/jaredrummler/android/sups/ProcessStatusInfo.java index d208c18..c7ef064 100644 --- a/library-sups/src/main/java/com/jaredrummler/android/sups/ProcessStatusInfo.java +++ b/library/src/main/java/com/jaredrummler/android/sups/ProcessStatusInfo.java @@ -29,6 +29,8 @@ public class ProcessStatusInfo implements Parcelable { private static final Pattern PS_LINE_PATTERN = Pattern.compile( "^(\\S+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(-?\\d+)\\s+(-?\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(bg|fg|un|er)?\\s+(\\S+)\\s+(\\S+)\\s+(D|R|S|T|W|X|Z)\\s+(\\S+)\\s+\\(u:(\\d+),\\s+s:(\\d+)\\)$"); + private static final Pattern PROCESS_NAME_PATTERN = Pattern.compile( + "^([A-Za-z]{1}[A-Za-z0-9_]*[\\.|:])*[A-Za-z][A-Za-z0-9_]*$"); private static final Pattern MULTI_USER_APP_ID = Pattern.compile("^u\\d+_a\\d+$"); private static final Pattern DEPRECATED_APP_ID = Pattern.compile("^app_\\d+$"); @@ -74,20 +76,20 @@ public class ProcessStatusInfo implements Parcelable { /** * Possible states: - *

- * "D" uninterruptible sleep (usually IO) - *

- * "R" running or runnable (on run queue) - *

- * "S" interruptible sleep (waiting for an event to complete) - *

- * "T" stopped, either by a job control signal or because it is being traced - *

- * "W" paging (not valid since the 2.6.xx kernel) - *

- * "X" dead (should never be seen) - *

- * "Z" defunct ("zombie") process, terminated but not reaped by its parent + * + *

"D" uninterruptible sleep (usually IO)

+ * + *

"R" running or runnable (on run queue)

+ * + *

"S" interruptible sleep (waiting for an event to complete)

+ * + *

"T" stopped, either by a job control signal or because it is being traced

+ * + *

"W" paging (not valid since the 2.6.xx kernel)

+ * + *

"X" dead (should never be seen)

+ * + *

"Z" defunct ("zombie") process, terminated but not reaped by its parent

*/ public final String state; @@ -130,6 +132,9 @@ public class ProcessStatusInfo implements Parcelable { } public boolean isApp() { + if (!PROCESS_NAME_PATTERN.matcher(name).matches()) { + return false; + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // u{user_id}_a{app_id} is used on API 17+ for multiple user account support. return MULTI_USER_APP_ID.matcher(user).matches(); diff --git a/library-sups/src/main/java/com/jaredrummler/android/sups/ps.java b/library/src/main/java/com/jaredrummler/android/sups/ps.java similarity index 100% rename from library-sups/src/main/java/com/jaredrummler/android/sups/ps.java rename to library/src/main/java/com/jaredrummler/android/sups/ps.java diff --git a/settings.gradle b/settings.gradle index 1ad6fbc..462ba77 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':library-main', ':demo', ':library-sups' +include ':demo', ':library'