1945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy/* 2945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Copyright (C) 2013 The Android Open Source Project 3945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * 4945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Licensed under the Apache License, Version 2.0 (the "License"); 5945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * you may not use this file except in compliance with the License. 6945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * You may obtain a copy of the License at 7945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * 8945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * http://www.apache.org/licenses/LICENSE-2.0 9945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * 10945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Unless required by applicable law or agreed to in writing, software 11945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * distributed under the License is distributed on an "AS IS" BASIS, 12945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * See the License for the specific language governing permissions and 14945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * limitations under the License. 15945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy */ 16945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 17945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamypackage android.ddm; 18945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 19945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport android.util.Log; 20945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport android.view.View; 21945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport android.view.ViewDebug; 22945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport android.view.ViewRootImpl; 23945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport android.view.WindowManagerGlobal; 24945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 25945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport org.apache.harmony.dalvik.ddmc.Chunk; 26945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport org.apache.harmony.dalvik.ddmc.ChunkHandler; 27945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport org.apache.harmony.dalvik.ddmc.DdmServer; 28945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 29945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport java.io.BufferedWriter; 30945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport java.io.ByteArrayOutputStream; 31945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport java.io.DataOutputStream; 32945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport java.io.IOException; 33945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport java.io.OutputStreamWriter; 34f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamyimport java.lang.reflect.Method; 35945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport java.nio.BufferUnderflowException; 36945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamyimport java.nio.ByteBuffer; 37945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 38945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy/** 39945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Handle various requests related to profiling / debugging of the view system. 40945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Support for these features are advertised via {@link DdmHandleHello}. 41945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy */ 42945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamypublic class DdmHandleViewDebug extends ChunkHandler { 43945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** List {@link ViewRootImpl}'s of this process. */ 44945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int CHUNK_VULW = type("VULW"); 45945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 46945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Operation on view root, first parameter in packet should be one of VURT_* constants */ 47945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int CHUNK_VURT = type("VURT"); 48945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 49945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Dump view hierarchy. */ 50945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int VURT_DUMP_HIERARCHY = 1; 51945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 52945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Capture View Layers. */ 53945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int VURT_CAPTURE_LAYERS = 2; 54945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 55e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda /** Dump View Theme. */ 56e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda private static final int VURT_DUMP_THEME = 3; 57e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda 58945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** 59945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Generic View Operation, first parameter in the packet should be one of the 60945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * VUOP_* constants below. 61945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy */ 62945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int CHUNK_VUOP = type("VUOP"); 63945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 64945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Capture View. */ 65945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int VUOP_CAPTURE_VIEW = 1; 66945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 67945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Obtain the Display List corresponding to the view. */ 68945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int VUOP_DUMP_DISPLAYLIST = 2; 69945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 70f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy /** Profile a view. */ 71f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy private static final int VUOP_PROFILE_VIEW = 3; 72945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 73f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy /** Invoke a method on the view. */ 74f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy private static final int VUOP_INVOKE_VIEW_METHOD = 4; 75945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 76f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy /** Set layout parameter. */ 77f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy private static final int VUOP_SET_LAYOUT_PARAMETER = 5; 78945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 79945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Error code indicating operation specified in chunk is invalid. */ 80945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int ERR_INVALID_OP = -1; 81945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 82945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Error code indicating that the parameters are invalid. */ 83945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final int ERR_INVALID_PARAM = -2; 84945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 85f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy /** Error code indicating an exception while performing operation. */ 86f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy private static final int ERR_EXCEPTION = -3; 87f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 88f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy private static final String TAG = "DdmViewDebug"; 89f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 90945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private static final DdmHandleViewDebug sInstance = new DdmHandleViewDebug(); 91945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 92945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** singleton, do not instantiate. */ 93945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private DdmHandleViewDebug() {} 94945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 95945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy public static void register() { 96945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy DdmServer.registerHandler(CHUNK_VULW, sInstance); 97945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy DdmServer.registerHandler(CHUNK_VURT, sInstance); 98945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy DdmServer.registerHandler(CHUNK_VUOP, sInstance); 99945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 100945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 101945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy @Override 102945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy public void connected() { 103945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 104945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 105945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy @Override 106945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy public void disconnected() { 107945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 108945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 109945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy @Override 110945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy public Chunk handleChunk(Chunk request) { 111945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy int type = request.type; 112945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 113a4d4e82927ceadc23863e74b7e1160e4497504a7Pablo Ceballos if (type == CHUNK_VULW) { 114945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return listWindows(); 115945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 116945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 117945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ByteBuffer in = wrapChunk(request); 118945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy int op = in.getInt(); 119945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 120945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy View rootView = getRootView(in); 121945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy if (rootView == null) { 122945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(ERR_INVALID_PARAM, "Invalid View Root"); 123945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 124945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 125945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy if (type == CHUNK_VURT) { 126945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy if (op == VURT_DUMP_HIERARCHY) 127945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return dumpHierarchy(rootView, in); 128945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy else if (op == VURT_CAPTURE_LAYERS) 129945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return captureLayers(rootView); 130e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda else if (op == VURT_DUMP_THEME) 131e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda return dumpTheme(rootView); 132945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy else 133945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(ERR_INVALID_OP, "Unknown view root operation: " + op); 134945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 135945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 136945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy final View targetView = getTargetView(rootView, in); 137945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy if (targetView == null) { 138945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(ERR_INVALID_PARAM, "Invalid target view"); 139945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 140945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 141945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy if (type == CHUNK_VUOP) { 142945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy switch (op) { 143945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy case VUOP_CAPTURE_VIEW: 144945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return captureView(rootView, targetView); 145945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy case VUOP_DUMP_DISPLAYLIST: 146945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return dumpDisplayLists(rootView, targetView); 147945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy case VUOP_PROFILE_VIEW: 148945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return profileView(rootView, targetView); 149f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case VUOP_INVOKE_VIEW_METHOD: 150f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy return invokeViewMethod(rootView, targetView, in); 151f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case VUOP_SET_LAYOUT_PARAMETER: 152f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy return setLayoutParameter(rootView, targetView, in); 153945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy default: 154945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(ERR_INVALID_OP, "Unknown view operation: " + op); 155945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 156945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } else { 157945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy throw new RuntimeException("Unknown packet " + ChunkHandler.name(type)); 158945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 159945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 160945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 161945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Returns the list of windows owned by this client. */ 162945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private Chunk listWindows() { 163945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy String[] windowNames = WindowManagerGlobal.getInstance().getViewRootNames(); 164945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 165945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy int responseLength = 4; // # of windows 166945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy for (String name : windowNames) { 167945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy responseLength += 4; // length of next window name 168945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy responseLength += name.length() * 2; // window name 169945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 170945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 171945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ByteBuffer out = ByteBuffer.allocate(responseLength); 172945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy out.order(ChunkHandler.CHUNK_ORDER); 173945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 174945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy out.putInt(windowNames.length); 175945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy for (String name : windowNames) { 176945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy out.putInt(name.length()); 177945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy putString(out, name); 178945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 179945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 180945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return new Chunk(CHUNK_VULW, out); 181945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 182945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 183945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private View getRootView(ByteBuffer in) { 184945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 185945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy int viewRootNameLength = in.getInt(); 186945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy String viewRootName = getString(in, viewRootNameLength); 187945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return WindowManagerGlobal.getInstance().getRootView(viewRootName); 188945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } catch (BufferUnderflowException e) { 189945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return null; 190945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 191945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 192945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 193945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private View getTargetView(View root, ByteBuffer in) { 194945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy int viewLength; 195945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy String viewName; 196945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 197945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 198945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy viewLength = in.getInt(); 199945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy viewName = getString(in, viewLength); 200945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } catch (BufferUnderflowException e) { 201945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return null; 202945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 203945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 204945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return ViewDebug.findView(root, viewName); 205945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 206945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 207945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** 208945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Returns the view hierarchy and/or view properties starting at the provided view. 209945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * Based on the input options, the return data may include: 210945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * - just the view hierarchy 211945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * - view hierarchy & the properties for each of the views 212945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * - just the view properties for a specific view. 213945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * TODO: Currently this only returns views starting at the root, need to fix so that 214945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy * it can return properties of any view. 215945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy */ 216945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private Chunk dumpHierarchy(View rootView, ByteBuffer in) { 217945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy boolean skipChildren = in.getInt() > 0; 218945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy boolean includeProperties = in.getInt() > 0; 2190d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy boolean v2 = in.hasRemaining() && in.getInt() > 0; 220945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 2210d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy long start = System.currentTimeMillis(); 2220d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy 2230d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy ByteArrayOutputStream b = new ByteArrayOutputStream(2*1024*1024); 224945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 2250d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy if (v2) { 2260d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy ViewDebug.dumpv2(rootView, b); 2270d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy } else { 2280d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy ViewDebug.dump(rootView, skipChildren, includeProperties, b); 2290d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy } 2300d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy } catch (IOException | InterruptedException e) { 231945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(1, "Unexpected error while obtaining view hierarchy: " 232945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy + e.getMessage()); 233945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 234945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 2350d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy long end = System.currentTimeMillis(); 2360d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy Log.d(TAG, "Time to obtain view hierarchy (ms): " + (end - start)); 2370d857b9028f2702ce439e13feccde8182d40e1e5Siva Velusamy 238945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy byte[] data = b.toByteArray(); 239945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return new Chunk(CHUNK_VURT, data, 0, data.length); 240945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 241945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 242945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Returns a buffer with region details & bitmap of every single view. */ 243945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private Chunk captureLayers(View rootView) { 244945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ByteArrayOutputStream b = new ByteArrayOutputStream(1024); 245945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy DataOutputStream dos = new DataOutputStream(b); 246945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 247945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ViewDebug.captureLayers(rootView, dos); 248945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } catch (IOException e) { 249945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(1, "Unexpected error while obtaining view hierarchy: " 250945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy + e.getMessage()); 251945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } finally { 252945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 253945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy dos.close(); 254945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } catch (IOException e) { 255945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy // ignore 256945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 257945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 258945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 259945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy byte[] data = b.toByteArray(); 260945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return new Chunk(CHUNK_VURT, data, 0, data.length); 261945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 262945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 263e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda /** 264e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda * Returns the Theme dump of the provided view. 265e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda */ 266e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda private Chunk dumpTheme(View rootView) { 267e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda ByteArrayOutputStream b = new ByteArrayOutputStream(1024); 268e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda try { 269e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda ViewDebug.dumpTheme(rootView, b); 270e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda } catch (IOException e) { 271e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda return createFailChunk(1, "Unexpected error while dumping the theme: " 272e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda + e.getMessage()); 273e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda } 274e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda 275e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda byte[] data = b.toByteArray(); 276e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda return new Chunk(CHUNK_VURT, data, 0, data.length); 277e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda } 278e82a4eeb40090f15054e2c76c0cea84b198a2b61Jon Miranda 279945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private Chunk captureView(View rootView, View targetView) { 280945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ByteArrayOutputStream b = new ByteArrayOutputStream(1024); 281945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 282945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ViewDebug.capture(rootView, b, targetView); 283945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } catch (IOException e) { 284945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(1, "Unexpected error while capturing view: " 285945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy + e.getMessage()); 286945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 287945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 288945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy byte[] data = b.toByteArray(); 289945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return new Chunk(CHUNK_VUOP, data, 0, data.length); 290945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 291945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 292945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Returns the display lists corresponding to the provided view. */ 293945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private Chunk dumpDisplayLists(final View rootView, final View targetView) { 294945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy rootView.post(new Runnable() { 295945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy @Override 296945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy public void run() { 297945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ViewDebug.outputDisplayList(rootView, targetView); 298945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 299945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy }); 300945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return null; 301945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 302945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 303f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy /** 304f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * Invokes provided method on the view. 305f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * The method name and its arguments are passed in as inputs via the byte buffer. 306f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * The buffer contains:<ol> 307f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * <li> len(method name) </li> 308f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * <li> method name </li> 309f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * <li> # of args </li> 310f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * <li> arguments: Each argument comprises of a type specifier followed by the actual argument. 311f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * The type specifier is a single character as used in JNI: 312f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * (Z - boolean, B - byte, C - char, S - short, I - int, J - long, 313f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * F - float, D - double). <p> 314f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * The type specifier is followed by the actual value of argument. 315f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * Booleans are encoded via bytes with 0 indicating false.</li> 316f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * </ol> 317f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy * Methods that take no arguments need only specify the method name. 318f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy */ 319f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy private Chunk invokeViewMethod(final View rootView, final View targetView, ByteBuffer in) { 320f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy int l = in.getInt(); 321f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy String methodName = getString(in, l); 322f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 323f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy Class<?>[] argTypes; 324f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy Object[] args; 325f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy if (!in.hasRemaining()) { 326f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes = new Class<?>[0]; 327f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args = new Object[0]; 328f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } else { 329f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy int nArgs = in.getInt(); 330f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 331f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes = new Class<?>[nArgs]; 332f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args = new Object[nArgs]; 333f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 334f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy for (int i = 0; i < nArgs; i++) { 335f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy char c = in.getChar(); 336f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy switch (c) { 337f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'Z': 338f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = boolean.class; 339f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.get() == 0 ? false : true; 340f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 341f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'B': 342f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = byte.class; 343f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.get(); 344f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 345f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'C': 346f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = char.class; 347f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.getChar(); 348f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 349f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'S': 350f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = short.class; 351f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.getShort(); 352f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 353f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'I': 354f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = int.class; 355f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.getInt(); 356f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 357f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'J': 358f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = long.class; 359f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.getLong(); 360f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 361f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'F': 362f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = float.class; 363f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.getFloat(); 364f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 365f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy case 'D': 366f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy argTypes[i] = double.class; 367f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy args[i] = in.getDouble(); 368f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy break; 369f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy default: 370f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy Log.e(TAG, "arg " + i + ", unrecognized type: " + c); 371f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy return createFailChunk(ERR_INVALID_PARAM, 372f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy "Unsupported parameter type (" + c + ") to invoke view method."); 373f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } 374f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } 375f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } 376f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 377f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy Method method = null; 378f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy try { 379f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy method = targetView.getClass().getMethod(methodName, argTypes); 380f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } catch (NoSuchMethodException e) { 381f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy Log.e(TAG, "No such method: " + e.getMessage()); 382f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy return createFailChunk(ERR_INVALID_PARAM, 383f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy "No such method: " + e.getMessage()); 384f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } 385f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 386f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy try { 387f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy ViewDebug.invokeViewMethod(targetView, method, args); 388f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } catch (Exception e) { 389f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy Log.e(TAG, "Exception while invoking method: " + e.getCause().getMessage()); 390f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy String msg = e.getCause().getMessage(); 391f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy if (msg == null) { 392f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy msg = e.getCause().toString(); 393f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } 394f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy return createFailChunk(ERR_EXCEPTION, msg); 395f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } 396f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 397945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return null; 398945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 399945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 400f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy private Chunk setLayoutParameter(final View rootView, final View targetView, ByteBuffer in) { 401f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy int l = in.getInt(); 402f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy String param = getString(in, l); 403f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy int value = in.getInt(); 404f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy try { 405f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy ViewDebug.setLayoutParameter(targetView, param, value); 406f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } catch (Exception e) { 407f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy Log.e(TAG, "Exception setting layout parameter: " + e); 408f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy return createFailChunk(ERR_EXCEPTION, "Error accessing field " 409f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy + param + ":" + e.getMessage()); 410f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy } 411f9455fafb690f23cee9cc9a59bfb68f31e695990Siva Velusamy 412945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return null; 413945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 414945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 415945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy /** Profiles provided view. */ 416945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy private Chunk profileView(View rootView, final View targetView) { 417945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ByteArrayOutputStream b = new ByteArrayOutputStream(32 * 1024); 418945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(b), 32 * 1024); 419945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 420945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy ViewDebug.profileViewAndChildren(targetView, bw); 421945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } catch (IOException e) { 422945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return createFailChunk(1, "Unexpected error while profiling view: " + e.getMessage()); 423945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } finally { 424945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy try { 425945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy bw.close(); 426945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } catch (IOException e) { 427945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy // ignore 428945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 429945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 430945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy 431945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy byte[] data = b.toByteArray(); 432945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy return new Chunk(CHUNK_VUOP, data, 0, data.length); 433945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy } 434945bfb6068d4ac1414a37a3ebe4dc4d02383e38eSiva Velusamy} 435