1 /* 2 * Copyright (C) 2016 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 package com.android.launcher3.logging; 17 18 import android.util.ArrayMap; 19 import android.util.SparseArray; 20 import android.view.View; 21 22 import com.android.launcher3.ButtonDropTarget; 23 import com.android.launcher3.LauncherSettings; 24 import com.android.launcher3.model.data.AppInfo; 25 import com.android.launcher3.model.data.ItemInfo; 26 import com.android.launcher3.userevent.nano.LauncherLogExtensions.TargetExtension; 27 import com.android.launcher3.userevent.nano.LauncherLogProto.Action; 28 import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType; 29 import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent; 30 import com.android.launcher3.userevent.nano.LauncherLogProto.Target; 31 import com.android.launcher3.util.InstantAppResolver; 32 33 import java.lang.reflect.Field; 34 import java.lang.reflect.Modifier; 35 import java.util.ArrayList; 36 37 /** 38 * Helper methods for logging. 39 */ 40 public class LoggerUtils { 41 private static final ArrayMap<Class, SparseArray<String>> sNameCache = new ArrayMap<>(); 42 private static final String UNKNOWN = "UNKNOWN"; 43 private static final int DEFAULT_PREDICTED_RANK = 10000; 44 private static final String DELIMITER_DOT = "\\."; 45 getFieldName(int value, Class c)46 public static String getFieldName(int value, Class c) { 47 SparseArray<String> cache; 48 synchronized (sNameCache) { 49 cache = sNameCache.get(c); 50 if (cache == null) { 51 cache = new SparseArray<>(); 52 for (Field f : c.getDeclaredFields()) { 53 if (f.getType() == int.class && Modifier.isStatic(f.getModifiers())) { 54 try { 55 f.setAccessible(true); 56 cache.put(f.getInt(null), f.getName()); 57 } catch (IllegalAccessException e) { 58 // Ignore 59 } 60 } 61 } 62 sNameCache.put(c, cache); 63 } 64 } 65 String result = cache.get(value); 66 return result != null ? result : UNKNOWN; 67 } 68 newItemTarget(int itemType)69 public static Target newItemTarget(int itemType) { 70 Target t = newTarget(Target.Type.ITEM); 71 t.itemType = itemType; 72 return t; 73 } 74 newItemTarget(View v, InstantAppResolver instantAppResolver)75 public static Target newItemTarget(View v, InstantAppResolver instantAppResolver) { 76 return (v != null) && (v.getTag() instanceof ItemInfo) 77 ? newItemTarget((ItemInfo) v.getTag(), instantAppResolver) 78 : newTarget(Target.Type.ITEM); 79 } 80 newItemTarget(ItemInfo info, InstantAppResolver instantAppResolver)81 public static Target newItemTarget(ItemInfo info, InstantAppResolver instantAppResolver) { 82 Target t = newTarget(Target.Type.ITEM); 83 switch (info.itemType) { 84 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 85 t.itemType = (instantAppResolver != null && info instanceof AppInfo 86 && instantAppResolver.isInstantApp(((AppInfo) info))) 87 ? ItemType.WEB_APP 88 : ItemType.APP_ICON; 89 t.predictedRank = DEFAULT_PREDICTED_RANK; 90 break; 91 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 92 t.itemType = ItemType.SHORTCUT; 93 t.predictedRank = DEFAULT_PREDICTED_RANK; 94 break; 95 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 96 t.itemType = ItemType.FOLDER_ICON; 97 break; 98 case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 99 t.itemType = ItemType.WIDGET; 100 break; 101 case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: 102 t.itemType = ItemType.DEEPSHORTCUT; 103 t.predictedRank = DEFAULT_PREDICTED_RANK; 104 break; 105 } 106 return t; 107 } 108 newDropTarget(View v)109 public static Target newDropTarget(View v) { 110 if (!(v instanceof ButtonDropTarget)) { 111 return newTarget(Target.Type.CONTAINER); 112 } 113 if (v instanceof ButtonDropTarget) { 114 return ((ButtonDropTarget) v).getDropTargetForLogging(); 115 } 116 return newTarget(Target.Type.CONTROL); 117 } 118 newTarget(int targetType, TargetExtension extension)119 public static Target newTarget(int targetType, TargetExtension extension) { 120 Target t = new Target(); 121 t.type = targetType; 122 t.extension = extension; 123 return t; 124 } 125 newTarget(int targetType)126 public static Target newTarget(int targetType) { 127 Target t = new Target(); 128 t.type = targetType; 129 return t; 130 } 131 newControlTarget(int controlType)132 public static Target newControlTarget(int controlType) { 133 Target t = newTarget(Target.Type.CONTROL); 134 t.controlType = controlType; 135 return t; 136 } 137 newContainerTarget(int containerType)138 public static Target newContainerTarget(int containerType) { 139 Target t = newTarget(Target.Type.CONTAINER); 140 t.containerType = containerType; 141 return t; 142 } 143 newAction(int type)144 public static Action newAction(int type) { 145 Action a = new Action(); 146 a.type = type; 147 return a; 148 } 149 newCommandAction(int command)150 public static Action newCommandAction(int command) { 151 Action a = newAction(Action.Type.COMMAND); 152 a.command = command; 153 return a; 154 } 155 newTouchAction(int touch)156 public static Action newTouchAction(int touch) { 157 Action a = newAction(Action.Type.TOUCH); 158 a.touch = touch; 159 return a; 160 } 161 newLauncherEvent(Action action, Target... srcTargets)162 public static LauncherEvent newLauncherEvent(Action action, Target... srcTargets) { 163 LauncherEvent event = new LauncherEvent(); 164 event.srcTarget = srcTargets; 165 event.action = action; 166 return event; 167 } 168 169 /** 170 * Creates LauncherEvent using Action and ArrayList of Targets 171 */ newLauncherEvent(Action action, ArrayList<Target> targets)172 public static LauncherEvent newLauncherEvent(Action action, ArrayList<Target> targets) { 173 Target[] targetsArray = new Target[targets.size()]; 174 targets.toArray(targetsArray); 175 return newLauncherEvent(action, targetsArray); 176 } 177 178 /** 179 * String conversion for only the helpful parts of {@link Object#toString()} method 180 * @param stringToExtract "foo.bar.baz.MyObject@1234" 181 * @return "MyObject@1234" 182 */ extractObjectNameAndAddress(String stringToExtract)183 public static String extractObjectNameAndAddress(String stringToExtract) { 184 String[] superStringParts = stringToExtract.split(DELIMITER_DOT); 185 if (superStringParts.length == 0) { 186 return ""; 187 } 188 return superStringParts[superStringParts.length - 1]; 189 } 190 } 191