summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-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
-rw-r--r--core/jni/android_util_Process.cpp12
-rw-r--r--services/java/com/android/server/SystemServer.java5
7 files changed, 159 insertions, 2 deletions
diff --git a/Android.mk b/Android.mk
index a98b1c2..7ebf4b5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -132,6 +132,7 @@ LOCAL_SRC_FILES += \
core/java/android/os/IPermissionController.aidl \
core/java/android/os/IPowerManager.aidl \
core/java/android/os/IRemoteCallback.aidl \
+ core/java/android/os/ISchedulingPolicyService.aidl \
core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IVibratorService.aidl \
core/java/android/service/dreams/IDreamManager.aidl \
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;
+ }
+
+}
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 93be342..d20cc9e 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -242,9 +242,17 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
continue;
}
- if (isDefault) {
- t_pri = getpriority(PRIO_PROCESS, t_pid);
+ t_pri = getpriority(PRIO_PROCESS, t_pid);
+
+ if (t_pri <= ANDROID_PRIORITY_AUDIO) {
+ int scheduler = sched_getscheduler(t_pid);
+ if ((scheduler == SCHED_FIFO) || (scheduler == SCHED_RR)) {
+ // This task wants to stay in it's current audio group so it can keep it's budget
+ continue;
+ }
+ }
+ if (isDefault) {
if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {
// This task wants to stay at background
continue;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d68a1ef..849281d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -30,6 +30,7 @@ import android.media.AudioService;
import android.net.wifi.p2p.WifiP2pService;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.SchedulingPolicyService;
import android.os.ServiceManager;
import android.os.StrictMode;
import android.os.SystemClock;
@@ -155,6 +156,10 @@ class ServerThread extends Thread {
Slog.i(TAG, "Telephony Registry");
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
+ Slog.i(TAG, "Scheduling Policy");
+ ServiceManager.addService(Context.SCHEDULING_POLICY_SERVICE,
+ new SchedulingPolicyService());
+
AttributeCache.init(context);
Slog.i(TAG, "Package Manager");