1# Copyright 2013 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"""Signs and aligns an APK."""
5
6import argparse
7import logging
8import shutil
9import subprocess
10import sys
11import tempfile
12
13from util import build_utils
14
15
16def FinalizeApk(apksigner_path,
17                zipalign_path,
18                unsigned_apk_path,
19                final_apk_path,
20                key_path,
21                key_passwd,
22                key_name,
23                min_sdk_version,
24                warnings_as_errors=False):
25  # Use a tempfile so that Ctrl-C does not leave the file with a fresh mtime
26  # and a corrupted state.
27  with tempfile.NamedTemporaryFile() as staging_file:
28    if zipalign_path:
29      # v2 signing requires that zipalign happen first.
30      logging.debug('Running zipalign')
31      zipalign_cmd = [
32          zipalign_path, '-p', '-f', '4', unsigned_apk_path, staging_file.name
33      ]
34      build_utils.CheckOutput(zipalign_cmd,
35                              print_stdout=True,
36                              fail_on_output=warnings_as_errors)
37      signer_input_path = staging_file.name
38    else:
39      signer_input_path = unsigned_apk_path
40
41    sign_cmd = build_utils.JavaCmd(warnings_as_errors) + [
42        '-jar',
43        apksigner_path,
44        'sign',
45        '--in',
46        signer_input_path,
47        '--out',
48        staging_file.name,
49        '--ks',
50        key_path,
51        '--ks-key-alias',
52        key_name,
53        '--ks-pass',
54        'pass:' + key_passwd,
55    ]
56    # V3 signing adds security niceties, which are irrelevant for local builds.
57    sign_cmd += ['--v3-signing-enabled', 'false']
58
59    if min_sdk_version >= 24:
60      # Disable v1 signatures when v2 signing can be used (it's much faster).
61      # By default, both v1 and v2 signing happen.
62      sign_cmd += ['--v1-signing-enabled', 'false']
63    else:
64      # Force SHA-1 (makes signing faster; insecure is fine for local builds).
65      # Leave v2 signing enabled since it verifies faster on device when
66      # supported.
67      sign_cmd += ['--min-sdk-version', '1']
68
69    logging.debug('Signing apk')
70    build_utils.CheckOutput(sign_cmd,
71                            print_stdout=True,
72                            fail_on_output=warnings_as_errors)
73    shutil.move(staging_file.name, final_apk_path)
74    # TODO(crbug.com/1174969): Remove this once Python2 is obsoleted.
75    if sys.version_info.major == 2:
76      staging_file.delete = False
77    else:
78      staging_file._closer.delete = False
79