Debug.java
/*
* Copyright (C) 2018 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 androidx.constraintlayout.motion.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import java.lang.reflect.Field;
import java.nio.CharBuffer;
/**
* Utilities useful for debugging
*
* @DoNotShow
*/
@SuppressLint("LogConditional")
public class Debug {
/**
* This logs n elements in the stack
*
* @param tag
* @param msg
* @param n
* @DoNotShow
*/
public static void logStack(String tag, String msg, int n) {
StackTraceElement[] st = new Throwable().getStackTrace();
String s = " ";
n = Math.min(n, st.length - 1);
for (int i = 1; i <= n; i++) {
StackTraceElement ste = st[i];
String stack = ".(" + st[i].getFileName() + ":" + st[i].getLineNumber()
+ ") " + st[i].getMethodName();
s += " ";
Log.v(tag, msg + s + stack + s);
}
}
/**
* This logs n elements in the stack
*
* @param msg
* @param n
* @DoNotShow
*/
public static void printStack(String msg, int n) {
StackTraceElement[] st = new Throwable().getStackTrace();
String s = " ";
n = Math.min(n, st.length - 1);
for (int i = 1; i <= n; i++) {
StackTraceElement ste = st[i];
String stack = ".(" + st[i].getFileName() + ":" + st[i].getLineNumber() + ") ";
s += " ";
System.out.println(msg + s + stack + s);
}
}
/**
* This provides return the name of a view
*
* @param view
* @return name of view
* @DoNotShow
*/
public static String getName(View view) {
try {
Context context = view.getContext();
return context.getResources().getResourceEntryName(view.getId());
} catch (Exception ex) {
return "UNKNOWN";
}
}
/**
* @TODO: add description
* @param obj
*/
public static void dumpPoc(Object obj) {
StackTraceElement s = new Throwable().getStackTrace()[1];
String loc = ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
Class c = obj.getClass();
System.out.println(loc + "------------- " + c.getName() + " --------------------");
Field[] declaredFields = c.getFields();
for (int i = 0; i < declaredFields.length; i++) {
Field declaredField = declaredFields[i];
try {
Object value = declaredField.get(obj);
if (!declaredField.getName().startsWith("layout_constraint")) {
continue;
}
if (value instanceof Integer && value.toString().equals("-1")) {
continue;
}
if (value instanceof Integer && value.toString().equals("0")) {
continue;
}
if (value instanceof Float && value.toString().equals("1.0")) {
continue;
}
if (value instanceof Float && value.toString().equals("0.5")) {
continue;
}
System.out.println(loc + " " + declaredField.getName() + " " + value);
} catch (IllegalAccessException e) {
}
}
System.out.println(loc + "------------- " + c.getSimpleName() + " --------------------");
}
/**
* This returns the name of a view given its id
*
* @param context
* @param id
* @return name of view
* @DoNotShow
*/
public static String getName(Context context, int id) {
try {
if (id != -1) {
return context.getResources().getResourceEntryName(id);
} else {
return "UNKNOWN";
}
} catch (Exception ex) {
return "?" + id;
}
}
/**
* This returns the name of a view given its id
*
* @param context
* @param id
* @return name of view
* @DoNotShow
*/
public static String getName(Context context, int[] id) {
try {
String str = id.length + "[";
for (int i = 0; i < id.length; i++) {
str += (i == 0) ? "" : " ";
String tmp = null;
try {
tmp = context.getResources().getResourceEntryName(id[i]);
} catch (Resources.NotFoundException e) {
tmp = "? " + id[i] + " ";
}
str += tmp;
}
return str + "]";
} catch (Exception ex) {
Log.v("DEBUG", ex.toString());
return "UNKNOWN";
}
}
/**
* convert an id number to an id String useful in debugging
*
* @param layout
* @param stateId
* @return
*/
public static String getState(MotionLayout layout, int stateId) {
return getState(layout, stateId, -1);
}
/**
* convert an id number to an id String useful in debugging
*
* @param layout
* @param stateId
* @param len trim if string > len
* @return
*/
public static String getState(MotionLayout layout, int stateId, int len) {
if (stateId == -1) {
return "UNDEFINED";
}
Context context = layout.getContext();
String str = context.getResources().getResourceEntryName(stateId);
if (len != -1) {
if (str.length() > len) {
str = str.replaceAll("([^_])[aeiou]+", "$1"); // del vowels ! at start
}
if (str.length() > len) {
int n = str.replaceAll("[^_]", "").length(); // count number of "_"
if (n > 0) {
int extra = (str.length() - len) / n;
String reg = CharBuffer.allocate(extra).toString().replace('eb3b9ed0-f11d-0137-cfb9-0ebaa35b92c0', '.') + "_";
str = str.replaceAll(reg, "_");
}
}
}
return str;
}
/**
* Convert a motion event action to a string
*
* @param event
* @return
*/
public static String getActionType(MotionEvent event) {
int type = event.getAction();
Field[] fields = MotionEvent.class.getFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
try {
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())
&& field.getType().equals(Integer.TYPE)
&& field.getInt(null) == type) {
return field.getName();
}
} catch (IllegalAccessException e) {
}
}
return "---";
}
/**
* Get file name and location where this method is called.
* Formatting it such that it is clickable by Intellij
*
* @return (filename : line_no)
*/
public static String getLocation() {
StackTraceElement s = new Throwable().getStackTrace()[1];
return ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
}
/**
* Get file name and location where this method is called.
* Formatting it such that it is clickable by Intellij
*
* @return (filename : line_no)
*/
public static String getLoc() {
StackTraceElement s = new Throwable().getStackTrace()[1];
return ".(" + s.getFileName() + ":" + s.getLineNumber() + ") " + s.getMethodName() + "()";
}
/**
* Get file name and location where this method is called.
* Formatting it such that it is clickable by Intellij
*
* @return (filename : line_no)
*/
public static String getLocation2() {
StackTraceElement s = new Throwable().getStackTrace()[2];
return ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
}
/**
* Get file name and location where this method is called.
* Formatting it such that it is clickable by Intellij
*
* @return (filename : line_no)
*/
public static String getCallFrom(int n) {
StackTraceElement s = new Throwable().getStackTrace()[2 + n];
return ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
}
/**
* @TODO: add description
* @param layout
* @param str
*/
public static void dumpLayoutParams(ViewGroup layout, String str) {
StackTraceElement s = new Throwable().getStackTrace()[1];
String loc = ".(" + s.getFileName() + ":" + s.getLineNumber() + ") " + str + " ";
int n = layout.getChildCount();
System.out.println(str + " children " + n);
for (int i = 0; i < n; i++) {
View v = layout.getChildAt(i);
System.out.println(loc + " " + getName(v));
ViewGroup.LayoutParams param = v.getLayoutParams();
Field[] declaredFields = param.getClass().getFields();
for (int k = 0; k < declaredFields.length; k++) {
Field declaredField = declaredFields[k];
try {
Object value = declaredField.get(param);
String name = declaredField.getName();
if (!(name.contains("To"))) {
continue;
}
if (value.toString().equals("-1")) {
continue;
}
System.out.println(loc + " " + declaredField.getName() + " " + value);
} catch (IllegalAccessException e) {
}
}
}
}
/**
* @TODO: add description
* @param param
* @param str
*/
public static void dumpLayoutParams(ViewGroup.LayoutParams param, String str) {
StackTraceElement s = new Throwable().getStackTrace()[1];
String loc = ".(" + s.getFileName() + ":" + s.getLineNumber() + ") " + str + " ";
System.out.println(" >>>>>>>>>>>>>>>>>>. dump " + loc + " " + param.getClass().getName());
Field[] declaredFields = param.getClass().getFields();
for (int k = 0; k < declaredFields.length; k++) {
Field declaredField = declaredFields[k];
try {
Object value = declaredField.get(param);
String name = declaredField.getName();
if (!name.contains("To")) {
continue;
}
if (value.toString().equals("-1")) {
continue;
}
// if (value instanceof Integer && value.toString().equals("-1")) {
// continue;
// }
System.out.println(loc + " " + name + " " + value);
} catch (IllegalAccessException e) {
}
}
System.out.println(" <<<<<<<<<<<<<<<<< dump " + loc);
}
}