3 # Copyright 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
16 from util
import build_device
17 from util
import build_utils
18 from util
import md5_check
20 BUILD_ANDROID_DIR
= os
.path
.join(os
.path
.dirname(__file__
), '..')
21 sys
.path
.append(BUILD_ANDROID_DIR
)
23 from pylib
import constants
24 from pylib
.utils
import apk_helper
27 def GetNewMetadata(device
, apk_package
):
28 """Gets the metadata on the device for the apk_package apk."""
29 output
= device
.RunShellCommand('ls -l /data/app/')
31 # -rw-r--r-- system system 7376582 2013-04-19 16:34 \
32 # org.chromium.chrome.shell.apk
33 # -rw-r--r-- system system 7376582 2013-04-19 16:34 \
34 # org.chromium.chrome.shell-1.apk
35 apk_matcher
= lambda s
: re
.match('.*%s(-[0-9]*)?(.apk)?$' % apk_package
, s
)
36 matches
= filter(apk_matcher
, output
)
37 return matches
[0] if matches
else None
39 def HasInstallMetadataChanged(device
, apk_package
, metadata_path
):
40 """Checks if the metadata on the device for apk_package has changed."""
41 if not os
.path
.exists(metadata_path
):
44 with
open(metadata_path
, 'r') as expected_file
:
45 return expected_file
.read() != device
.GetInstallMetadata(apk_package
)
48 def RecordInstallMetadata(device
, apk_package
, metadata_path
):
49 """Records the metadata from the device for apk_package."""
50 metadata
= GetNewMetadata(device
, apk_package
)
52 raise Exception('APK install failed unexpectedly.')
54 with
open(metadata_path
, 'w') as outfile
:
55 outfile
.write(metadata
)
59 parser
= optparse
.OptionParser()
60 parser
.add_option('--apk-path',
61 help='Path to .apk to install.')
62 parser
.add_option('--split-apk-path',
63 help='Path to .apk splits (can specify multiple times, causes '
64 '--install-multiple to be used.',
66 parser
.add_option('--android-sdk-tools',
67 help='Path to the Android SDK build tools folder. ' +
68 'Required when using --split-apk-path.')
69 parser
.add_option('--install-record',
70 help='Path to install record (touched only when APK is installed).')
71 parser
.add_option('--build-device-configuration',
72 help='Path to build device configuration.')
73 parser
.add_option('--stamp',
74 help='Path to touch on success.')
75 parser
.add_option('--configuration-name',
76 help='The build CONFIGURATION_NAME')
77 options
, _
= parser
.parse_args()
79 device
= build_device
.GetBuildDeviceFromPath(
80 options
.build_device_configuration
)
84 constants
.SetBuildType(options
.configuration_name
)
86 serial_number
= device
.GetSerialNumber()
87 apk_package
= apk_helper
.GetPackageName(options
.apk_path
)
89 metadata_path
= '%s.%s.device.time.stamp' % (options
.apk_path
, serial_number
)
91 # If the APK on the device does not match the one that was last installed by
92 # the build, then the APK has to be installed (regardless of the md5 record).
93 force_install
= HasInstallMetadataChanged(device
, apk_package
, metadata_path
)
97 if options
.split_apk_path
:
98 device
.InstallSplitApk(options
.apk_path
, options
.split_apk_path
)
100 device
.Install(options
.apk_path
, reinstall
=True)
102 RecordInstallMetadata(device
, apk_package
, metadata_path
)
103 build_utils
.Touch(options
.install_record
)
106 record_path
= '%s.%s.md5.stamp' % (options
.apk_path
, serial_number
)
107 md5_check
.CallAndRecordIfStale(
109 record_path
=record_path
,
110 input_paths
=[options
.apk_path
],
114 build_utils
.Touch(options
.stamp
)
117 if __name__
== '__main__':