1 /*
2  * Copyright (C) 2017 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 static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
19 
20 import android.content.ComponentName;
21 import android.os.Process;
22 import android.text.TextUtils;
23 
24 import com.android.launcher3.ItemInfo;
25 import com.android.launcher3.LauncherAppWidgetInfo;
26 import com.android.launcher3.LauncherSettings;
27 import com.android.launcher3.WorkspaceItemInfo;
28 import com.android.launcher3.model.nano.LauncherDumpProto;
29 import com.android.launcher3.model.nano.LauncherDumpProto.ContainerType;
30 import com.android.launcher3.model.nano.LauncherDumpProto.DumpTarget;
31 import com.android.launcher3.model.nano.LauncherDumpProto.ItemType;
32 import com.android.launcher3.model.nano.LauncherDumpProto.UserType;
33 import com.android.launcher3.util.ShortcutUtil;
34 
35 import java.util.ArrayList;
36 import java.util.List;
37 
38 /**
39  * This class can be used when proto definition doesn't support nesting.
40  */
41 public class DumpTargetWrapper {
42     DumpTarget node;
43     ArrayList<DumpTargetWrapper> children;
44 
DumpTargetWrapper()45     public DumpTargetWrapper() {
46         children = new ArrayList<>();
47     }
48 
DumpTargetWrapper(int containerType, int id)49     public DumpTargetWrapper(int containerType, int id) {
50         this();
51         node = newContainerTarget(containerType, id);
52     }
53 
DumpTargetWrapper(ItemInfo info)54     public DumpTargetWrapper(ItemInfo info) {
55         this();
56         node = newItemTarget(info);
57     }
58 
getDumpTarget()59     public DumpTarget getDumpTarget() {
60         return node;
61     }
62 
add(DumpTargetWrapper child)63     public void add(DumpTargetWrapper child) {
64         children.add(child);
65     }
66 
getFlattenedList()67     public List<DumpTarget> getFlattenedList() {
68         ArrayList<DumpTarget> list = new ArrayList<>();
69         list.add(node);
70         if (!children.isEmpty()) {
71             for(DumpTargetWrapper t: children) {
72                 list.addAll(t.getFlattenedList());
73             }
74             list.add(node); // add a delimiter empty object
75         }
76         return list;
77     }
newItemTarget(ItemInfo info)78     public DumpTarget newItemTarget(ItemInfo info) {
79         DumpTarget dt = new DumpTarget();
80         dt.type = DumpTarget.Type.ITEM;
81         if (info == null) {
82             return dt;
83         }
84         switch (info.itemType) {
85             case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
86                 dt.itemType = ItemType.APP_ICON;
87                 break;
88             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
89                 dt.itemType = ItemType.WIDGET;
90                 break;
91             case ITEM_TYPE_DEEP_SHORTCUT:
92             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
93                 dt.itemType = ItemType.SHORTCUT;
94                 break;
95             default:
96                 dt.itemType = ItemType.UNKNOWN_ITEMTYPE;
97                 break;
98         }
99         return dt;
100     }
101 
newContainerTarget(int type, int id)102     public DumpTarget newContainerTarget(int type, int id) {
103         DumpTarget dt = new DumpTarget();
104         dt.type = DumpTarget.Type.CONTAINER;
105         dt.containerType = type;
106         dt.pageId = id;
107         return dt;
108     }
109 
getDumpTargetStr(DumpTarget t)110     public static String getDumpTargetStr(DumpTarget t) {
111         if (t == null){
112             return "";
113         }
114         switch (t.type) {
115             case LauncherDumpProto.DumpTarget.Type.ITEM:
116                 return getItemStr(t);
117             case LauncherDumpProto.DumpTarget.Type.CONTAINER:
118                 String str = LoggerUtils.getFieldName(t.containerType, ContainerType.class);
119                 if (t.containerType == ContainerType.WORKSPACE) {
120                     str += " id=" + t.pageId;
121                 } else if (t.containerType == ContainerType.FOLDER) {
122                     str += " grid(" + t.gridX + "," + t.gridY+ ")";
123                 }
124                 return str;
125             default:
126                 return "UNKNOWN TARGET TYPE";
127         }
128     }
129 
getItemStr(DumpTarget t)130     private static String getItemStr(DumpTarget t) {
131         if (t == null) {
132             return "";
133         }
134         String typeStr = LoggerUtils.getFieldName(t.itemType, ItemType.class);
135         if (!TextUtils.isEmpty(t.packageName)) {
136             typeStr += ", package=" + t.packageName;
137         }
138         if (!TextUtils.isEmpty(t.component)) {
139             typeStr += ", component=" + t.component;
140         }
141         return typeStr + ", grid(" + t.gridX + "," + t.gridY + "), span(" + t.spanX + "," + t.spanY
142                 + "), pageIdx=" + t.pageId + " user=" + t.userType;
143     }
144 
writeToDumpTarget(ItemInfo info)145     public DumpTarget writeToDumpTarget(ItemInfo info) {
146         if (info == null) {
147             return node;
148         }
149         if (ShortcutUtil.isDeepShortcut(info)) {
150             node.component = ((WorkspaceItemInfo) info).getDeepShortcutId();
151         } else {
152             ComponentName cmp = info.getTargetComponent();
153             node.component = cmp == null ? "" : cmp.flattenToString();
154         }
155         node.packageName = info.getTargetComponent() == null? "":
156                 info.getTargetComponent().getPackageName();
157         if (info instanceof LauncherAppWidgetInfo) {
158             node.component = ((LauncherAppWidgetInfo) info).providerName.flattenToString();
159             node.packageName = ((LauncherAppWidgetInfo) info).providerName.getPackageName();
160         }
161 
162         node.gridX = info.cellX;
163         node.gridY = info.cellY;
164         node.spanX = info.spanX;
165         node.spanY = info.spanY;
166         node.userType = (info.user.equals(Process.myUserHandle()))? UserType.DEFAULT : UserType.WORK;
167         return node;
168     }
169 }
170