1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.recents.misc; 18 19 20 import android.content.ComponentCallbacks2; 21 import android.content.Context; 22 import android.util.Log; 23 import android.view.MotionEvent; 24 import android.widget.Toast; 25 26 import java.util.HashMap; 27 import java.util.Map; 28 29 30 public class Console { 31 // Timer 32 public static final Map<Object, Long> mTimeLogs = new HashMap<Object, Long>(); 33 34 // Colors 35 public static final String AnsiReset = "\u001B[0m"; 36 public static final String AnsiBlack = "\u001B[30m"; 37 public static final String AnsiRed = "\u001B[31m"; // SystemUIHandshake 38 public static final String AnsiGreen = "\u001B[32m"; // MeasureAndLayout 39 public static final String AnsiYellow = "\u001B[33m"; // SynchronizeViewsWithModel 40 public static final String AnsiBlue = "\u001B[34m"; // TouchEvents, Search 41 public static final String AnsiPurple = "\u001B[35m"; // Draw 42 public static final String AnsiCyan = "\u001B[36m"; // ClickEvents 43 public static final String AnsiWhite = "\u001B[37m"; 44 45 // Console enabled state 46 public static boolean Enabled = false; 47 48 /** Logs a key */ 49 public static void log(String key) { 50 log(true, key, "", AnsiReset); 51 } 52 53 /** Logs a conditioned key */ 54 public static void log(boolean condition, String key) { 55 if (condition) { 56 log(condition, key, "", AnsiReset); 57 } 58 } 59 60 /** Logs a key in a specific color */ 61 public static void log(boolean condition, String key, Object data) { 62 if (condition) { 63 log(condition, key, data, AnsiReset); 64 } 65 } 66 67 /** Logs a key with data in a specific color */ 68 public static void log(boolean condition, String key, Object data, String color) { 69 if (condition) { 70 System.out.println(color + key + AnsiReset + " " + data.toString()); 71 } 72 } 73 74 /** Logs an error */ 75 public static void logError(Context context, String msg) { 76 Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); 77 Log.e("Recents", msg); 78 } 79 80 /** Logs a raw error */ 81 public static void logRawError(String msg, Exception e) { 82 Log.e("Recents", msg, e); 83 } 84 85 /** Logs a divider bar */ 86 public static void logDivider(boolean condition) { 87 if (condition) { 88 System.out.println("==== [" + System.currentTimeMillis() + 89 "] ============================================================"); 90 } 91 } 92 93 /** Starts a time trace */ 94 public static void logStartTracingTime(boolean condition, String key) { 95 if (condition) { 96 long curTime = System.currentTimeMillis(); 97 mTimeLogs.put(key, curTime); 98 Console.log(condition, "[Recents|" + key + "]", 99 "started @ " + curTime); 100 } 101 } 102 103 /** Continues a time trace */ 104 public static void logTraceTime(boolean condition, String key, String desc) { 105 if (condition) { 106 long timeDiff = System.currentTimeMillis() - mTimeLogs.get(key); 107 Console.log(condition, "[Recents|" + key + "|" + desc + "]", 108 "+" + timeDiff + "ms"); 109 } 110 } 111 112 /** Logs a stack trace */ 113 public static void logStackTrace() { 114 logStackTrace("", 99); 115 } 116 117 /** Logs a stack trace to a certain depth */ 118 public static void logStackTrace(int depth) { 119 logStackTrace("", depth); 120 } 121 122 /** Logs a stack trace to a certain depth with a key */ 123 public static void logStackTrace(String key, int depth) { 124 int offset = 0; 125 StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 126 String tinyStackTrace = ""; 127 // Skip over the known stack trace classes 128 for (int i = 0; i < callStack.length; i++) { 129 StackTraceElement el = callStack[i]; 130 String className = el.getClassName(); 131 if (className.indexOf("dalvik.system.VMStack") == -1 && 132 className.indexOf("java.lang.Thread") == -1 && 133 className.indexOf("recents.Console") == -1) { 134 break; 135 } else { 136 offset++; 137 } 138 } 139 // Build the pretty stack trace 140 int start = Math.min(offset + depth, callStack.length); 141 int end = offset; 142 String indent = ""; 143 for (int i = start - 1; i >= end; i--) { 144 StackTraceElement el = callStack[i]; 145 tinyStackTrace += indent + " -> " + el.getClassName() + 146 "[" + el.getLineNumber() + "]." + el.getMethodName(); 147 if (i > end) { 148 tinyStackTrace += "\n"; 149 indent += " "; 150 } 151 } 152 log(true, key, tinyStackTrace, AnsiRed); 153 } 154 155 156 /** Returns the stringified MotionEvent action */ 157 public static String motionEventActionToString(int action) { 158 switch (action) { 159 case MotionEvent.ACTION_DOWN: 160 return "Down"; 161 case MotionEvent.ACTION_UP: 162 return "Up"; 163 case MotionEvent.ACTION_MOVE: 164 return "Move"; 165 case MotionEvent.ACTION_CANCEL: 166 return "Cancel"; 167 case MotionEvent.ACTION_POINTER_DOWN: 168 return "Pointer Down"; 169 case MotionEvent.ACTION_POINTER_UP: 170 return "Pointer Up"; 171 default: 172 return "" + action; 173 } 174 } 175 176 public static String trimMemoryLevelToString(int level) { 177 switch (level) { 178 case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN: 179 return "UI Hidden"; 180 case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE: 181 return "Running Moderate"; 182 case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND: 183 return "Background"; 184 case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW: 185 return "Running Low"; 186 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 187 return "Moderate"; 188 case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL: 189 return "Critical"; 190 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 191 return "Complete"; 192 default: 193 return "" + level; 194 } 195 } 196 } 197