• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.Context;
19 import android.util.ArrayMap;
20 import android.util.SparseArray;
21 import android.view.View;
22 
23 import com.android.launcher3.AppInfo;
24 import com.android.launcher3.ButtonDropTarget;
25 import com.android.launcher3.ItemInfo;
26 import com.android.launcher3.LauncherSettings;
27 import com.android.launcher3.userevent.nano.LauncherLogExtensions.TargetExtension;
28 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
29 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
30 import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
31 import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
32 import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
33 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
34 import com.android.launcher3.userevent.nano.LauncherLogProto.TipType;
35 import com.android.launcher3.util.InstantAppResolver;
36 
37 import java.lang.reflect.Field;
38 import java.lang.reflect.Modifier;
39 
40 /**
41  * Helper methods for logging.
42  */
43 public class LoggerUtils {
44     private static final ArrayMap<Class, SparseArray<String>> sNameCache = new ArrayMap<>();
45     private static final String UNKNOWN = "UNKNOWN";
46 
getFieldName(int value, Class c)47     public static String getFieldName(int value, Class c) {
48         SparseArray<String> cache;
49         synchronized (sNameCache) {
50             cache = sNameCache.get(c);
51             if (cache == null) {
52                 cache = new SparseArray<>();
53                 for (Field f : c.getDeclaredFields()) {
54                     if (f.getType() == int.class && Modifier.isStatic(f.getModifiers())) {
55                         try {
56                             f.setAccessible(true);
57                             cache.put(f.getInt(null), f.getName());
58                         } catch (IllegalAccessException e) {
59                             // Ignore
60                         }
61                     }
62                 }
63                 sNameCache.put(c, cache);
64             }
65         }
66         String result = cache.get(value);
67         return result != null ? result : UNKNOWN;
68     }
69 
getActionStr(Action action)70     public static String getActionStr(Action action) {
71         String str = "";
72         switch (action.type) {
73             case Action.Type.TOUCH:
74                 str += getFieldName(action.touch, Action.Touch.class);
75                 if (action.touch == Action.Touch.SWIPE || action.touch == Action.Touch.FLING) {
76                     str += " direction=" + getFieldName(action.dir, Action.Direction.class);
77                 }
78                 return str;
79             case Action.Type.COMMAND: return getFieldName(action.command, Action.Command.class);
80             default: return getFieldName(action.type, Action.Type.class);
81         }
82     }
83 
getTargetStr(Target t)84     public static String getTargetStr(Target t) {
85         if (t == null){
86             return "";
87         }
88         String str = "";
89         switch (t.type) {
90             case Target.Type.ITEM:
91                 str = getItemStr(t);
92                 break;
93             case Target.Type.CONTROL:
94                 str = getFieldName(t.controlType, ControlType.class);
95                 break;
96             case Target.Type.CONTAINER:
97                 str = getFieldName(t.containerType, ContainerType.class);
98                 if (t.containerType == ContainerType.WORKSPACE ||
99                         t.containerType == ContainerType.HOTSEAT) {
100                     str += " id=" + t.pageIndex;
101                 } else if (t.containerType == ContainerType.FOLDER) {
102                     str += " grid(" + t.gridX + "," + t.gridY+ ")";
103                 }
104                 break;
105             default:
106                 str += "UNKNOWN TARGET TYPE";
107         }
108 
109         if (t.tipType != TipType.DEFAULT_NONE) {
110             str += " " + getFieldName(t.tipType, TipType.class);
111         }
112 
113         return str;
114     }
115 
getItemStr(Target t)116     private static String getItemStr(Target t) {
117         String typeStr = getFieldName(t.itemType, ItemType.class);
118         if (t.packageNameHash != 0) {
119             typeStr += ", packageHash=" + t.packageNameHash;
120         }
121         if (t.componentHash != 0) {
122             typeStr += ", componentHash=" + t.componentHash;
123         }
124         if (t.intentHash != 0) {
125             typeStr += ", intentHash=" + t.intentHash;
126         }
127         if ((t.packageNameHash != 0 || t.componentHash != 0 || t.intentHash != 0) &&
128                 t.itemType != ItemType.TASK) {
129             typeStr += ", predictiveRank=" + t.predictedRank + ", grid(" + t.gridX + "," + t.gridY
130                     + "), span(" + t.spanX + "," + t.spanY
131                     + "), pageIdx=" + t.pageIndex;
132 
133         }
134         if (t.itemType == ItemType.TASK) {
135             typeStr += ", pageIdx=" + t.pageIndex;
136         }
137         return typeStr;
138     }
139 
newItemTarget(int itemType)140     public static Target newItemTarget(int itemType) {
141         Target t = newTarget(Target.Type.ITEM);
142         t.itemType = itemType;
143         return t;
144     }
145 
newItemTarget(View v, InstantAppResolver instantAppResolver)146     public static Target newItemTarget(View v, InstantAppResolver instantAppResolver) {
147         return (v.getTag() instanceof ItemInfo)
148                 ? newItemTarget((ItemInfo) v.getTag(), instantAppResolver)
149                 : newTarget(Target.Type.ITEM);
150     }
151 
newItemTarget(ItemInfo info, InstantAppResolver instantAppResolver)152     public static Target newItemTarget(ItemInfo info, InstantAppResolver instantAppResolver) {
153         Target t = newTarget(Target.Type.ITEM);
154 
155         switch (info.itemType) {
156             case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
157                 t.itemType = (instantAppResolver != null && info instanceof AppInfo
158                         && instantAppResolver.isInstantApp(((AppInfo) info)) )
159                         ? ItemType.WEB_APP
160                         : ItemType.APP_ICON;
161                 t.predictedRank = -100; // Never assigned
162                 break;
163             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
164                 t.itemType = ItemType.SHORTCUT;
165                 break;
166             case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
167                 t.itemType = ItemType.FOLDER_ICON;
168                 break;
169             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
170                 t.itemType = ItemType.WIDGET;
171                 break;
172             case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
173                 t.itemType = ItemType.DEEPSHORTCUT;
174                 break;
175         }
176         return t;
177     }
178 
newDropTarget(View v)179     public static Target newDropTarget(View v) {
180         if (!(v instanceof ButtonDropTarget)) {
181             return newTarget(Target.Type.CONTAINER);
182         }
183         if (v instanceof ButtonDropTarget) {
184             return ((ButtonDropTarget) v).getDropTargetForLogging();
185         }
186         return newTarget(Target.Type.CONTROL);
187     }
188 
newTarget(int targetType, TargetExtension extension)189     public static Target newTarget(int targetType, TargetExtension extension) {
190         Target t = new Target();
191         t.type = targetType;
192         t.extension = extension;
193         return t;
194     }
195 
newTarget(int targetType)196     public static Target newTarget(int targetType) {
197         Target t = new Target();
198         t.type = targetType;
199         return t;
200     }
201 
newControlTarget(int controlType)202     public static Target newControlTarget(int controlType) {
203         Target t = newTarget(Target.Type.CONTROL);
204         t.controlType = controlType;
205         return t;
206     }
207 
newContainerTarget(int containerType)208     public static Target newContainerTarget(int containerType) {
209         Target t = newTarget(Target.Type.CONTAINER);
210         t.containerType = containerType;
211         return t;
212     }
213 
newAction(int type)214     public static Action newAction(int type) {
215         Action a = new Action();
216         a.type = type;
217         return a;
218     }
219 
newCommandAction(int command)220     public static Action newCommandAction(int command) {
221         Action a = newAction(Action.Type.COMMAND);
222         a.command = command;
223         return a;
224     }
225 
newTouchAction(int touch)226     public static Action newTouchAction(int touch) {
227         Action a = newAction(Action.Type.TOUCH);
228         a.touch = touch;
229         return a;
230     }
231 
newLauncherEvent(Action action, Target... srcTargets)232     public static LauncherEvent newLauncherEvent(Action action, Target... srcTargets) {
233         LauncherEvent event = new LauncherEvent();
234         event.srcTarget = srcTargets;
235         event.action = action;
236         return event;
237     }
238 }
239