From f9455fafb690f23cee9cc9a59bfb68f31e695990 Mon Sep 17 00:00:00 2001 From: Siva Velusamy Date: Thu, 17 Jan 2013 18:01:52 -0800 Subject: Support invoking view methods from hierarchy viewer This CL adds support for invoking any view method with primtive arguments, and setting layout parameters from the debugger (hierarchy viewer). requestLayout() and invalidate() are now just implemented using the more generic invokeMethod() command. Change-Id: Icffda251728a4963b35266786b0b6143bae7fe8e --- core/java/android/view/ViewDebug.java | 65 +++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'core/java/android/view/ViewDebug.java') diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 6e2826881b1d..987ff7857c32 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; /** * Various debugging/tracing tools related to {@link View} and the view hierarchy. @@ -1374,4 +1375,68 @@ public class ViewDebug { sb.append(capturedViewExportMethods(view, klass, "")); Log.d(tag, sb.toString()); } + + /** + * Invoke a particular method on given view. + * The given method is always invoked on the UI thread. The caller thread will stall until the + * method invocation is complete. Returns an object equal to the result of the method + * invocation, null if the method is declared to return void + * @throws Exception if the method invocation caused any exception + * @hide + */ + public static Object invokeViewMethod(final View view, final Method method, + final Object[] args) { + final CountDownLatch latch = new CountDownLatch(1); + final AtomicReference result = new AtomicReference(); + final AtomicReference exception = new AtomicReference(); + + view.post(new Runnable() { + @Override + public void run() { + try { + result.set(method.invoke(view, args)); + } catch (InvocationTargetException e) { + exception.set(e.getCause()); + } catch (Exception e) { + exception.set(e); + } + + latch.countDown(); + } + }); + + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + if (exception.get() != null) { + throw new RuntimeException(exception.get()); + } + + return result.get(); + } + + /** + * @hide + */ + public static void setLayoutParameter(final View view, final String param, final int value) + throws NoSuchFieldException, IllegalAccessException { + final ViewGroup.LayoutParams p = view.getLayoutParams(); + final Field f = p.getClass().getField(param); + if (f.getType() != int.class) { + throw new RuntimeException("Only integer layout parameters can be set. Field " + + param + " is of type " + f.getType().getSimpleName()); + } + + f.set(p, Integer.valueOf(value)); + + view.post(new Runnable() { + @Override + public void run() { + view.setLayoutParams(p); + } + }); + } } -- cgit v1.2.3