xref: /aosp_15_r20/external/chromium-trace/catapult/devil/devil/android/sdk/bundletool.py (revision 1fa4b3da657c0e9ad43c0220bacf9731820715a5)
1# Copyright 2019 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""This module wraps bundletool."""
5
6import json
7
8from devil import base_error
9from devil import devil_env
10from devil.utils import cmd_helper
11from devil.utils import lazy
12
13with devil_env.SysPath(devil_env.PY_UTILS_PATH):
14  from py_utils import tempfile_ext
15
16_bundletool_path = lazy.WeakConstant(lambda: devil_env.config.FetchPath(
17    'bundletool'))
18
19
20def ExtractApks(output_dir,
21                apks_path,
22                abis,
23                locales,
24                features,
25                pixel_density,
26                sdk_version,
27                modules=None):
28  """Extracts splits from APKS archive.
29
30  Args:
31    output_dir: Directory to extract splits into.
32    apks_path: Path to APKS archive.
33    abis: ABIs to support.
34    locales: Locales to support.
35    features: Device features to support.
36    pixel_density: Pixel density to support.
37    sdk_version: Target SDK version.
38    modules: Extra modules to install.
39  """
40  device_spec = {
41      'supportedAbis': abis,
42      'supportedLocales': ['%s-%s' % l for l in locales],
43      'deviceFeatures': features,
44      'screenDensity': pixel_density,
45      'sdkVersion': sdk_version,
46  }
47  with tempfile_ext.TemporaryFileName(suffix='.json') as device_spec_path:
48    with open(device_spec_path, 'w') as f:
49      json.dump(device_spec, f)
50    cmd = [
51        'java',
52        '-jar',
53        _bundletool_path.read(),
54        'extract-apks',
55        '--apks=%s' % apks_path,
56        '--device-spec=%s' % device_spec_path,
57        '--output-dir=%s' % output_dir,
58    ]
59    if modules:
60      cmd += ['--modules=%s' % ','.join(modules)]
61    status, stdout, stderr = cmd_helper.GetCmdStatusOutputAndError(cmd)
62    if status != 0:
63      raise base_error.BaseError('Failed running {} with output\n{}\n{}'.format(
64          ' '.join(cmd), stdout, stderr))
65