diff options
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/content/Context.java | 11 | ||||
-rw-r--r-- | core/java/android/os/ISchedulingPolicyService.aidl | 34 | ||||
-rw-r--r-- | core/java/android/os/Process.java | 33 | ||||
-rw-r--r-- | core/java/android/os/SchedulingPolicyService.java | 65 |
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; + } + +} |