blob: 05237d0b991ae27b7c043e30bd07623acfce1f65 [file] [log] [blame]
Joe Onorato6f9d4bd2010-09-29 17:43:46 -07001#!/usr/bin/env python2.5
2
3import cgi
Winson Chung88381732013-07-12 13:41:18 -07004import codecs
Joe Onorato6f9d4bd2010-09-29 17:43:46 -07005import os
Winson Chung88381732013-07-12 13:41:18 -07006import pprint
Joe Onorato6f9d4bd2010-09-29 17:43:46 -07007import shutil
8import sys
9import sqlite3
10
Winson Chung88381732013-07-12 13:41:18 -070011SCREENS = 0
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070012COLUMNS = 4
13ROWS = 4
Winson Chung88381732013-07-12 13:41:18 -070014HOTSEAT_SIZE = 4
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070015CELL_SIZE = 110
16
Winson Chung88381732013-07-12 13:41:18 -070017CONTAINER_DESKTOP = -100
18CONTAINER_HOTSEAT = -101
19
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070020DIR = "db_files"
21AUTO_FILE = DIR + "/launcher.db"
22INDEX_FILE = DIR + "/index.html"
23
24def usage():
Winson Chung88381732013-07-12 13:41:18 -070025 print "usage: print_db.py launcher.db <sw600|sw720> -- prints a launcher.db"
26 print "usage: print_db.py <sw600|sw720> -- adb pulls a launcher.db from a device"
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070027 print " and prints it"
28 print
29 print "The dump will be created in a directory called db_files in cwd."
30 print "This script will delete any db_files directory you have now"
31
32
33def make_dir():
34 shutil.rmtree(DIR, True)
35 os.makedirs(DIR)
36
Winson Chungd64d1762013-08-20 14:37:16 -070037def adb_root_remount():
38 os.system("adb root")
39 os.system("adb remount")
40
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070041def pull_file(fn):
42 print "pull_file: " + fn
43 rv = os.system("adb pull"
Winson Chung88381732013-07-12 13:41:18 -070044 + " /data/data/com.google.android.googlequicksearchbox/databases/launcher.db"
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070045 + " " + fn);
46 if rv != 0:
47 print "adb pull failed"
48 sys.exit(1)
49
50def get_favorites(conn):
51 c = conn.cursor()
52 c.execute("SELECT * FROM favorites")
53 columns = [d[0] for d in c.description]
54 rows = []
55 for row in c:
56 rows.append(row)
57 return columns,rows
58
Winson Chungd64d1762013-08-20 14:37:16 -070059def get_screens(conn):
60 c = conn.cursor()
61 c.execute("SELECT * FROM workspaceScreens")
62 columns = [d[0] for d in c.description]
63 rows = []
64 for row in c:
65 rows.append(row)
66 return columns,rows
67
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070068def print_intent(out, id, i, cell):
69 if cell:
70 out.write("""<span class="intent" title="%s">shortcut</span>""" % (
71 cgi.escape(cell, True)
72 ))
73
74
75def print_icon(out, id, i, cell):
76 if cell:
77 icon_fn = "icon_%d.png" % id
Winson Chung88381732013-07-12 13:41:18 -070078 out.write("""<img style="width: 3em; height: 3em;" src="%s">""" % ( icon_fn ))
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070079 f = file(DIR + "/" + icon_fn, "w")
80 f.write(cell)
81 f.close()
82
Winson Chung88381732013-07-12 13:41:18 -070083def print_icon_type(out, id, i, cell):
84 if cell == 0:
85 out.write("Application (%d)" % cell)
86 elif cell == 1:
87 out.write("Shortcut (%d)" % cell)
88 elif cell == 2:
89 out.write("Folder (%d)" % cell)
90 elif cell == 4:
91 out.write("Widget (%d)" % cell)
92 elif cell:
93 out.write("%d" % cell)
94
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070095def print_cell(out, id, i, cell):
96 if not cell is None:
Winson Chung88381732013-07-12 13:41:18 -070097 out.write(cgi.escape(unicode(cell)))
Joe Onorato6f9d4bd2010-09-29 17:43:46 -070098
99FUNCTIONS = {
100 "intent": print_intent,
Winson Chung88381732013-07-12 13:41:18 -0700101 "icon": print_icon,
102 "iconType": print_icon_type
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700103}
104
Winson Chungbfc003a2011-08-24 11:32:02 -0700105def render_cell_info(out, cell, occupied):
106 if cell is None:
107 out.write(" <td width=%d height=%d></td>\n" %
108 (CELL_SIZE, CELL_SIZE))
109 elif cell == occupied:
110 pass
111 else:
112 cellX = cell["cellX"]
113 cellY = cell["cellY"]
114 spanX = cell["spanX"]
115 spanY = cell["spanY"]
116 intent = cell["intent"]
117 if intent:
118 title = "title=\"%s\"" % cgi.escape(cell["intent"], True)
119 else:
120 title = ""
121 out.write((" <td colspan=%d rowspan=%d width=%d height=%d"
122 + " bgcolor=#dddddd align=center valign=middle %s>") % (
123 spanX, spanY,
124 (CELL_SIZE*spanX), (CELL_SIZE*spanY),
125 title))
126 itemType = cell["itemType"]
127 if itemType == 0:
Winson Chung88381732013-07-12 13:41:18 -0700128 out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
Winson Chungbfc003a2011-08-24 11:32:02 -0700129 out.write("<br/>\n")
130 out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>")
131 elif itemType == 1:
Winson Chung88381732013-07-12 13:41:18 -0700132 out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
Winson Chungbfc003a2011-08-24 11:32:02 -0700133 out.write("<br/>\n")
134 out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>")
135 elif itemType == 2:
136 out.write("""<i>folder</i>""")
Winson Chungbfc003a2011-08-24 11:32:02 -0700137 elif itemType == 4:
138 out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"])
Winson Chungbfc003a2011-08-24 11:32:02 -0700139 else:
140 out.write("<b>unknown type: %d</b>" % itemType)
141 out.write("</td>\n")
142
Winson Chungd64d1762013-08-20 14:37:16 -0700143def render_screen_info(out, screen):
144 out.write("<tr>")
145 out.write("<td>%s</td>" % (screen["_id"]))
146 out.write("<td>%s</td>" % (screen["screenRank"]))
147 out.write("</tr>")
148
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700149def process_file(fn):
Winson Chung88381732013-07-12 13:41:18 -0700150 global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700151 print "process_file: " + fn
152 conn = sqlite3.connect(fn)
153 columns,rows = get_favorites(conn)
Winson Chungd64d1762013-08-20 14:37:16 -0700154 screenCols, screenRows = get_screens(conn)
Winson Chung88381732013-07-12 13:41:18 -0700155
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700156 data = [dict(zip(columns,row)) for row in rows]
Winson Chungd64d1762013-08-20 14:37:16 -0700157 screenData = [dict(zip(screenCols, screenRow)) for screenRow in screenRows]
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700158
Winson Chung88381732013-07-12 13:41:18 -0700159 # Calculate the proper number of screens, columns, and rows in this db
160 screensIdMap = []
161 hotseatIdMap = []
162 HOTSEAT_SIZE = 0
163 for d in data:
Winson Chung8481e322013-08-09 16:06:38 -0700164 if d["spanX"] is None:
165 d["spanX"] = 1
166 if d["spanY"] is None:
167 d["spanY"] = 1
Winson Chung88381732013-07-12 13:41:18 -0700168 if d["container"] == CONTAINER_DESKTOP:
169 if d["screen"] not in screensIdMap:
170 screensIdMap.append(d["screen"])
171 COLUMNS = max(COLUMNS, d["cellX"] + d["spanX"])
172 ROWS = max(ROWS, d["cellX"] + d["spanX"])
173 elif d["container"] == CONTAINER_HOTSEAT:
174 hotseatIdMap.append(d["screen"])
175 HOTSEAT_SIZE = max(HOTSEAT_SIZE, d["screen"] + 1)
176 SCREENS = len(screensIdMap)
177
178 out = codecs.open(INDEX_FILE, encoding="utf-8", mode="w")
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700179 out.write("""<html>
180<head>
181<style type="text/css">
182.intent {
183 font-style: italic;
184}
185</style>
186</head>
187<body>
188""")
189
190 # Data table
191 out.write("<b>Favorites table</b><br/>\n")
192 out.write("""<html>
193<table border=1 cellspacing=0 cellpadding=4>
194<tr>
195""")
196 print_functions = []
197 for col in columns:
198 print_functions.append(FUNCTIONS.get(col, print_cell))
199 for i in range(0,len(columns)):
200 col = columns[i]
201 out.write(""" <th>%s</th>
202""" % ( col ))
203 out.write("""
204</tr>
205""")
Winson Chung88381732013-07-12 13:41:18 -0700206
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700207 for row in rows:
208 out.write("""<tr>
209""")
210 for i in range(0,len(row)):
211 cell = row[i]
212 # row[0] is always _id
213 out.write(""" <td>""")
214 print_functions[i](out, row[0], row, cell)
215 out.write("""</td>
216""")
217 out.write("""</tr>
218""")
219 out.write("""</table>
220""")
221
Winson Chungd64d1762013-08-20 14:37:16 -0700222 # Screens
223 out.write("<br/><b>Screens</b><br/>\n")
224 out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
225 out.write("<tr><td>Screen ID</td><td>Rank</td></tr>\n")
226 for screen in screenData:
227 render_screen_info(out, screen)
228 out.write("</table>\n")
229
Winson Chungbfc003a2011-08-24 11:32:02 -0700230 # Hotseat
231 hotseat = []
232 for i in range(0, HOTSEAT_SIZE):
233 hotseat.append(None)
234 for row in data:
Winson Chung88381732013-07-12 13:41:18 -0700235 if row["container"] != CONTAINER_HOTSEAT:
Winson Chungbfc003a2011-08-24 11:32:02 -0700236 continue
237 screen = row["screen"]
238 hotseat[screen] = row
239 out.write("<br/><b>Hotseat</b><br/>\n")
240 out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
241 for cell in hotseat:
242 render_cell_info(out, cell, None)
243 out.write("</table>\n")
244
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700245 # Pages
246 screens = []
247 for i in range(0,SCREENS):
248 screen = []
249 for j in range(0,ROWS):
250 m = []
251 for k in range(0,COLUMNS):
252 m.append(None)
253 screen.append(m)
254 screens.append(screen)
255 occupied = "occupied"
256 for row in data:
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700257 # desktop
Winson Chung88381732013-07-12 13:41:18 -0700258 if row["container"] != CONTAINER_DESKTOP:
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700259 continue
Winson Chung88381732013-07-12 13:41:18 -0700260 screen = screens[screensIdMap.index(row["screen"])]
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700261 cellX = row["cellX"]
262 cellY = row["cellY"]
263 spanX = row["spanX"]
264 spanY = row["spanY"]
265 for j in range(cellY, cellY+spanY):
266 for k in range(cellX, cellX+spanX):
267 screen[j][k] = occupied
268 screen[cellY][cellX] = row
269 i=0
270 for screen in screens:
271 out.write("<br/><b>Screen %d</b><br/>\n" % i)
272 out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
273 for m in screen:
274 out.write(" <tr>\n")
275 for cell in m:
Winson Chungbfc003a2011-08-24 11:32:02 -0700276 render_cell_info(out, cell, occupied)
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700277 out.write("</tr>\n")
278 out.write("</table>\n")
279 i=i+1
280
281 out.write("""
282</body>
283</html>
284""")
285
286 out.close()
287
Winson Chung88381732013-07-12 13:41:18 -0700288def updateDeviceClassConstants(str):
289 global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
290 devClass = str.lower()
291 if devClass == "sw600":
292 COLUMNS = 6
293 ROWS = 6
294 HOTSEAT_SIZE = 6
295 return True
296 elif devClass == "sw720":
297 COLUMNS = 8
298 ROWS = 6
299 HOTSEAT_SIZE = 8
300 return True
301 return False
302
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700303def main(argv):
Winson Chung88381732013-07-12 13:41:18 -0700304 if len(argv) == 1 or (len(argv) == 2 and updateDeviceClassConstants(argv[1])):
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700305 make_dir()
Winson Chungd64d1762013-08-20 14:37:16 -0700306 adb_root_remount()
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700307 pull_file(AUTO_FILE)
308 process_file(AUTO_FILE)
Winson Chung88381732013-07-12 13:41:18 -0700309 elif len(argv) == 2 or (len(argv) == 3 and updateDeviceClassConstants(argv[2])):
Joe Onorato6f9d4bd2010-09-29 17:43:46 -0700310 make_dir()
311 process_file(argv[1])
312 else:
313 usage()
314
315if __name__=="__main__":
316 main(sys.argv)