• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.android.launcher3.util;
17 
18 
19 import android.text.TextUtils;
20 import android.util.Pair;
21 import android.util.Xml;
22 
23 import org.xmlpull.v1.XmlSerializer;
24 
25 import java.io.IOException;
26 import java.io.StringWriter;
27 import java.io.Writer;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.Map;
31 
32 /**
33  * Helper class to build xml for Launcher Layout
34  */
35 public class LauncherLayoutBuilder {
36 
37     // Object Tags
38     private static final String TAG_WORKSPACE = "workspace";
39     private static final String TAG_AUTO_INSTALL = "autoinstall";
40     private static final String TAG_FOLDER = "folder";
41     private static final String TAG_APPWIDGET = "appwidget";
42     private static final String TAG_SHORTCUT = "shortcut";
43     private static final String TAG_EXTRA = "extra";
44 
45     private static final String ATTR_CONTAINER = "container";
46     private static final String ATTR_RANK = "rank";
47 
48     private static final String ATTR_PACKAGE_NAME = "packageName";
49     private static final String ATTR_CLASS_NAME = "className";
50     private static final String ATTR_TITLE = "title";
51     private static final String ATTR_TITLE_TEXT = "titleText";
52     private static final String ATTR_SCREEN = "screen";
53     private static final String ATTR_SHORTCUT_ID = "shortcutId";
54 
55     // x and y can be specified as negative integers, in which case -1 represents the
56     // last row / column, -2 represents the second last, and so on.
57     private static final String ATTR_X = "x";
58     private static final String ATTR_Y = "y";
59     private static final String ATTR_SPAN_X = "spanX";
60     private static final String ATTR_SPAN_Y = "spanY";
61 
62     private static final String ATTR_CHILDREN = "children";
63 
64 
65     // Style attrs -- "Extra"
66     private static final String ATTR_KEY = "key";
67     private static final String ATTR_VALUE = "value";
68 
69     private static final String CONTAINER_DESKTOP = "desktop";
70     private static final String CONTAINER_HOTSEAT = "hotseat";
71 
72     private final ArrayList<Pair<String, HashMap<String, Object>>> mNodes = new ArrayList<>();
73 
atHotseat(int rank)74     public Location atHotseat(int rank) {
75         Location l = new Location();
76         l.items.put(ATTR_CONTAINER, CONTAINER_HOTSEAT);
77         l.items.put(ATTR_RANK, Integer.toString(rank));
78         return l;
79     }
80 
atWorkspace(int x, int y, int screen)81     public Location atWorkspace(int x, int y, int screen) {
82         Location l = new Location();
83         l.items.put(ATTR_CONTAINER, CONTAINER_DESKTOP);
84         l.items.put(ATTR_X, Integer.toString(x));
85         l.items.put(ATTR_Y, Integer.toString(y));
86         l.items.put(ATTR_SCREEN, Integer.toString(screen));
87         return l;
88     }
89 
build()90     public String build() throws IOException {
91         StringWriter writer = new StringWriter();
92         build(writer);
93         return writer.toString();
94     }
95 
build(Writer writer)96     public void build(Writer writer) throws IOException {
97         XmlSerializer serializer = Xml.newSerializer();
98         serializer.setOutput(writer);
99 
100         serializer.startDocument("UTF-8", true);
101         serializer.startTag(null, TAG_WORKSPACE);
102         writeNodes(serializer, mNodes);
103         serializer.endTag(null, TAG_WORKSPACE);
104         serializer.endDocument();
105         serializer.flush();
106     }
107 
writeNodes(XmlSerializer serializer, ArrayList<Pair<String, HashMap<String, Object>>> nodes)108     private static void writeNodes(XmlSerializer serializer,
109             ArrayList<Pair<String, HashMap<String, Object>>> nodes) throws IOException {
110         for (Pair<String, HashMap<String, Object>> node : nodes) {
111             ArrayList<Pair<String, HashMap<String, Object>>> children = null;
112 
113             serializer.startTag(null, node.first);
114             for (Map.Entry<String, Object> attr : node.second.entrySet()) {
115                 if (ATTR_CHILDREN.equals(attr.getKey())) {
116                     children = (ArrayList<Pair<String, HashMap<String, Object>>>) attr.getValue();
117                 } else {
118                     serializer.attribute(null, attr.getKey(), (String) attr.getValue());
119                 }
120             }
121 
122             if (children != null) {
123                 writeNodes(serializer, children);
124             }
125             serializer.endTag(null, node.first);
126         }
127     }
128 
129     public class Location {
130 
131         final HashMap<String, Object> items = new HashMap<>();
132 
putApp(String packageName, String className)133         public LauncherLayoutBuilder putApp(String packageName, String className) {
134             items.put(ATTR_PACKAGE_NAME, packageName);
135             items.put(ATTR_CLASS_NAME, TextUtils.isEmpty(className) ? packageName : className);
136             mNodes.add(Pair.create(TAG_AUTO_INSTALL, items));
137             return LauncherLayoutBuilder.this;
138         }
139 
putShortcut(String packageName, String shortcutId)140         public LauncherLayoutBuilder putShortcut(String packageName, String shortcutId) {
141             items.put(ATTR_PACKAGE_NAME, packageName);
142             items.put(ATTR_SHORTCUT_ID, shortcutId);
143             mNodes.add(Pair.create(TAG_SHORTCUT, items));
144             return LauncherLayoutBuilder.this;
145         }
146 
putWidget(String packageName, String className, int spanX, int spanY)147         public LauncherLayoutBuilder putWidget(String packageName, String className,
148                 int spanX, int spanY) {
149             items.put(ATTR_PACKAGE_NAME, packageName);
150             items.put(ATTR_CLASS_NAME, className);
151             items.put(ATTR_SPAN_X, Integer.toString(spanX));
152             items.put(ATTR_SPAN_Y, Integer.toString(spanY));
153             mNodes.add(Pair.create(TAG_APPWIDGET, items));
154             return LauncherLayoutBuilder.this;
155         }
156 
putFolder(int titleResId)157         public FolderBuilder putFolder(int titleResId) {
158             items.put(ATTR_TITLE, Integer.toString(titleResId));
159             return putFolder();
160         }
161 
putFolder(String title)162         public FolderBuilder putFolder(String title) {
163             items.put(ATTR_TITLE_TEXT, title);
164             return putFolder();
165         }
166 
putFolder()167         private FolderBuilder putFolder() {
168             FolderBuilder folderBuilder = new FolderBuilder();
169             items.put(ATTR_CHILDREN, folderBuilder.mChildren);
170             mNodes.add(Pair.create(TAG_FOLDER, items));
171             return folderBuilder;
172         }
173     }
174 
175     public class FolderBuilder {
176 
177         final ArrayList<Pair<String, HashMap<String, Object>>> mChildren = new ArrayList<>();
178 
addApp(String packageName, String className)179         public FolderBuilder addApp(String packageName, String className) {
180             HashMap<String, Object> items = new HashMap<>();
181             items.put(ATTR_PACKAGE_NAME, packageName);
182             items.put(ATTR_CLASS_NAME, TextUtils.isEmpty(className) ? packageName : className);
183             mChildren.add(Pair.create(TAG_AUTO_INSTALL, items));
184             return this;
185         }
186 
addShortcut(String packageName, String shortcutId)187         public FolderBuilder addShortcut(String packageName, String shortcutId) {
188             HashMap<String, Object> items = new HashMap<>();
189             items.put(ATTR_PACKAGE_NAME, packageName);
190             items.put(ATTR_SHORTCUT_ID, shortcutId);
191             mChildren.add(Pair.create(TAG_SHORTCUT, items));
192             return this;
193         }
194 
build()195         public LauncherLayoutBuilder build() {
196             return LauncherLayoutBuilder.this;
197         }
198     }
199 }
200