am 160edb36
: Add ability to guard a thread against setting its own prio to bg
Merge commit '160edb3645f8b7012bab70ae6e6e8c4a5733082b' into gingerbread-plus-aosp * commit '160edb3645f8b7012bab70ae6e6e8c4a5733082b': Add ability to guard a thread against setting its own prio to bg
This commit is contained in:
@ -625,6 +625,15 @@ public class Process {
|
|||||||
public static final native void setThreadPriority(int tid, int priority)
|
public static final native void setThreadPriority(int tid, int priority)
|
||||||
throws IllegalArgumentException, SecurityException;
|
throws IllegalArgumentException, SecurityException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call with 'false' to cause future calls to {@link #setThreadPriority(int)} to
|
||||||
|
* throw an exception if passed a background-level thread priority. This is only
|
||||||
|
* effective if the JNI layer is built with GUARD_THREAD_PRIORITY defined to 1.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final native void setCanSelfBackground(boolean backgroundOk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the scheduling group for a thread.
|
* Sets the scheduling group for a thread.
|
||||||
* @hide
|
* @hide
|
||||||
|
@ -52,9 +52,15 @@ pid_t gettid() { return syscall(__NR_gettid);}
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define POLICY_DEBUG 0
|
#define POLICY_DEBUG 0
|
||||||
|
#define GUARD_THREAD_PRIORITY 0
|
||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
|
|
||||||
|
#if GUARD_THREAD_PRIORITY
|
||||||
|
Mutex gKeyCreateMutex;
|
||||||
|
static pthread_key_t gBgKey = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void signalExceptionForPriorityError(JNIEnv* env, jobject obj, int err)
|
static void signalExceptionForPriorityError(JNIEnv* env, jobject obj, int err)
|
||||||
{
|
{
|
||||||
switch (err) {
|
switch (err) {
|
||||||
@ -264,9 +270,41 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
|
|||||||
closedir(d);
|
closedir(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void android_os_Process_setCanSelfBackground(JNIEnv* env, jobject clazz, jboolean bgOk) {
|
||||||
|
// Establishes the calling thread as illegal to put into the background.
|
||||||
|
// Typically used only for the system process's main looper.
|
||||||
|
#if GUARD_THREAD_PRIORITY
|
||||||
|
LOGV("Process.setCanSelfBackground(%d) : tid=%d", bgOk, androidGetTid());
|
||||||
|
{
|
||||||
|
Mutex::Autolock _l(gKeyCreateMutex);
|
||||||
|
if (gBgKey == -1) {
|
||||||
|
pthread_key_create(&gBgKey, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// inverted: not-okay, we set a sentinel value
|
||||||
|
pthread_setspecific(gBgKey, (void*)(bgOk ? 0 : 0xbaad));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
|
void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
|
||||||
jint pid, jint pri)
|
jint pid, jint pri)
|
||||||
{
|
{
|
||||||
|
#if GUARD_THREAD_PRIORITY
|
||||||
|
// if we're putting the current thread into the background, check the TLS
|
||||||
|
// to make sure this thread isn't guarded. If it is, raise an exception.
|
||||||
|
if (pri >= ANDROID_PRIORITY_BACKGROUND) {
|
||||||
|
if (pid == androidGetTid()) {
|
||||||
|
void* bgOk = pthread_getspecific(gBgKey);
|
||||||
|
if (bgOk == ((void*)0xbaad)) {
|
||||||
|
LOGE("Thread marked fg-only put self in background!");
|
||||||
|
jniThrowException(env, "java/lang/SecurityException", "May not put this thread into background");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int rc = androidSetThreadPriority(pid, pri);
|
int rc = androidSetThreadPriority(pid, pri);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
if (rc == INVALID_OPERATION) {
|
if (rc == INVALID_OPERATION) {
|
||||||
@ -852,6 +890,7 @@ static const JNINativeMethod methods[] = {
|
|||||||
{"getUidForName", "(Ljava/lang/String;)I", (void*)android_os_Process_getUidForName},
|
{"getUidForName", "(Ljava/lang/String;)I", (void*)android_os_Process_getUidForName},
|
||||||
{"getGidForName", "(Ljava/lang/String;)I", (void*)android_os_Process_getGidForName},
|
{"getGidForName", "(Ljava/lang/String;)I", (void*)android_os_Process_getGidForName},
|
||||||
{"setThreadPriority", "(II)V", (void*)android_os_Process_setThreadPriority},
|
{"setThreadPriority", "(II)V", (void*)android_os_Process_setThreadPriority},
|
||||||
|
{"setCanSelfBackground", "(Z)V", (void*)android_os_Process_setCanSelfBackground},
|
||||||
{"setThreadPriority", "(I)V", (void*)android_os_Process_setCallingThreadPriority},
|
{"setThreadPriority", "(I)V", (void*)android_os_Process_setCallingThreadPriority},
|
||||||
{"getThreadPriority", "(I)I", (void*)android_os_Process_getThreadPriority},
|
{"getThreadPriority", "(I)I", (void*)android_os_Process_getThreadPriority},
|
||||||
{"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup},
|
{"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup},
|
||||||
|
@ -80,6 +80,7 @@ class ServerThread extends Thread {
|
|||||||
android.os.Process.THREAD_PRIORITY_FOREGROUND);
|
android.os.Process.THREAD_PRIORITY_FOREGROUND);
|
||||||
|
|
||||||
BinderInternal.disableBackgroundScheduling(true);
|
BinderInternal.disableBackgroundScheduling(true);
|
||||||
|
android.os.Process.setCanSelfBackground(false);
|
||||||
|
|
||||||
String factoryTestStr = SystemProperties.get("ro.factorytest");
|
String factoryTestStr = SystemProperties.get("ro.factorytest");
|
||||||
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
|
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
|
||||||
|
@ -572,6 +572,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
mHaveInputMethods);
|
mHaveInputMethods);
|
||||||
android.os.Process.setThreadPriority(
|
android.os.Process.setThreadPriority(
|
||||||
android.os.Process.THREAD_PRIORITY_DISPLAY);
|
android.os.Process.THREAD_PRIORITY_DISPLAY);
|
||||||
|
android.os.Process.setCanSelfBackground(false);
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
mService = s;
|
mService = s;
|
||||||
@ -607,6 +608,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
// Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
|
// Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
|
||||||
android.os.Process.setThreadPriority(
|
android.os.Process.setThreadPriority(
|
||||||
android.os.Process.THREAD_PRIORITY_FOREGROUND);
|
android.os.Process.THREAD_PRIORITY_FOREGROUND);
|
||||||
|
android.os.Process.setCanSelfBackground(false);
|
||||||
mPolicy.init(mContext, mService, mPM);
|
mPolicy.init(mContext, mService, mPM);
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
@ -1259,6 +1259,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
|
|
||||||
android.os.Process.setThreadPriority(
|
android.os.Process.setThreadPriority(
|
||||||
android.os.Process.THREAD_PRIORITY_FOREGROUND);
|
android.os.Process.THREAD_PRIORITY_FOREGROUND);
|
||||||
|
android.os.Process.setCanSelfBackground(false);
|
||||||
|
|
||||||
ActivityManagerService m = new ActivityManagerService();
|
ActivityManagerService m = new ActivityManagerService();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user