summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/Context.java11
-rw-r--r--core/java/android/os/ISchedulingPolicyService.aidl34
-rw-r--r--core/java/android/os/Process.java33
-rw-r--r--core/java/android/os/SchedulingPolicyService.java65
4 files changed, 143 insertions, 0 deletions
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 36638f9..381daa3 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1928,6 +1928,17 @@ public abstract class Context {
public static final String INPUT_SERVICE = "input";
/**
+ * Use with {@link #getSystemService} to retrieve a
+ * {@link android.os.SchedulingPolicyService} for managing scheduling policy.
+ *
+ * @see #getSystemService
+ * @see android.os.SchedulingPolicyService
+ *
+ * @hide
+ */
+ public static final String SCHEDULING_POLICY_SERVICE = "scheduling_policy";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/os/ISchedulingPolicyService.aidl b/core/java/android/os/ISchedulingPolicyService.aidl
new file mode 100644
index 0000000..1273c83
--- /dev/null
+++ b/core/java/android/os/ISchedulingPolicyService.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/**
+ * Initially only provides requestPriority() below, but in longer term
+ * other scheduling policy related services will be collected here.
+ *
+ * @hide
+ */
+interface ISchedulingPolicyService {
+
+ /**
+ * Move thread tid into appropriate cgroup and assign it priority prio.
+ * The thread group leader of tid must be pid.
+ * There may be restrictions on who can call this.
+ */
+ int requestPriority(int pid, int tid, int prio);
+
+}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 8e041bb..0ba7b88 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -299,6 +299,24 @@ public class Process {
**/
private static final int THREAD_GROUP_FOREGROUND = 1;
+ /**
+ * System thread group.
+ * @hide
+ **/
+ public static final int THREAD_GROUP_SYSTEM = 2;
+
+ /**
+ * Application audio thread group.
+ * @hide
+ **/
+ public static final int THREAD_GROUP_AUDIO_APP = 3;
+
+ /**
+ * System audio thread group.
+ * @hide
+ **/
+ public static final int THREAD_GROUP_AUDIO_SYS = 4;
+
public static final int SIGNAL_QUIT = 3;
public static final int SIGNAL_KILL = 9;
public static final int SIGNAL_USR1 = 10;
@@ -658,6 +676,21 @@ public class Process {
}
/**
+ * Returns the thread group leader id for a currently running thread.
+ * @param tid the thread id
+ * @return the thread group leader id of the thread, or -1 if the thread is not running.
+ * This is same as what getpid(2) would return if called by tid.
+ * @hide
+ */
+ public static final int getThreadGroupLeader(int tid) {
+ String[] procStatusLabels = { "Tgid:" };
+ long[] procStatusValues = new long[1];
+ procStatusValues[0] = -1;
+ Process.readProcLines("/proc/" + tid + "/status", procStatusLabels, procStatusValues);
+ return (int) procStatusValues[0];
+ }
+
+ /**
* Set the priority of a thread, based on Linux priorities.
*
* @param tid The identifier of the thread/process to change.
diff --git a/core/java/android/os/SchedulingPolicyService.java b/core/java/android/os/SchedulingPolicyService.java
new file mode 100644
index 0000000..94f907b
--- /dev/null
+++ b/core/java/android/os/SchedulingPolicyService.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Process;
+import android.util.Log;
+
+/**
+ * The implementation of the scheduling policy service interface.
+ *
+ * @hide
+ */
+public class SchedulingPolicyService extends ISchedulingPolicyService.Stub {
+
+ private static final String TAG = "SchedulingPolicyService";
+
+ // Minimum and maximum values allowed for requestPriority parameter prio
+ private static final int PRIORITY_MIN = 1;
+ private static final int PRIORITY_MAX = 2;
+
+ public SchedulingPolicyService() {
+ }
+
+ public int requestPriority(int pid, int tid, int prio) {
+ //Log.i(TAG, "requestPriority(pid=" + pid + ", tid=" + tid + ", prio=" + prio + ")");
+
+ // Verify that caller is mediaserver, priority is in range, and that the
+ // callback thread specified by app belongs to the app that called mediaserver.
+ // Once we've verified that the caller is mediaserver, we can trust the pid but
+ // we can't trust the tid. No need to explicitly check for pid == 0 || tid == 0,
+ // since if not the case then the getThreadGroupLeader() test will also fail.
+ if (Binder.getCallingUid() != Process.MEDIA_UID || prio < PRIORITY_MIN ||
+ prio > PRIORITY_MAX || Process.getThreadGroupLeader(tid) != pid) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+ try {
+ // make good use of our CAP_SYS_NICE capability
+ Process.setThreadGroup(tid, Binder.getCallingPid() == pid ?
+ Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_AUDIO_APP);
+ // must be in this order or it fails the schedulability constraint
+ Process.setThreadScheduler(tid, Process.SCHED_FIFO, prio);
+ } catch (RuntimeException e) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+ return PackageManager.PERMISSION_GRANTED;
+ }
+
+}