Don't allow dangerous operations on shared handlers

Test: Boot, tree hugger
Fix: 235594693
Change-Id: I1c14bc2e4dd22623cecbd166ea20cd62f6a8d790
This commit is contained in:
Makoto Onuki
2022-06-10 09:24:35 -07:00
parent eff8acaabd
commit a15d36b097
7 changed files with 35 additions and 9 deletions

View File

@@ -230,6 +230,7 @@ public class Handler {
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
mIsShared = false;
}
/**
@@ -253,10 +254,17 @@ public class Handler {
*/
@UnsupportedAppUsage
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
this(looper, callback, async, /* shared= */ false);
}
/** @hide */
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async,
boolean shared) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
mIsShared = shared;
}
/**
@@ -778,6 +786,14 @@ public class Handler {
return queue.enqueueMessage(msg, uptimeMillis);
}
private Object disallowNullArgumentIfShared(@Nullable Object arg) {
if (mIsShared && arg == null) {
throw new IllegalArgumentException("Null argument disallowed for shared handler."
+ " Consider creating your own Handler instance.");
}
return arg;
}
/**
* Remove any pending posts of messages with code 'what' that are in the
* message queue.
@@ -792,7 +808,7 @@ public class Handler {
* all messages will be removed.
*/
public final void removeMessages(int what, @Nullable Object object) {
mQueue.removeMessages(this, what, object);
mQueue.removeMessages(this, what, disallowNullArgumentIfShared(object));
}
/**
@@ -807,7 +823,7 @@ public class Handler {
*@hide
*/
public final void removeEqualMessages(int what, @Nullable Object object) {
mQueue.removeEqualMessages(this, what, object);
mQueue.removeEqualMessages(this, what, disallowNullArgumentIfShared(object));
}
/**
@@ -816,7 +832,7 @@ public class Handler {
* all callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(@Nullable Object token) {
mQueue.removeCallbacksAndMessages(this, token);
mQueue.removeCallbacksAndMessages(this, disallowNullArgumentIfShared(token));
}
/**
@@ -827,7 +843,7 @@ public class Handler {
*@hide
*/
public final void removeCallbacksAndEqualMessages(@Nullable Object token) {
mQueue.removeCallbacksAndEqualMessages(this, token);
mQueue.removeCallbacksAndEqualMessages(this, disallowNullArgumentIfShared(token));
}
/**
* Check if there are any pending posts of messages with code 'what' in
@@ -951,6 +967,9 @@ public class Handler {
@UnsupportedAppUsage
IMessenger mMessenger;
/** If it's a shared handler, we disallow certain dangeraous operations. */
private final boolean mIsShared;
private static final class BlockingRunnable implements Runnable {
private final Runnable mTask;
private boolean mDone;

View File

@@ -46,7 +46,8 @@ public final class BackgroundThread extends HandlerThread {
looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
looper.setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
sHandler = new Handler(sInstance.getLooper());
sHandler = new Handler(sInstance.getLooper(), /*callback=*/ null, /* async=*/ false,
/* shared=*/ true);
sHandlerExecutor = new HandlerExecutor(sHandler);
}
}

View File

@@ -43,7 +43,7 @@ public final class DisplayThread extends ServiceThread {
sInstance = new DisplayThread();
sInstance.start();
sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
sHandler = new Handler(sInstance.getLooper());
sHandler = makeSharedHandler(sInstance.getLooper());
}
}

View File

@@ -51,7 +51,7 @@ public final class FgThread extends ServiceThread {
looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
looper.setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
sHandler = new Handler(sInstance.getLooper());
sHandler = makeSharedHandler(sInstance.getLooper());
sHandlerExecutor = new HandlerExecutor(sHandler);
}
}

View File

@@ -41,7 +41,7 @@ public final class IoThread extends ServiceThread {
sInstance = new IoThread();
sInstance.start();
sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
sHandler = new Handler(sInstance.getLooper());
sHandler = makeSharedHandler(sInstance.getLooper());
sHandlerExecutor = new HandlerExecutor(sHandler);
}
}

View File

@@ -16,7 +16,9 @@
package com.android.server;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
import android.os.StrictMode;
@@ -43,4 +45,8 @@ public class ServiceThread extends HandlerThread {
super.run();
}
protected static Handler makeSharedHandler(Looper looper) {
return new Handler(looper, /*callback=*/ null, /* async=*/ false, /* shared=*/ true);
}
}

View File

@@ -53,7 +53,7 @@ public final class UiThread extends ServiceThread {
looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
looper.setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
sHandler = new Handler(sInstance.getLooper());
sHandler = makeSharedHandler(sInstance.getLooper());
}
}