Merge "Bring back buttons in dialogs. Bug #2390537"
This commit is contained in:
@@ -89,6 +89,15 @@ public class ViewDebug {
|
||||
*/
|
||||
public static final boolean TRACE_RECYCLER = false;
|
||||
|
||||
/**
|
||||
* Enables or disables motion events tracing. Any invoker of
|
||||
* {@link #trace(View, MotionEvent, MotionEventTraceType)} should first check
|
||||
* that this value is set to true as not to affect performance.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final boolean TRACE_MOTION_EVENTS = false;
|
||||
|
||||
/**
|
||||
* The system property of dynamic switch for capturing view information
|
||||
* when it is set, we dump interested fields and methods for the view on focus
|
||||
@@ -367,7 +376,6 @@ public class ViewDebug {
|
||||
BIND_VIEW,
|
||||
RECYCLE_FROM_ACTIVE_HEAP,
|
||||
RECYCLE_FROM_SCRAP_HEAP,
|
||||
MOVE_TO_ACTIVE_HEAP,
|
||||
MOVE_TO_SCRAP_HEAP,
|
||||
MOVE_FROM_ACTIVE_TO_SCRAP_HEAP
|
||||
}
|
||||
@@ -384,6 +392,21 @@ public class ViewDebug {
|
||||
private static List<RecyclerTrace> sRecyclerTraces;
|
||||
private static String sRecyclerTracePrefix;
|
||||
|
||||
/**
|
||||
* Defines the type of motion events trace to output to the motion events traces file.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public enum MotionEventTraceType {
|
||||
DISPATCH,
|
||||
ON_INTERCEPT,
|
||||
ON_TOUCH
|
||||
}
|
||||
|
||||
private static BufferedWriter sMotionEventTraces;
|
||||
private static ViewRoot sMotionEventRoot;
|
||||
private static String sMotionEventTracePrefix;
|
||||
|
||||
/**
|
||||
* Returns the number of instanciated Views.
|
||||
*
|
||||
@@ -675,6 +698,146 @@ public class ViewDebug {
|
||||
sHierarhcyRoot = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a trace to the currently opened traces file. The trace contains the class name
|
||||
* and instance's hashcode of the specified view as well as the supplied trace type.
|
||||
*
|
||||
* @param view the view to trace
|
||||
* @param event the event of the trace
|
||||
* @param type the type of the trace
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static void trace(View view, MotionEvent event, MotionEventTraceType type) {
|
||||
if (sMotionEventTraces == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sMotionEventTraces.write(type.name());
|
||||
sMotionEventTraces.write(' ');
|
||||
sMotionEventTraces.write(event.getAction());
|
||||
sMotionEventTraces.write(' ');
|
||||
sMotionEventTraces.write(view.getClass().getName());
|
||||
sMotionEventTraces.write('@');
|
||||
sMotionEventTraces.write(Integer.toHexString(view.hashCode()));
|
||||
sHierarchyTraces.newLine();
|
||||
} catch (IOException e) {
|
||||
Log.w("View", "Error while dumping trace of event " + event + " for view " + view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts tracing the motion events for the hierarchy of the specificy view.
|
||||
* The trace is identified by a prefix, used to build the traces files names:
|
||||
* <code>/EXTERNAL/motion-events/PREFIX.traces</code> and
|
||||
* <code>/EXTERNAL/motion-events/PREFIX.tree</code>.
|
||||
*
|
||||
* Only one view hierarchy can be traced at the same time. After calling this method, any
|
||||
* other invocation will result in a <code>IllegalStateException</code> unless
|
||||
* {@link #stopMotionEventTracing()} is invoked before.
|
||||
*
|
||||
* Calling this method creates the file <code>/EXTERNAL/motion-events/PREFIX.traces</code>
|
||||
* containing all the traces (or method calls) relative to the specified view's hierarchy.
|
||||
*
|
||||
* This method will return immediately if TRACE_HIERARCHY is false.
|
||||
*
|
||||
* @param prefix the traces files name prefix
|
||||
* @param view the view whose hierarchy must be traced
|
||||
*
|
||||
* @see #stopMotionEventTracing()
|
||||
* @see #trace(View, MotionEvent, android.view.ViewDebug.MotionEventTraceType)
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static void startMotionEventTracing(String prefix, View view) {
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (!TRACE_MOTION_EVENTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sMotionEventRoot != null) {
|
||||
throw new IllegalStateException("You must call stopMotionEventTracing() before running" +
|
||||
" a new trace!");
|
||||
}
|
||||
|
||||
File hierarchyDump = new File(Environment.getExternalStorageDirectory(), "motion-events/");
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
hierarchyDump.mkdirs();
|
||||
|
||||
hierarchyDump = new File(hierarchyDump, prefix + ".traces");
|
||||
sMotionEventTracePrefix = prefix;
|
||||
|
||||
try {
|
||||
sMotionEventTraces = new BufferedWriter(new FileWriter(hierarchyDump), 32 * 1024);
|
||||
} catch (IOException e) {
|
||||
Log.e("View", "Could not dump view hierarchy");
|
||||
return;
|
||||
}
|
||||
|
||||
sMotionEventRoot = (ViewRoot) view.getRootView().getParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the current motion events tracing. This method closes the file
|
||||
* <code>/EXTERNAL/motion-events/PREFIX.traces</code>.
|
||||
*
|
||||
* Calling this method creates the file <code>/EXTERNAL/motion-events/PREFIX.tree</code>
|
||||
* containing the view hierarchy of the view supplied to
|
||||
* {@link #startMotionEventTracing(String, View)}.
|
||||
*
|
||||
* This method will return immediately if TRACE_HIERARCHY is false.
|
||||
*
|
||||
* @see #startMotionEventTracing(String, View)
|
||||
* @see #trace(View, MotionEvent, android.view.ViewDebug.MotionEventTraceType)
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static void stopMotionEventTracing() {
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (!TRACE_MOTION_EVENTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sMotionEventRoot == null || sMotionEventTraces == null) {
|
||||
throw new IllegalStateException("You must call startMotionEventTracing() before" +
|
||||
" stopMotionEventTracing()!");
|
||||
}
|
||||
|
||||
try {
|
||||
sMotionEventTraces.close();
|
||||
} catch (IOException e) {
|
||||
Log.e("View", "Could not write view traces");
|
||||
}
|
||||
sMotionEventTraces = null;
|
||||
|
||||
File hierarchyDump = new File(Environment.getExternalStorageDirectory(), "motion-events/");
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
hierarchyDump.mkdirs();
|
||||
hierarchyDump = new File(hierarchyDump, sMotionEventTracePrefix + ".tree");
|
||||
|
||||
BufferedWriter out;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(hierarchyDump), 8 * 1024);
|
||||
} catch (IOException e) {
|
||||
Log.e("View", "Could not dump view hierarchy");
|
||||
return;
|
||||
}
|
||||
|
||||
View view = sMotionEventRoot.getView();
|
||||
if (view instanceof ViewGroup) {
|
||||
ViewGroup group = (ViewGroup) view;
|
||||
dumpViewHierarchy(group, out, 0);
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
Log.e("View", "Could not dump view hierarchy");
|
||||
}
|
||||
}
|
||||
|
||||
sHierarhcyRoot = null;
|
||||
}
|
||||
|
||||
static void dispatchCommand(View view, String command, String parameters,
|
||||
OutputStream clientStream) throws IOException {
|
||||
|
||||
|
||||
@@ -754,7 +754,7 @@ public class LinearLayout extends ViewGroup {
|
||||
maxHeight = Math.max(maxHeight, ascent + descent);
|
||||
}
|
||||
|
||||
if (useLargestChild) {
|
||||
if (useLargestChild && widthMode == MeasureSpec.AT_MOST) {
|
||||
mTotalLength = 0;
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
|
||||
Reference in New Issue
Block a user