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;

import static android.view.MotionEvent.ACTION_DOWN;

/**
 * Utilities useful for debugging
 * @suppress
 */
@SuppressLint("LogConditional")
public class Debug {

    /**
     * This logs n elements in the stack
     *
     * @param tag
     * @param msg
     * @param n
     * @suppress
     */
    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
     * @suppress
     */
    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
     * @suppress
     */
    public static String getName(View view) {
        try {
            Context context = view.getContext();
            return context.getResources().getResourceEntryName(view.getId());
        } catch (Exception ex) {
            return "UNKNOWN";
        }
    }

    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
     * @suppress
     */
    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
     * @suppress
     */
    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()+")";
    }

    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) {

                }

            }

        }
    }

    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);

        }
}