summaryrefslogtreecommitdiffstats
path: root/tools/releasetools/common.py
diff options
context:
space:
mode:
authorDoug Zongker <dougz@android.com>2009-06-22 11:32:31 -0700
committerDoug Zongker <dougz@android.com>2009-06-22 15:09:22 -0700
commit05d3dea519688b61d86e30c2d4b99ff494aeca73 (patch)
tree40fb8d5af9ffcd6739bd3e8ebbbaa621f1738269 /tools/releasetools/common.py
parent09e82c0d93b557256dcde07c5ca5cfeb07af9d03 (diff)
downloadbuild-05d3dea519688b61d86e30c2d4b99ff494aeca73.zip
build-05d3dea519688b61d86e30c2d4b99ff494aeca73.tar.gz
build-05d3dea519688b61d86e30c2d4b99ff494aeca73.tar.bz2
support hooks for device-specific code in OTA package generation
Replace the installation of the "radio image", which is an HTC-specific notion, with calls to device-specific python modules that can add whatever additional OTA script commands are necessary. Add the -s flag to specify the location of the device-specific script (replacing the unused -s flag in sign_target_files_apks).
Diffstat (limited to 'tools/releasetools/common.py')
-rw-r--r--tools/releasetools/common.py78
1 files changed, 75 insertions, 3 deletions
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 0b3803f..9ba85c6 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -15,6 +15,7 @@
import errno
import getopt
import getpass
+import imp
import os
import re
import shutil
@@ -33,7 +34,7 @@ OPTIONS.search_path = "out/host/linux-x86"
OPTIONS.max_image_size = {}
OPTIONS.verbose = False
OPTIONS.tempfiles = []
-
+OPTIONS.device_specific = None
class ExternalError(RuntimeError): pass
@@ -233,6 +234,10 @@ COMMON_DOCSTRING = """
Prepend <dir>/bin to the list of places to search for binaries
run by this script, and expect to find jars in <dir>/framework.
+ -s (--device_specific) <file>
+ Path to the python module containing device-specific
+ releasetools code.
+
-v (--verbose)
Show command lines being executed.
@@ -257,8 +262,9 @@ def ParseOptions(argv,
try:
opts, args = getopt.getopt(
- argv, "hvp:" + extra_opts,
- ["help", "verbose", "path="] + list(extra_long_opts))
+ argv, "hvp:s:" + extra_opts,
+ ["help", "verbose", "path=", "device_specific="] +
+ list(extra_long_opts))
except getopt.GetoptError, err:
Usage(docstring)
print "**", str(err), "**"
@@ -274,6 +280,8 @@ def ParseOptions(argv,
OPTIONS.verbose = True
elif o in ("-p", "--path"):
OPTIONS.search_path = a
+ elif o in ("-s", "--device_specific"):
+ OPTIONS.device_specific = a
else:
if extra_option_handler is None or not extra_option_handler(o, a):
assert False, "unknown option \"%s\"" % (o,)
@@ -398,3 +406,67 @@ def ZipWriteStr(zip, filename, data, perms=0644):
zinfo.compress_type = zip.compression
zinfo.external_attr = perms << 16
zip.writestr(zinfo, data)
+
+
+class DeviceSpecificParams(object):
+ module = None
+ def __init__(self, **kwargs):
+ """Keyword arguments to the constructor become attributes of this
+ object, which is passed to all functions in the device-specific
+ module."""
+ for k, v in kwargs.iteritems():
+ setattr(self, k, v)
+
+ if self.module is None:
+ path = OPTIONS.device_specific
+ if path is None: return
+ if os.path.isdir(path):
+ info = imp.find_module("releasetools", [path])
+ else:
+ d, f = os.path.split(path)
+ b, x = os.path.splitext(f)
+ if x == ".py":
+ f = b
+ info = imp.find_module(f, [d])
+ if not info or info[0] is None:
+ raise ValueError("unable to find device-specific module")
+ self.module = imp.load_module("device_specific", *info)
+
+ def _DoCall(self, function_name, *args, **kwargs):
+ """Call the named function in the device-specific module, passing
+ the given args and kwargs. The first argument to the call will be
+ the DeviceSpecific object itself. If there is no module, or the
+ module does not define the function, return the value of the
+ 'default' kwarg (which itself defaults to None)."""
+ if self.module is None or not hasattr(self.module, function_name):
+ return kwargs.get("default", None)
+ return getattr(self.module, function_name)(*((self,) + args), **kwargs)
+
+ def FullOTA_Assertions(self):
+ """Called after emitting the block of assertions at the top of a
+ full OTA package. Implementations can add whatever additional
+ assertions they like."""
+ return self._DoCall("FullOTA_Assertions")
+
+ def FullOTA_InstallEnd(self):
+ """Called at the end of full OTA installation; typically this is
+ used to install the image for the device's baseband processor."""
+ return self._DoCall("FullOTA_InstallEnd")
+
+ def IncrementalOTA_Assertions(self):
+ """Called after emitting the block of assertions at the top of an
+ incremental OTA package. Implementations can add whatever
+ additional assertions they like."""
+ return self._DoCall("IncrementalOTA_Assertions")
+
+ def IncrementalOTA_VerifyEnd(self):
+ """Called at the end of the verification phase of incremental OTA
+ installation; additional checks can be placed here to abort the
+ script before any changes are made."""
+ return self._DoCall("IncrementalOTA_VerifyEnd")
+
+ def IncrementalOTA_InstallEnd(self):
+ """Called at the end of incremental OTA installation; typically
+ this is used to install the image for the device's baseband
+ processor."""
+ return self._DoCall("IncrementalOTA_InstallEnd")