1*9e94795aSAndroid Build Coastguard Worker#!/usr/bin/env python 2*9e94795aSAndroid Build Coastguard Worker# 3*9e94795aSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 4*9e94795aSAndroid Build Coastguard Worker# 5*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6*9e94795aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of 7*9e94795aSAndroid Build Coastguard Worker# the License at 8*9e94795aSAndroid Build Coastguard Worker# 9*9e94795aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*9e94795aSAndroid Build Coastguard Worker# 11*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13*9e94795aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14*9e94795aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under 15*9e94795aSAndroid Build Coastguard Worker# the License. 16*9e94795aSAndroid Build Coastguard Worker# 17*9e94795aSAndroid Build Coastguard Worker"""Generates dexopt files for vendor apps, from a merged target_files. 18*9e94795aSAndroid Build Coastguard Worker 19*9e94795aSAndroid Build Coastguard WorkerExpects items in OPTIONS prepared by merge_target_files.py. 20*9e94795aSAndroid Build Coastguard Worker""" 21*9e94795aSAndroid Build Coastguard Worker 22*9e94795aSAndroid Build Coastguard Workerimport glob 23*9e94795aSAndroid Build Coastguard Workerimport json 24*9e94795aSAndroid Build Coastguard Workerimport logging 25*9e94795aSAndroid Build Coastguard Workerimport os 26*9e94795aSAndroid Build Coastguard Workerimport shutil 27*9e94795aSAndroid Build Coastguard Workerimport subprocess 28*9e94795aSAndroid Build Coastguard Worker 29*9e94795aSAndroid Build Coastguard Workerimport common 30*9e94795aSAndroid Build Coastguard Workerimport merge_utils 31*9e94795aSAndroid Build Coastguard Worker 32*9e94795aSAndroid Build Coastguard Workerlogger = logging.getLogger(__name__) 33*9e94795aSAndroid Build Coastguard WorkerOPTIONS = common.OPTIONS 34*9e94795aSAndroid Build Coastguard Worker 35*9e94795aSAndroid Build Coastguard Worker 36*9e94795aSAndroid Build Coastguard Workerdef MergeDexopt(temp_dir, output_target_files_dir): 37*9e94795aSAndroid Build Coastguard Worker """If needed, generates dexopt files for vendor apps. 38*9e94795aSAndroid Build Coastguard Worker 39*9e94795aSAndroid Build Coastguard Worker Args: 40*9e94795aSAndroid Build Coastguard Worker temp_dir: Location containing an 'output' directory where target files have 41*9e94795aSAndroid Build Coastguard Worker been extracted, e.g. <temp_dir>/output/SYSTEM, <temp_dir>/output/IMAGES, 42*9e94795aSAndroid Build Coastguard Worker etc. 43*9e94795aSAndroid Build Coastguard Worker output_target_files_dir: The name of a directory that will be used to create 44*9e94795aSAndroid Build Coastguard Worker the output target files package after all the special cases are processed. 45*9e94795aSAndroid Build Coastguard Worker """ 46*9e94795aSAndroid Build Coastguard Worker # Load vendor and framework META/misc_info.txt. 47*9e94795aSAndroid Build Coastguard Worker if (OPTIONS.vendor_misc_info.get('building_with_vsdk') != 'true' or 48*9e94795aSAndroid Build Coastguard Worker OPTIONS.framework_dexpreopt_tools is None or 49*9e94795aSAndroid Build Coastguard Worker OPTIONS.framework_dexpreopt_config is None or 50*9e94795aSAndroid Build Coastguard Worker OPTIONS.vendor_dexpreopt_config is None): 51*9e94795aSAndroid Build Coastguard Worker return 52*9e94795aSAndroid Build Coastguard Worker 53*9e94795aSAndroid Build Coastguard Worker logger.info('applying dexpreopt') 54*9e94795aSAndroid Build Coastguard Worker 55*9e94795aSAndroid Build Coastguard Worker # The directory structure to apply dexpreopt is: 56*9e94795aSAndroid Build Coastguard Worker # 57*9e94795aSAndroid Build Coastguard Worker # <temp_dir>/ 58*9e94795aSAndroid Build Coastguard Worker # framework_meta/ 59*9e94795aSAndroid Build Coastguard Worker # META/ 60*9e94795aSAndroid Build Coastguard Worker # vendor_meta/ 61*9e94795aSAndroid Build Coastguard Worker # META/ 62*9e94795aSAndroid Build Coastguard Worker # output/ 63*9e94795aSAndroid Build Coastguard Worker # SYSTEM/ 64*9e94795aSAndroid Build Coastguard Worker # VENDOR/ 65*9e94795aSAndroid Build Coastguard Worker # IMAGES/ 66*9e94795aSAndroid Build Coastguard Worker # <other items extracted from system and vendor target files> 67*9e94795aSAndroid Build Coastguard Worker # tools/ 68*9e94795aSAndroid Build Coastguard Worker # <contents of dexpreopt_tools.zip> 69*9e94795aSAndroid Build Coastguard Worker # system_config/ 70*9e94795aSAndroid Build Coastguard Worker # <contents of system dexpreopt_config.zip> 71*9e94795aSAndroid Build Coastguard Worker # vendor_config/ 72*9e94795aSAndroid Build Coastguard Worker # <contents of vendor dexpreopt_config.zip> 73*9e94795aSAndroid Build Coastguard Worker # system -> output/SYSTEM 74*9e94795aSAndroid Build Coastguard Worker # vendor -> output/VENDOR 75*9e94795aSAndroid Build Coastguard Worker # apex/ (extracted updatable APEX) 76*9e94795aSAndroid Build Coastguard Worker # <apex 1>/ 77*9e94795aSAndroid Build Coastguard Worker # ... 78*9e94795aSAndroid Build Coastguard Worker # <apex 2>/ 79*9e94795aSAndroid Build Coastguard Worker # ... 80*9e94795aSAndroid Build Coastguard Worker # ... 81*9e94795aSAndroid Build Coastguard Worker # out/dex2oat_result/vendor/ 82*9e94795aSAndroid Build Coastguard Worker # <app> 83*9e94795aSAndroid Build Coastguard Worker # oat/arm64/ 84*9e94795aSAndroid Build Coastguard Worker # package.vdex 85*9e94795aSAndroid Build Coastguard Worker # package.odex 86*9e94795aSAndroid Build Coastguard Worker # <priv-app> 87*9e94795aSAndroid Build Coastguard Worker # oat/arm64/ 88*9e94795aSAndroid Build Coastguard Worker # package.vdex 89*9e94795aSAndroid Build Coastguard Worker # package.odex 90*9e94795aSAndroid Build Coastguard Worker dexpreopt_tools_files_temp_dir = os.path.join(temp_dir, 'tools') 91*9e94795aSAndroid Build Coastguard Worker dexpreopt_framework_config_files_temp_dir = os.path.join( 92*9e94795aSAndroid Build Coastguard Worker temp_dir, 'system_config') 93*9e94795aSAndroid Build Coastguard Worker dexpreopt_vendor_config_files_temp_dir = os.path.join(temp_dir, 94*9e94795aSAndroid Build Coastguard Worker 'vendor_config') 95*9e94795aSAndroid Build Coastguard Worker 96*9e94795aSAndroid Build Coastguard Worker merge_utils.ExtractItems( 97*9e94795aSAndroid Build Coastguard Worker input_zip=OPTIONS.framework_dexpreopt_tools, 98*9e94795aSAndroid Build Coastguard Worker output_dir=dexpreopt_tools_files_temp_dir, 99*9e94795aSAndroid Build Coastguard Worker extract_item_list=('*',)) 100*9e94795aSAndroid Build Coastguard Worker merge_utils.ExtractItems( 101*9e94795aSAndroid Build Coastguard Worker input_zip=OPTIONS.framework_dexpreopt_config, 102*9e94795aSAndroid Build Coastguard Worker output_dir=dexpreopt_framework_config_files_temp_dir, 103*9e94795aSAndroid Build Coastguard Worker extract_item_list=('*',)) 104*9e94795aSAndroid Build Coastguard Worker merge_utils.ExtractItems( 105*9e94795aSAndroid Build Coastguard Worker input_zip=OPTIONS.vendor_dexpreopt_config, 106*9e94795aSAndroid Build Coastguard Worker output_dir=dexpreopt_vendor_config_files_temp_dir, 107*9e94795aSAndroid Build Coastguard Worker extract_item_list=('*',)) 108*9e94795aSAndroid Build Coastguard Worker 109*9e94795aSAndroid Build Coastguard Worker os.symlink( 110*9e94795aSAndroid Build Coastguard Worker os.path.join(output_target_files_dir, 'SYSTEM'), 111*9e94795aSAndroid Build Coastguard Worker os.path.join(temp_dir, 'system')) 112*9e94795aSAndroid Build Coastguard Worker os.symlink( 113*9e94795aSAndroid Build Coastguard Worker os.path.join(output_target_files_dir, 'VENDOR'), 114*9e94795aSAndroid Build Coastguard Worker os.path.join(temp_dir, 'vendor')) 115*9e94795aSAndroid Build Coastguard Worker 116*9e94795aSAndroid Build Coastguard Worker # Extract APEX. 117*9e94795aSAndroid Build Coastguard Worker logging.info('extracting APEX') 118*9e94795aSAndroid Build Coastguard Worker apex_extract_root_dir = os.path.join(temp_dir, 'apex') 119*9e94795aSAndroid Build Coastguard Worker os.makedirs(apex_extract_root_dir) 120*9e94795aSAndroid Build Coastguard Worker 121*9e94795aSAndroid Build Coastguard Worker command = [ 122*9e94795aSAndroid Build Coastguard Worker 'apexd_host', 123*9e94795aSAndroid Build Coastguard Worker '--system_path', 124*9e94795aSAndroid Build Coastguard Worker os.path.join(temp_dir, 'system'), 125*9e94795aSAndroid Build Coastguard Worker '--apex_path', 126*9e94795aSAndroid Build Coastguard Worker apex_extract_root_dir, 127*9e94795aSAndroid Build Coastguard Worker ] 128*9e94795aSAndroid Build Coastguard Worker logging.info(' running %s', command) 129*9e94795aSAndroid Build Coastguard Worker subprocess.check_call(command) 130*9e94795aSAndroid Build Coastguard Worker 131*9e94795aSAndroid Build Coastguard Worker # Modify system config to point to the tools that have been extracted. 132*9e94795aSAndroid Build Coastguard Worker # Absolute or .. paths are not allowed by the dexpreopt_gen tool in 133*9e94795aSAndroid Build Coastguard Worker # dexpreopt_soong.config. 134*9e94795aSAndroid Build Coastguard Worker dexpreopt_framework_soon_config = os.path.join( 135*9e94795aSAndroid Build Coastguard Worker dexpreopt_framework_config_files_temp_dir, 'dexpreopt_soong.config') 136*9e94795aSAndroid Build Coastguard Worker with open(dexpreopt_framework_soon_config, 'w') as f: 137*9e94795aSAndroid Build Coastguard Worker dexpreopt_soong_config = { 138*9e94795aSAndroid Build Coastguard Worker 'Profman': 'tools/profman', 139*9e94795aSAndroid Build Coastguard Worker 'Dex2oat': 'tools/dex2oatd', 140*9e94795aSAndroid Build Coastguard Worker 'Aapt': 'tools/aapt2', 141*9e94795aSAndroid Build Coastguard Worker 'SoongZip': 'tools/soong_zip', 142*9e94795aSAndroid Build Coastguard Worker 'Zip2zip': 'tools/zip2zip', 143*9e94795aSAndroid Build Coastguard Worker 'ManifestCheck': 'tools/manifest_check', 144*9e94795aSAndroid Build Coastguard Worker 'ConstructContext': 'tools/construct_context', 145*9e94795aSAndroid Build Coastguard Worker } 146*9e94795aSAndroid Build Coastguard Worker json.dump(dexpreopt_soong_config, f) 147*9e94795aSAndroid Build Coastguard Worker 148*9e94795aSAndroid Build Coastguard Worker # TODO(b/188179859): Make *dex location configurable to vendor or system_other. 149*9e94795aSAndroid Build Coastguard Worker use_system_other_odex = False 150*9e94795aSAndroid Build Coastguard Worker 151*9e94795aSAndroid Build Coastguard Worker if use_system_other_odex: 152*9e94795aSAndroid Build Coastguard Worker dex_img = 'SYSTEM_OTHER' 153*9e94795aSAndroid Build Coastguard Worker else: 154*9e94795aSAndroid Build Coastguard Worker dex_img = 'VENDOR' 155*9e94795aSAndroid Build Coastguard Worker # Open vendor_filesystem_config to append the items generated by dexopt. 156*9e94795aSAndroid Build Coastguard Worker vendor_file_system_config = open( 157*9e94795aSAndroid Build Coastguard Worker os.path.join(temp_dir, 'output', 'META', 158*9e94795aSAndroid Build Coastguard Worker 'vendor_filesystem_config.txt'), 'a') 159*9e94795aSAndroid Build Coastguard Worker 160*9e94795aSAndroid Build Coastguard Worker # Dexpreopt vendor apps. 161*9e94795aSAndroid Build Coastguard Worker dexpreopt_config_suffix = '_dexpreopt.config' 162*9e94795aSAndroid Build Coastguard Worker for config in glob.glob( 163*9e94795aSAndroid Build Coastguard Worker os.path.join(dexpreopt_vendor_config_files_temp_dir, 164*9e94795aSAndroid Build Coastguard Worker '*' + dexpreopt_config_suffix)): 165*9e94795aSAndroid Build Coastguard Worker app = os.path.basename(config)[:-len(dexpreopt_config_suffix)] 166*9e94795aSAndroid Build Coastguard Worker logging.info('dexpreopt config: %s %s', config, app) 167*9e94795aSAndroid Build Coastguard Worker 168*9e94795aSAndroid Build Coastguard Worker apk_dir = 'app' 169*9e94795aSAndroid Build Coastguard Worker apk_path = os.path.join(temp_dir, 'vendor', apk_dir, app, app + '.apk') 170*9e94795aSAndroid Build Coastguard Worker if not os.path.exists(apk_path): 171*9e94795aSAndroid Build Coastguard Worker apk_dir = 'priv-app' 172*9e94795aSAndroid Build Coastguard Worker apk_path = os.path.join(temp_dir, 'vendor', apk_dir, app, app + '.apk') 173*9e94795aSAndroid Build Coastguard Worker if not os.path.exists(apk_path): 174*9e94795aSAndroid Build Coastguard Worker logging.warning( 175*9e94795aSAndroid Build Coastguard Worker 'skipping dexpreopt for %s, no apk found in vendor/app ' 176*9e94795aSAndroid Build Coastguard Worker 'or vendor/priv-app', app) 177*9e94795aSAndroid Build Coastguard Worker continue 178*9e94795aSAndroid Build Coastguard Worker 179*9e94795aSAndroid Build Coastguard Worker # Generate dexpreopting script. Note 'out_dir' is not the output directory 180*9e94795aSAndroid Build Coastguard Worker # where the script is generated, but the OUT_DIR at build time referenced 181*9e94795aSAndroid Build Coastguard Worker # in the dexpreot config files, e.g., "out/.../core-oj.jar", so the tool knows 182*9e94795aSAndroid Build Coastguard Worker # how to adjust the path. 183*9e94795aSAndroid Build Coastguard Worker command = [ 184*9e94795aSAndroid Build Coastguard Worker os.path.join(dexpreopt_tools_files_temp_dir, 'dexpreopt_gen'), 185*9e94795aSAndroid Build Coastguard Worker '-global', 186*9e94795aSAndroid Build Coastguard Worker os.path.join(dexpreopt_framework_config_files_temp_dir, 187*9e94795aSAndroid Build Coastguard Worker 'dexpreopt.config'), 188*9e94795aSAndroid Build Coastguard Worker '-global_soong', 189*9e94795aSAndroid Build Coastguard Worker os.path.join(dexpreopt_framework_config_files_temp_dir, 190*9e94795aSAndroid Build Coastguard Worker 'dexpreopt_soong.config'), 191*9e94795aSAndroid Build Coastguard Worker '-module', 192*9e94795aSAndroid Build Coastguard Worker config, 193*9e94795aSAndroid Build Coastguard Worker '-dexpreopt_script', 194*9e94795aSAndroid Build Coastguard Worker 'dexpreopt_app.sh', 195*9e94795aSAndroid Build Coastguard Worker '-out_dir', 196*9e94795aSAndroid Build Coastguard Worker 'out', 197*9e94795aSAndroid Build Coastguard Worker '-base_path', 198*9e94795aSAndroid Build Coastguard Worker '.', 199*9e94795aSAndroid Build Coastguard Worker '--uses_target_files', 200*9e94795aSAndroid Build Coastguard Worker ] 201*9e94795aSAndroid Build Coastguard Worker 202*9e94795aSAndroid Build Coastguard Worker # Run the command from temp_dir so all tool paths are its descendants. 203*9e94795aSAndroid Build Coastguard Worker logging.info('running %s', command) 204*9e94795aSAndroid Build Coastguard Worker subprocess.check_call(command, cwd=temp_dir) 205*9e94795aSAndroid Build Coastguard Worker 206*9e94795aSAndroid Build Coastguard Worker # Call the generated script. 207*9e94795aSAndroid Build Coastguard Worker command = ['sh', 'dexpreopt_app.sh', apk_path] 208*9e94795aSAndroid Build Coastguard Worker logging.info('running %s', command) 209*9e94795aSAndroid Build Coastguard Worker subprocess.check_call(command, cwd=temp_dir) 210*9e94795aSAndroid Build Coastguard Worker 211*9e94795aSAndroid Build Coastguard Worker # Output files are in: 212*9e94795aSAndroid Build Coastguard Worker # 213*9e94795aSAndroid Build Coastguard Worker # <temp_dir>/out/dex2oat_result/vendor/priv-app/<app>/oat/arm64/package.vdex 214*9e94795aSAndroid Build Coastguard Worker # <temp_dir>/out/dex2oat_result/vendor/priv-app/<app>/oat/arm64/package.odex 215*9e94795aSAndroid Build Coastguard Worker # <temp_dir>/out/dex2oat_result/vendor/app/<app>/oat/arm64/package.vdex 216*9e94795aSAndroid Build Coastguard Worker # <temp_dir>/out/dex2oat_result/vendor/app/<app>/oat/arm64/package.odex 217*9e94795aSAndroid Build Coastguard Worker # 218*9e94795aSAndroid Build Coastguard Worker # Copy the files to their destination. The structure of system_other is: 219*9e94795aSAndroid Build Coastguard Worker # 220*9e94795aSAndroid Build Coastguard Worker # system_other/ 221*9e94795aSAndroid Build Coastguard Worker # system-other-odex-marker 222*9e94795aSAndroid Build Coastguard Worker # system/ 223*9e94795aSAndroid Build Coastguard Worker # app/ 224*9e94795aSAndroid Build Coastguard Worker # <app>/oat/arm64/ 225*9e94795aSAndroid Build Coastguard Worker # <app>.odex 226*9e94795aSAndroid Build Coastguard Worker # <app>.vdex 227*9e94795aSAndroid Build Coastguard Worker # ... 228*9e94795aSAndroid Build Coastguard Worker # priv-app/ 229*9e94795aSAndroid Build Coastguard Worker # <app>/oat/arm64/ 230*9e94795aSAndroid Build Coastguard Worker # <app>.odex 231*9e94795aSAndroid Build Coastguard Worker # <app>.vdex 232*9e94795aSAndroid Build Coastguard Worker # ... 233*9e94795aSAndroid Build Coastguard Worker 234*9e94795aSAndroid Build Coastguard Worker # TODO(b/188179859): Support for other architectures. 235*9e94795aSAndroid Build Coastguard Worker arch = 'arm64' 236*9e94795aSAndroid Build Coastguard Worker 237*9e94795aSAndroid Build Coastguard Worker dex_destination = os.path.join(temp_dir, 'output', dex_img, apk_dir, app, 238*9e94795aSAndroid Build Coastguard Worker 'oat', arch) 239*9e94795aSAndroid Build Coastguard Worker os.makedirs(dex_destination) 240*9e94795aSAndroid Build Coastguard Worker dex2oat_path = os.path.join(temp_dir, 'out', 'dex2oat_result', 'vendor', 241*9e94795aSAndroid Build Coastguard Worker apk_dir, app, 'oat', arch) 242*9e94795aSAndroid Build Coastguard Worker shutil.copy( 243*9e94795aSAndroid Build Coastguard Worker os.path.join(dex2oat_path, 'package.vdex'), 244*9e94795aSAndroid Build Coastguard Worker os.path.join(dex_destination, app + '.vdex')) 245*9e94795aSAndroid Build Coastguard Worker shutil.copy( 246*9e94795aSAndroid Build Coastguard Worker os.path.join(dex2oat_path, 'package.odex'), 247*9e94795aSAndroid Build Coastguard Worker os.path.join(dex_destination, app + '.odex')) 248*9e94795aSAndroid Build Coastguard Worker 249*9e94795aSAndroid Build Coastguard Worker # Append entries to vendor_file_system_config.txt, such as: 250*9e94795aSAndroid Build Coastguard Worker # 251*9e94795aSAndroid Build Coastguard Worker # vendor/app/<app>/oat 0 2000 755 selabel=u:object_r:vendor_app_file:s0 capabilities=0x0 252*9e94795aSAndroid Build Coastguard Worker # vendor/app/<app>/oat/arm64 0 2000 755 selabel=u:object_r:vendor_app_file:s0 capabilities=0x0 253*9e94795aSAndroid Build Coastguard Worker # vendor/app/<app>/oat/arm64/<app>.odex 0 0 644 selabel=u:object_r:vendor_app_file:s0 capabilities=0x0 254*9e94795aSAndroid Build Coastguard Worker # vendor/app/<app>/oat/arm64/<app>.vdex 0 0 644 selabel=u:object_r:vendor_app_file:s0 capabilities=0x0 255*9e94795aSAndroid Build Coastguard Worker if not use_system_other_odex: 256*9e94795aSAndroid Build Coastguard Worker vendor_app_prefix = 'vendor/' + apk_dir + '/' + app + '/oat' 257*9e94795aSAndroid Build Coastguard Worker selabel = 'selabel=u:object_r:vendor_app_file:s0 capabilities=0x0' 258*9e94795aSAndroid Build Coastguard Worker vendor_file_system_config.writelines([ 259*9e94795aSAndroid Build Coastguard Worker vendor_app_prefix + ' 0 2000 755 ' + selabel + '\n', 260*9e94795aSAndroid Build Coastguard Worker vendor_app_prefix + '/' + arch + ' 0 2000 755 ' + selabel + '\n', 261*9e94795aSAndroid Build Coastguard Worker vendor_app_prefix + '/' + arch + '/' + app + '.odex 0 0 644 ' + 262*9e94795aSAndroid Build Coastguard Worker selabel + '\n', 263*9e94795aSAndroid Build Coastguard Worker vendor_app_prefix + '/' + arch + '/' + app + '.vdex 0 0 644 ' + 264*9e94795aSAndroid Build Coastguard Worker selabel + '\n', 265*9e94795aSAndroid Build Coastguard Worker ]) 266*9e94795aSAndroid Build Coastguard Worker 267*9e94795aSAndroid Build Coastguard Worker if not use_system_other_odex: 268*9e94795aSAndroid Build Coastguard Worker vendor_file_system_config.close() 269*9e94795aSAndroid Build Coastguard Worker # Delete vendor.img so that it will be regenerated. 270*9e94795aSAndroid Build Coastguard Worker # TODO(b/188179859): Rebuilding a vendor image in GRF mode (e.g., T(framework) 271*9e94795aSAndroid Build Coastguard Worker # and S(vendor) may require logic similar to that in 272*9e94795aSAndroid Build Coastguard Worker # rebuild_image_with_sepolicy. 273*9e94795aSAndroid Build Coastguard Worker vendor_img = os.path.join(output_target_files_dir, 'IMAGES', 'vendor.img') 274*9e94795aSAndroid Build Coastguard Worker if os.path.exists(vendor_img): 275*9e94795aSAndroid Build Coastguard Worker logging.info('Deleting %s', vendor_img) 276*9e94795aSAndroid Build Coastguard Worker os.remove(vendor_img) 277