xref: /aosp_15_r20/build/make/tools/releasetools/merge/merge_dexopt.py (revision 9e94795a3d4ef5c1d47486f9a02bb378756cea8a)
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