xref: /aosp_15_r20/external/perfetto/python/tools/update_permalink.py (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6dbdd20aSAndroid Build Coastguard Worker
3*6dbdd20aSAndroid Build Coastguard Workerimport sys
4*6dbdd20aSAndroid Build Coastguard Workerimport argparse
5*6dbdd20aSAndroid Build Coastguard Workerimport urllib
6*6dbdd20aSAndroid Build Coastguard Workerimport json
7*6dbdd20aSAndroid Build Coastguard Workerimport urllib.request
8*6dbdd20aSAndroid Build Coastguard Workerimport urllib.parse
9*6dbdd20aSAndroid Build Coastguard Workerimport ssl
10*6dbdd20aSAndroid Build Coastguard Workerimport hashlib
11*6dbdd20aSAndroid Build Coastguard Workerimport copy
12*6dbdd20aSAndroid Build Coastguard Worker
13*6dbdd20aSAndroid Build Coastguard WorkerBUCKET_NAME = "perfetto-ui-data"
14*6dbdd20aSAndroid Build Coastguard WorkerCURRENT_STATE_VERSION = 28
15*6dbdd20aSAndroid Build Coastguard Worker
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_15(old):
18*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
19*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 16
20*6dbdd20aSAndroid Build Coastguard Worker  new["flamegraphModalDismissed"] = False
21*6dbdd20aSAndroid Build Coastguard Worker  return new
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard Worker
24*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_16(old):
25*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
26*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 17
27*6dbdd20aSAndroid Build Coastguard Worker  new["nextId"] = max(old["nextId"], old["nextNoteId"], old["nextAreaId"])
28*6dbdd20aSAndroid Build Coastguard Worker  engines = old["engines"]
29*6dbdd20aSAndroid Build Coastguard Worker  if len(engines) > 0:
30*6dbdd20aSAndroid Build Coastguard Worker    new["currentEngineId"] = list(engines.values())[0]['id']
31*6dbdd20aSAndroid Build Coastguard Worker  return new
32*6dbdd20aSAndroid Build Coastguard Worker
33*6dbdd20aSAndroid Build Coastguard Worker
34*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_17(old):
35*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
36*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 18
37*6dbdd20aSAndroid Build Coastguard Worker  # TODO(hjd): Update
38*6dbdd20aSAndroid Build Coastguard Worker  return new
39*6dbdd20aSAndroid Build Coastguard Worker
40*6dbdd20aSAndroid Build Coastguard Worker
41*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_18(old):
42*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
43*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 19
44*6dbdd20aSAndroid Build Coastguard Worker  # TODO(hjd): Update
45*6dbdd20aSAndroid Build Coastguard Worker  return new
46*6dbdd20aSAndroid Build Coastguard Worker
47*6dbdd20aSAndroid Build Coastguard Worker
48*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_19(old):
49*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
50*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 20
51*6dbdd20aSAndroid Build Coastguard Worker  # TODO(hjd): Update
52*6dbdd20aSAndroid Build Coastguard Worker  return new
53*6dbdd20aSAndroid Build Coastguard Worker
54*6dbdd20aSAndroid Build Coastguard Worker
55*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_20(old):
56*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
57*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 21
58*6dbdd20aSAndroid Build Coastguard Worker  # TODO(hjd): Update
59*6dbdd20aSAndroid Build Coastguard Worker  return new
60*6dbdd20aSAndroid Build Coastguard Worker
61*6dbdd20aSAndroid Build Coastguard Worker
62*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_20(old):
63*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
64*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 22
65*6dbdd20aSAndroid Build Coastguard Worker  # TODO(hjd): Update
66*6dbdd20aSAndroid Build Coastguard Worker  return new
67*6dbdd20aSAndroid Build Coastguard Worker
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_21(old):
70*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
71*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 22
72*6dbdd20aSAndroid Build Coastguard Worker  # TODO(hjd): Update
73*6dbdd20aSAndroid Build Coastguard Worker  return new
74*6dbdd20aSAndroid Build Coastguard Worker
75*6dbdd20aSAndroid Build Coastguard Worker
76*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_22(old):
77*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
78*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 23
79*6dbdd20aSAndroid Build Coastguard Worker  new["logFilteringCriteria"] = {
80*6dbdd20aSAndroid Build Coastguard Worker      "minimumLevel": 2,
81*6dbdd20aSAndroid Build Coastguard Worker  }
82*6dbdd20aSAndroid Build Coastguard Worker  return new
83*6dbdd20aSAndroid Build Coastguard Worker
84*6dbdd20aSAndroid Build Coastguard Worker
85*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_23(old):
86*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
87*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 24
88*6dbdd20aSAndroid Build Coastguard Worker  current_engine_id = new["currentEngineId"]
89*6dbdd20aSAndroid Build Coastguard Worker  new["engine"] = new["engines"][
90*6dbdd20aSAndroid Build Coastguard Worker      current_engine_id] if current_engine_id else None
91*6dbdd20aSAndroid Build Coastguard Worker  del new["currentEngineId"]
92*6dbdd20aSAndroid Build Coastguard Worker  del new["engines"]
93*6dbdd20aSAndroid Build Coastguard Worker  return new
94*6dbdd20aSAndroid Build Coastguard Worker
95*6dbdd20aSAndroid Build Coastguard Worker
96*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_24(old):
97*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
98*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 25
99*6dbdd20aSAndroid Build Coastguard Worker  new["omniboxState"] = new["frontendLocalState"]["omniboxState"]
100*6dbdd20aSAndroid Build Coastguard Worker  del new["frontendLocalState"]["omniboxState"]
101*6dbdd20aSAndroid Build Coastguard Worker  return new
102*6dbdd20aSAndroid Build Coastguard Worker
103*6dbdd20aSAndroid Build Coastguard Worker
104*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_25(old):
105*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
106*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 26
107*6dbdd20aSAndroid Build Coastguard Worker  new["logFilteringCriteria"]["tags"] = []
108*6dbdd20aSAndroid Build Coastguard Worker  return new
109*6dbdd20aSAndroid Build Coastguard Worker
110*6dbdd20aSAndroid Build Coastguard Worker
111*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_26(old):
112*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
113*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 27
114*6dbdd20aSAndroid Build Coastguard Worker  new["logFilteringCriteria"]["textEntry"] = ""
115*6dbdd20aSAndroid Build Coastguard Worker  return new
116*6dbdd20aSAndroid Build Coastguard Worker
117*6dbdd20aSAndroid Build Coastguard Worker
118*6dbdd20aSAndroid Build Coastguard Workerdef upgrade_27(old):
119*6dbdd20aSAndroid Build Coastguard Worker  new = copy.deepcopy(old)
120*6dbdd20aSAndroid Build Coastguard Worker  new["version"] = 28
121*6dbdd20aSAndroid Build Coastguard Worker  new["logFilteringCriteria"]["hideNonMatching"] = False
122*6dbdd20aSAndroid Build Coastguard Worker  return new
123*6dbdd20aSAndroid Build Coastguard Worker
124*6dbdd20aSAndroid Build Coastguard Worker
125*6dbdd20aSAndroid Build Coastguard Workerdef bug_compatible_hash_mangling(hash):
126*6dbdd20aSAndroid Build Coastguard Worker  pairs = [hash[i:i + 2] for i in range(0, len(hash), 2)]
127*6dbdd20aSAndroid Build Coastguard Worker  return ''.join([pair.removeprefix("0") for pair in pairs])
128*6dbdd20aSAndroid Build Coastguard Worker
129*6dbdd20aSAndroid Build Coastguard Worker
130*6dbdd20aSAndroid Build Coastguard Workerdef upload_state(state):
131*6dbdd20aSAndroid Build Coastguard Worker  data = state.encode("utf-8")
132*6dbdd20aSAndroid Build Coastguard Worker  hash = bug_compatible_hash_mangling(hashlib.sha256(data).hexdigest())
133*6dbdd20aSAndroid Build Coastguard Worker
134*6dbdd20aSAndroid Build Coastguard Worker  try:
135*6dbdd20aSAndroid Build Coastguard Worker    get(make_state_url(hash))
136*6dbdd20aSAndroid Build Coastguard Worker  except:
137*6dbdd20aSAndroid Build Coastguard Worker    pass
138*6dbdd20aSAndroid Build Coastguard Worker  else:
139*6dbdd20aSAndroid Build Coastguard Worker    return hash
140*6dbdd20aSAndroid Build Coastguard Worker
141*6dbdd20aSAndroid Build Coastguard Worker  url = f"https://www.googleapis.com/upload/storage/v1/b/{BUCKET_NAME}/o?uploadType=media&name={hash}&predefinedAcl=publicRead"
142*6dbdd20aSAndroid Build Coastguard Worker  request = urllib.request.Request(url, data=data)
143*6dbdd20aSAndroid Build Coastguard Worker  request.add_header("Content-Type", "application/json; charset=utf-8")
144*6dbdd20aSAndroid Build Coastguard Worker  response = urllib.request.urlopen(request)
145*6dbdd20aSAndroid Build Coastguard Worker  return hash
146*6dbdd20aSAndroid Build Coastguard Worker
147*6dbdd20aSAndroid Build Coastguard Worker
148*6dbdd20aSAndroid Build Coastguard Workerdef make_state_url(id):
149*6dbdd20aSAndroid Build Coastguard Worker  return f"https://storage.googleapis.com/{BUCKET_NAME}/{id}"
150*6dbdd20aSAndroid Build Coastguard Worker
151*6dbdd20aSAndroid Build Coastguard Worker
152*6dbdd20aSAndroid Build Coastguard Workerdef make_ui_url(id):
153*6dbdd20aSAndroid Build Coastguard Worker  return f"https://ui.perfetto.dev/#!/?s={id}"
154*6dbdd20aSAndroid Build Coastguard Worker
155*6dbdd20aSAndroid Build Coastguard Worker
156*6dbdd20aSAndroid Build Coastguard Workerdef extract_state_uuid(url):
157*6dbdd20aSAndroid Build Coastguard Worker  fragment = urllib.parse.urlparse(url).fragment
158*6dbdd20aSAndroid Build Coastguard Worker  fragment = fragment.removeprefix("!/?")
159*6dbdd20aSAndroid Build Coastguard Worker  return urllib.parse.parse_qs(fragment)["s"][0]
160*6dbdd20aSAndroid Build Coastguard Worker
161*6dbdd20aSAndroid Build Coastguard Worker
162*6dbdd20aSAndroid Build Coastguard Workerdef get(url):
163*6dbdd20aSAndroid Build Coastguard Worker  context = ssl._create_unverified_context()
164*6dbdd20aSAndroid Build Coastguard Worker  response = urllib.request.urlopen(url, context=context)
165*6dbdd20aSAndroid Build Coastguard Worker  contents = response.read().decode()
166*6dbdd20aSAndroid Build Coastguard Worker  return contents
167*6dbdd20aSAndroid Build Coastguard Worker
168*6dbdd20aSAndroid Build Coastguard Worker
169*6dbdd20aSAndroid Build Coastguard Workerdef post(url):
170*6dbdd20aSAndroid Build Coastguard Worker  context = ssl._create_unverified_context()
171*6dbdd20aSAndroid Build Coastguard Worker  response = urllib.request.urlopen(url, context=context)
172*6dbdd20aSAndroid Build Coastguard Worker  contents = response.read().decode()
173*6dbdd20aSAndroid Build Coastguard Worker  return contents
174*6dbdd20aSAndroid Build Coastguard Worker
175*6dbdd20aSAndroid Build Coastguard Worker
176*6dbdd20aSAndroid Build Coastguard Workerdef main():
177*6dbdd20aSAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
178*6dbdd20aSAndroid Build Coastguard Worker  parser.add_argument("permalink", help="Permalink you wish to update")
179*6dbdd20aSAndroid Build Coastguard Worker  parser.add_argument(
180*6dbdd20aSAndroid Build Coastguard Worker      "--target-version",
181*6dbdd20aSAndroid Build Coastguard Worker      help=f"Target state version (default: {CURRENT_STATE_VERSION})",
182*6dbdd20aSAndroid Build Coastguard Worker      default=CURRENT_STATE_VERSION)
183*6dbdd20aSAndroid Build Coastguard Worker  parser.add_argument(
184*6dbdd20aSAndroid Build Coastguard Worker      "--verbose", help=f"Show debug information", action="store_true")
185*6dbdd20aSAndroid Build Coastguard Worker  args = parser.parse_args()
186*6dbdd20aSAndroid Build Coastguard Worker
187*6dbdd20aSAndroid Build Coastguard Worker  permalink_url = args.permalink
188*6dbdd20aSAndroid Build Coastguard Worker  old_uuid = extract_state_uuid(permalink_url)
189*6dbdd20aSAndroid Build Coastguard Worker  old_state_url = make_state_url(old_uuid)
190*6dbdd20aSAndroid Build Coastguard Worker  old_state = get(old_state_url)
191*6dbdd20aSAndroid Build Coastguard Worker  old_json = json.loads(old_state)
192*6dbdd20aSAndroid Build Coastguard Worker
193*6dbdd20aSAndroid Build Coastguard Worker  old_state_version = old_json["version"]
194*6dbdd20aSAndroid Build Coastguard Worker  new_state_version = args.target_version
195*6dbdd20aSAndroid Build Coastguard Worker
196*6dbdd20aSAndroid Build Coastguard Worker  print(json.dumps(old_json, sort_keys=True, indent=4))
197*6dbdd20aSAndroid Build Coastguard Worker
198*6dbdd20aSAndroid Build Coastguard Worker  UPGRADE = {
199*6dbdd20aSAndroid Build Coastguard Worker      15: upgrade_15,
200*6dbdd20aSAndroid Build Coastguard Worker      16: upgrade_16,
201*6dbdd20aSAndroid Build Coastguard Worker      17: upgrade_17,
202*6dbdd20aSAndroid Build Coastguard Worker      18: upgrade_18,
203*6dbdd20aSAndroid Build Coastguard Worker      19: upgrade_19,
204*6dbdd20aSAndroid Build Coastguard Worker      20: upgrade_20,
205*6dbdd20aSAndroid Build Coastguard Worker      21: upgrade_21,
206*6dbdd20aSAndroid Build Coastguard Worker      22: upgrade_22,
207*6dbdd20aSAndroid Build Coastguard Worker      23: upgrade_23,
208*6dbdd20aSAndroid Build Coastguard Worker      24: upgrade_24,
209*6dbdd20aSAndroid Build Coastguard Worker      25: upgrade_25,
210*6dbdd20aSAndroid Build Coastguard Worker      26: upgrade_26,
211*6dbdd20aSAndroid Build Coastguard Worker      27: upgrade_27,
212*6dbdd20aSAndroid Build Coastguard Worker  }
213*6dbdd20aSAndroid Build Coastguard Worker
214*6dbdd20aSAndroid Build Coastguard Worker  new_json = old_json
215*6dbdd20aSAndroid Build Coastguard Worker  for i in range(old_state_version, new_state_version):
216*6dbdd20aSAndroid Build Coastguard Worker    new_json = UPGRADE[i](new_json)
217*6dbdd20aSAndroid Build Coastguard Worker
218*6dbdd20aSAndroid Build Coastguard Worker  new_state = json.dumps(new_json)
219*6dbdd20aSAndroid Build Coastguard Worker  new_uuid = upload_state(new_state)
220*6dbdd20aSAndroid Build Coastguard Worker  new_url = make_ui_url(new_uuid)
221*6dbdd20aSAndroid Build Coastguard Worker  print(f"Your new permalink is accessible at:")
222*6dbdd20aSAndroid Build Coastguard Worker  print(f"{new_url}")
223*6dbdd20aSAndroid Build Coastguard Worker  return 0
224*6dbdd20aSAndroid Build Coastguard Worker
225*6dbdd20aSAndroid Build Coastguard Worker
226*6dbdd20aSAndroid Build Coastguard Workerif __name__ == "__main__":
227*6dbdd20aSAndroid Build Coastguard Worker  sys.exit(main())
228