Cherrypick d1ed33c4 from hc-mr1. do not merge.
Fix zombie threads in the Layoutlib.
Some widgets can create (indirectly) HandlerThread which are started
but never stopped.
This patch use the delegate methods to override the thread run method
to record which threads are started to be able to call quit() on them
after a render.
Note that we should really fix layoutlib_create to be able to call
the default implementation from a delegate to remove code duplication.
Change-Id: Iaf5432623e9704bb3114a8e0583c8553282c205e
diff --git a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
new file mode 100644
index 0000000..afbe97c0
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 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 com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.impl.RenderAction;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Delegate overriding selected methods of android.os.HandlerThread
+ *
+ * Through the layoutlib_create tool, selected methods of Handler have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ *
+ */
+public class HandlerThread_Delegate {
+
+ private static Map<BridgeContext, List<HandlerThread>> sThreads =
+ new HashMap<BridgeContext, List<HandlerThread>>();
+
+ public static void cleanUp(BridgeContext context) {
+ List<HandlerThread> list = sThreads.get(context);
+ if (list != null) {
+ for (HandlerThread thread : list) {
+ thread.quit();
+ }
+
+ list.clear();
+ sThreads.remove(context);
+ }
+ }
+
+ // -------- Delegate methods
+
+ @LayoutlibDelegate
+ /*package*/ static void run(HandlerThread theThread) {
+ // record the thread so that it can be quit() on clean up.
+ BridgeContext context = RenderAction.getCurrentContext();
+ List<HandlerThread> list = sThreads.get(context);
+ if (list == null) {
+ list = new ArrayList<HandlerThread>();
+ sThreads.put(context, list);
+ }
+
+ list.add(theThread);
+
+ // ---- START DEFAULT IMPLEMENTATION.
+
+ theThread.mTid = Process.myTid();
+ Looper.prepare();
+ synchronized (theThread) {
+ theThread.mLooper = Looper.myLooper();
+ theThread.notifyAll();
+ }
+ Process.setThreadPriority(theThread.mPriority);
+ theThread.onLooperPrepared();
+ Looper.loop();
+ theThread.mTid = -1;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index 8e80c21..6194f5d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -29,6 +29,7 @@
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.resources.ResourceType;
+import android.os.HandlerThread_Delegate;
import android.util.DisplayMetrics;
import java.util.concurrent.TimeUnit;
@@ -228,6 +229,10 @@
private void tearDown() {
// Make sure to remove static references, otherwise we could not unload the lib
mContext.disposeResources();
+
+ // quit HandlerThread created during this session.
+ HandlerThread_Delegate.cleanUp(sCurrentContext);
+
sCurrentContext = null;
Bridge.setLog(null);
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 708d8b5..8602782c 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -98,6 +98,7 @@
"android.content.res.Resources$Theme#resolveAttribute",
"android.graphics.BitmapFactory#finishDecode",
"android.os.Handler#sendMessageAtTime",
+ "android.os.HandlerThread#run",
"android.os.Build#getString",
"android.view.LayoutInflater#parseInclude",
"android.view.View#isInEditMode",