summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Brown <jeffbrown@google.com> 2012-08-25 12:29:46 -0700
committer Jeff Brown <jeffbrown@google.com> 2012-08-25 13:40:26 -0700
commita2910d0abbbe18ba1710dfd4a31af45769632255 (patch)
treebac98df3737fe3df7e9cd168973fcfe62fad05b0
parentba94170a7a4f78d68fe228e9ee35ed82c4de09c8 (diff)
Make it easier to create asynchronous Handlers.
There are potentially very many Handlers owned by services that should not be blocked by barriers introduced by UI traversals occurring on the same thread (if that ever happens). Add some convenience constructors to make it easy to switch these Handlers over to being async. Bug: 7057752 Change-Id: I64d9bffe81e7c52ada4cfad4e89d4340153f4688
-rw-r--r--core/java/android/os/Handler.java118
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java2
-rw-r--r--services/java/com/android/server/DockObserver.java2
-rw-r--r--services/java/com/android/server/input/InputManagerService.java4
-rw-r--r--services/java/com/android/server/power/DisplayPowerController.java2
-rw-r--r--services/java/com/android/server/power/Notifier.java2
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java2
7 files changed, 84 insertions, 48 deletions
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 77853683b2e5..4e2b5c0a892d 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -101,37 +101,88 @@ public class Handler {
}
/**
- * Default constructor associates this handler with the queue for the
+ * Default constructor associates this handler with the {@link Looper} for the
* current thread.
*
- * If there isn't one, this handler won't be able to receive messages.
+ * If this thread does not have a looper, this handler won't be able to receive messages
+ * so an exception is thrown.
*/
public Handler() {
- if (FIND_POTENTIAL_LEAKS) {
- final Class<? extends Handler> klass = getClass();
- if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
- (klass.getModifiers() & Modifier.STATIC) == 0) {
- Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
- klass.getCanonicalName());
- }
- }
-
- mLooper = Looper.myLooper();
- if (mLooper == null) {
- throw new RuntimeException(
- "Can't create handler inside thread that has not called Looper.prepare()");
- }
- mQueue = mLooper.mQueue;
- mCallback = null;
- mAsynchronous = false;
+ this(null, false);
}
/**
- * Constructor associates this handler with the queue for the
+ * Constructor associates this handler with the {@link Looper} for the
* current thread and takes a callback interface in which you can handle
* messages.
+ *
+ * If this thread does not have a looper, this handler won't be able to receive messages
+ * so an exception is thrown.
+ *
+ * @param callback The callback interface in which to handle messages, or null.
*/
public Handler(Callback callback) {
+ this(callback, false);
+ }
+
+ /**
+ * Use the provided {@link Looper} instead of the default one.
+ *
+ * @param looper The looper, must not be null.
+ */
+ public Handler(Looper looper) {
+ this(looper, null, false);
+ }
+
+ /**
+ * Use the provided {@link Looper} instead of the default one and take a callback
+ * interface in which to handle messages.
+ *
+ * @param looper The looper, must not be null.
+ * @param callback The callback interface in which to handle messages, or null.
+ */
+ public Handler(Looper looper, Callback callback) {
+ this(looper, callback, false);
+ }
+
+ /**
+ * Use the {@link Looper} for the current thread
+ * and set whether the handler should be asynchronous.
+ *
+ * Handlers are synchronous by default unless this constructor is used to make
+ * one that is strictly asynchronous.
+ *
+ * Asynchronous messages represent interrupts or events that do not require global ordering
+ * with represent to synchronous messages. Asynchronous messages are not subject to
+ * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
+ *
+ * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
+ * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
+ *
+ * @hide
+ */
+ public Handler(boolean async) {
+ this(null, async);
+ }
+
+ /**
+ * Use the {@link Looper} for the current thread with the specified callback interface
+ * and set whether the handler should be asynchronous.
+ *
+ * Handlers are synchronous by default unless this constructor is used to make
+ * one that is strictly asynchronous.
+ *
+ * Asynchronous messages represent interrupts or events that do not require global ordering
+ * with represent to synchronous messages. Asynchronous messages are not subject to
+ * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
+ *
+ * @param callback The callback interface in which to handle messages, or null.
+ * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
+ * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
+ *
+ * @hide
+ */
+ public Handler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
@@ -148,32 +199,11 @@ public class Handler {
}
mQueue = mLooper.mQueue;
mCallback = callback;
- mAsynchronous = false;
- }
-
- /**
- * Use the provided queue instead of the default one.
- */
- public Handler(Looper looper) {
- mLooper = looper;
- mQueue = looper.mQueue;
- mCallback = null;
- mAsynchronous = false;
- }
-
- /**
- * Use the provided queue instead of the default one and take a callback
- * interface in which to handle messages.
- */
- public Handler(Looper looper, Callback callback) {
- mLooper = looper;
- mQueue = looper.mQueue;
- mCallback = callback;
- mAsynchronous = false;
+ mAsynchronous = async;
}
/**
- * Use the provided queue instead of the default one and take a callback
+ * Use the provided {@link Looper} instead of the default one and take a callback
* interface in which to handle messages. Also set whether the handler
* should be asynchronous.
*
@@ -184,6 +214,8 @@ public class Handler {
* with represent to synchronous messages. Asynchronous messages are not subject to
* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
*
+ * @param looper The looper, must not be null.
+ * @param callback The callback interface in which to handle messages, or null.
* @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
* each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
*
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 3ea50201502f..236a4ea48350 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -971,7 +971,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback {
* interacts with the keyguard ui should be posted to this handler, rather
* than called directly.
*/
- private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
+ private Handler mHandler = new Handler(true /*async*/) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 2bed95732a29..f1ff27ff351b 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -241,7 +241,7 @@ final class DockObserver extends UEventObserver {
SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK) != 0;
}
- private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
+ private final Handler mHandler = new Handler(true /*async*/) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 0b8ff620c4cc..29c68ebf0424 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -1438,6 +1438,10 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
* Private handler for the input manager.
*/
private final class InputManagerHandler extends Handler {
+ public InputManagerHandler() {
+ super(true /*async*/);
+ }
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index 5f917af174ef..cd211da09973 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -1112,7 +1112,7 @@ final class DisplayPowerController {
private final class DisplayControllerHandler extends Handler {
public DisplayControllerHandler(Looper looper) {
- super(looper);
+ super(looper, null, true /*async*/);
}
@Override
diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java
index 9d928e503420..75f84457a143 100644
--- a/services/java/com/android/server/power/Notifier.java
+++ b/services/java/com/android/server/power/Notifier.java
@@ -422,7 +422,7 @@ final class Notifier {
private final class NotifierHandler extends Handler {
public NotifierHandler(Looper looper) {
- super(looper);
+ super(looper, null, true /*async*/);
}
@Override
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 9f2b247d3106..cbb5b6df1677 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -1952,7 +1952,7 @@ public final class PowerManagerService extends IPowerManager.Stub
*/
private final class PowerManagerHandler extends Handler {
public PowerManagerHandler(Looper looper) {
- super(looper);
+ super(looper, null, true /*async*/);
}
@Override