Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3233ae9 authored by Christopher Tate's avatar Christopher Tate Committed by Android Git Automerger
Browse files

am 160edb36: Add ability to guard a thread against setting its own prio to bg

Merge commit '160edb36' into gingerbread-plus-aosp

* commit '160edb36':
  Add ability to guard a thread against setting its own prio to bg
parents 177c405a 160edb36
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -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
+39 −0
Original line number Original line Diff line number Diff line
@@ -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},
+2 −1
Original line number Original line Diff line number Diff line
@@ -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
+2 −0
Original line number Original line Diff line number Diff line
@@ -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) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -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();