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