Home | History | Annotate | Download | only in logging
      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 
     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 
     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 
     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 
    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 
    140     public static Target newItemTarget(int itemType) {
    141         Target t = newTarget(Target.Type.ITEM);
    142         t.itemType = itemType;
    143         return t;
    144     }
    145 
    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 
    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 
    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 
    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 
    196     public static Target newTarget(int targetType) {
    197         Target t = new Target();
    198         t.type = targetType;
    199         return t;
    200     }
    201 
    202     public static Target newControlTarget(int controlType) {
    203         Target t = newTarget(Target.Type.CONTROL);
    204         t.controlType = controlType;
    205         return t;
    206     }
    207 
    208     public static Target newContainerTarget(int containerType) {
    209         Target t = newTarget(Target.Type.CONTAINER);
    210         t.containerType = containerType;
    211         return t;
    212     }
    213 
    214     public static Action newAction(int type) {
    215         Action a = new Action();
    216         a.type = type;
    217         return a;
    218     }
    219 
    220     public static Action newCommandAction(int command) {
    221         Action a = newAction(Action.Type.COMMAND);
    222         a.command = command;
    223         return a;
    224     }
    225 
    226     public static Action newTouchAction(int touch) {
    227         Action a = newAction(Action.Type.TOUCH);
    228         a.touch = touch;
    229         return a;
    230     }
    231 
    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