Bug 1163082 - Part 3: Add ANDROID_ASSETS_FILES and bake assets into the APK. r=froyndj
authorNick Alexander <nalexander@mozilla.com>
Mon, 11 May 2015 15:39:27 -0700
changeset 263875 03b964b6bca76a2704ef1dad277e1e6ac9d7a5ce
parent 263874 6b2a1dac0727ae770886fcf3bb8b888f5ca198d2
child 263876 032c4c8f3789c27c879f878ebc87c464cb5c1e52
push id1997
push usernalexander@mozilla.com
push dateTue, 12 May 2015 03:21:22 +0000
reviewersfroyndj
bugs1163082
milestone40.0a1
Bug 1163082 - Part 3: Add ANDROID_ASSETS_FILES and bake assets into the APK. r=froyndj
Makefile.in
mobile/android/base/moz.build
python/mozbuild/mozbuild/backend/recursivemake.py
python/mozbuild/mozbuild/frontend/context.py
python/mozbuild/mozbuild/frontend/data.py
python/mozbuild/mozbuild/frontend/emitter.py
toolkit/mozapps/installer/upload-files.mk
--- a/Makefile.in
+++ b/Makefile.in
@@ -90,17 +90,17 @@ backend.RecursiveMakeBackend:
 Makefile: backend.RecursiveMakeBackend
 	@$(TOUCH) $@
 
 include backend.RecursiveMakeBackend.pp
 
 default:: backend.RecursiveMakeBackend
 
 install_manifests := \
-  $(addprefix dist/,bin branding idl include public private sdk xpi-stage) \
+  $(addprefix dist/,android_assets bin branding idl include public private sdk xpi-stage) \
   _tests \
   $(NULL)
 install_manifest_depends = \
   CLOBBER \
   $(configure_dir)/configure \
   config.status \
   backend.RecursiveMakeBackend \
   $(NULL)
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -941,8 +941,11 @@ if CONFIG['MOZ_ANDROID_MLS_STUMBLER']:
     main.included_projects += ['../FennecStumbler']
     main.referenced_projects += ['../FennecStumbler']
 
 if CONFIG['MOZ_ANDROID_SEARCH_ACTIVITY']:
     # The Search Activity code is built as part of Fennec, so we follow suit in Eclipse.
     main.add_classpathentry('search', TOPSRCDIR + '/mobile/android/search/java', dstdir='search')
 
 DIST_FILES += ['package-name.txt.in']
+
+# This arranges to have dist/android_assets/* appear in assets/* in the APK.
+ANDROID_ASSETS_DIRS += [TOPOBJDIR + '/dist/android_assets']
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -22,16 +22,17 @@ from reftest import ReftestManifest
 from mozpack.copier import FilePurger
 from mozpack.manifests import (
     InstallManifest,
 )
 import mozpack.path as mozpath
 
 from .common import CommonBackend
 from ..frontend.data import (
+    AndroidAssetsFiles,
     AndroidEclipseProjectData,
     BrandingFiles,
     ConfigFileSubstitution,
     ContextDerived,
     ContextWrapped,
     Defines,
     DistFiles,
     DirectoryTraversal,
@@ -373,16 +374,17 @@ class RecursiveMakeBackend(CommonBackend
 
         self._test_manifests = {}
 
         self.backend_input_files.add(mozpath.join(self.environment.topobjdir,
             'config', 'autoconf.mk'))
 
         self._install_manifests = {
             k: InstallManifest() for k in [
+                'dist_android_assets',
                 'dist_bin',
                 'dist_branding',
                 'dist_idl',
                 'dist_include',
                 'dist_public',
                 'dist_private',
                 'dist_sdk',
                 'dist_xpi-stage',
@@ -489,16 +491,19 @@ class RecursiveMakeBackend(CommonBackend
 """.format(output=obj.output,
            inputs=' ' + ' '.join(obj.inputs) if obj.inputs else '',
            script=obj.script,
            method=obj.method))
 
         elif isinstance(obj, TestHarnessFiles):
             self._process_test_harness_files(obj, backend_file)
 
+        elif isinstance(obj, AndroidAssetsFiles):
+            self._process_android_assets_files(obj, backend_file)
+
         elif isinstance(obj, Resources):
             self._process_resources(obj, obj.resources, backend_file)
 
         elif isinstance(obj, BrandingFiles):
             self._process_branding_files(obj, obj.files, backend_file)
 
         elif isinstance(obj, JsPreferenceFile):
             if obj.path.startswith('/'):
@@ -931,16 +936,20 @@ class RecursiveMakeBackend(CommonBackend
 INSTALL_TARGETS += %(prefix)s
 """ % { 'prefix': prefix,
         'dest': '$(DEPTH)/%s/%s' % (destdir, path),
         'files': ' '.join(files) })
 
     def _process_test_harness_files(self, obj, backend_file):
         self._process_files(obj, backend_file, 'TEST_HARNESS_FILES', '_tests', self._install_manifests['tests'])
 
+    def _process_android_assets_files(self, obj, backend_file):
+        self._process_files(obj, backend_file, 'ANDROID_ASSETS_FILES', 'dist/android_assets',
+            self._install_manifests['dist_android_assets'])
+
     def _process_resources(self, obj, resources, backend_file):
         dep_path = mozpath.join(self.environment.topobjdir, '_build_manifests', '.deps', 'install')
 
         # Resources need to go in the 'res' subdirectory of $(DIST)/bin, so we
         # specify a root namespace of 'res'.
         for source, dest, flags in self._walk_hierarchy(obj, resources,
                                                         namespace='res'):
             if flags and flags.preprocess:
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1407,16 +1407,31 @@ VARIABLES = {
         to export ``foo.py`` to ``_tests/foo``, append to
         ``TEST_HARNESS_FILES`` like so::
            TEST_HARNESS_FILES.foo += ['foo.py']
 
         Files from topsrcdir and the objdir can also be installed by prefixing
         the path(s) with a '/' character and a '!' character, respectively::
            TEST_HARNESS_FILES.path += ['/build/bar.py', '!quux.py']
         """, 'libs'),
+
+    'ANDROID_ASSETS_FILES': (HierarchicalStringList, list,
+        """List of files to be installed into Fennec package assets directory.
+
+        ``ANDROID_ASSETS_FILES`` can be used to install files to any directory
+        under assets/ in the APK. Files can be appended to a field to indicate
+        which subdirectory they should be exported to. For example,
+        to export ``foo.py`` to ``assets/foo/``, append to
+        ``ANDROID_ASSETS_FILES`` like so::
+           ANDROID_ASSETS_FILES.foo += ['foo.py']
+
+        Files from topsrcdir, the objdir, and the topobjdir can also be installed by prefixing
+        the path(s) with a '/' character, a '!' character, and a '!/', respectively::
+           ANDROID_ASSETS_FILES.path += ['/intopsrcdir', '!inobjdir', '!/intopobjdir']
+        """, 'libs'),
 }
 
 # Sanity check: we don't want any variable above to have a list as storage type.
 for name, (storage_type, input_types, docs, tier) in VARIABLES.items():
     if storage_type == list:
         raise RuntimeError('%s has a "list" storage type. Use "List" instead.'
             % name)
 
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -224,16 +224,22 @@ class AbstractFileList(ContextDerived):
         self.objdir_files = objdir_files
 
 class TestHarnessFiles(AbstractFileList):
     """Sandbox container object for TEST_HARNESS_FILES,
     which is a HierarchicalStringList.
     """
     pass
 
+class AndroidAssetsFiles(AbstractFileList):
+    """Sandbox container object for ANDROID_ASSETS_FILES,
+    which is a HierarchicalStringList.
+    """
+    pass
+
 class Resources(ContextDerived):
     """Context derived container object for RESOURCE_FILES, which is a
     HierarchicalStringList, with an extra ``.preprocess`` property on each
     entry.
 
     The local defines plus anything in ACDEFINES are stored in ``defines`` as a
     dictionary, for any files that need preprocessing.
     """
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -20,16 +20,17 @@ from mozbuild.util import (
 )
 
 import mozpack.path as mozpath
 import manifestparser
 import reftest
 import mozinfo
 
 from .data import (
+    AndroidAssetsFiles,
     BrandingFiles,
     ConfigFileSubstitution,
     ContextWrapped,
     Defines,
     DistFiles,
     DirectoryTraversal,
     Exports,
     FinalTargetFiles,
@@ -593,16 +594,19 @@ class TreeMetadataEmitter(LoggingMixin):
                 dist_install=not context.get('NO_DIST_INSTALL', False))
 
         for obj in self._process_generated_files(context):
             yield obj
 
         for obj in self._process_test_harness_files(context):
             yield obj
 
+        for obj in self._process_android_assets_files(context):
+            yield obj
+
         defines = context.get('DEFINES')
         if defines:
             yield Defines(context, defines)
 
         resources = context.get('RESOURCE_FILES')
         if resources:
             yield Resources(context, resources, defines)
 
@@ -839,16 +843,20 @@ class TreeMetadataEmitter(LoggingMixin):
                 method = None
                 inputs = []
             yield GeneratedFile(context, script, method, output, inputs)
 
     def _process_test_harness_files(self, context):
         return self._process_files(context, 'TEST_HARNESS_FILES', TestHarnessFiles,
             allow_install_to_root=False)
 
+    def _process_android_assets_files(self, context):
+        return self._process_files(context, 'ANDROID_ASSETS_FILES', AndroidAssetsFiles,
+            allow_install_to_root=True)
+
     def _process_files(self, context, varname, factory, allow_install_to_root=True):
         """Process an optional list of files named 'varname',
         possibly yielding the output of 'factory'.
 
         'factory' should accept four parameters:
         - context
         - srcdir_files
         - srcdir_pattern_files
--- a/toolkit/mozapps/installer/upload-files.mk
+++ b/toolkit/mozapps/installer/upload-files.mk
@@ -458,16 +458,17 @@ INNER_MAKE_PACKAGE	= \
   make -C $(GECKO_APP_AP_PATH) gecko-nodeps.ap_ && \
   cp $(GECKO_APP_AP_PATH)/gecko-nodeps.ap_ $(_ABS_DIST)/gecko.ap_ && \
   ( (test ! -f $(GECKO_APP_AP_PATH)/R.txt && echo "*** Warning: The R.txt that is being packaged might not agree with the R.txt that was built. This is normal during l10n repacks.") || \
     diff $(GECKO_APP_AP_PATH)/R.txt $(GECKO_APP_AP_PATH)/gecko-nodeps/R.txt >/dev/null || \
     (echo "*** Error: The R.txt that was built and the R.txt that is being packaged are not the same. Rebuild mobile/android/base and re-package." && exit 1)) && \
   ( cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && \
     unzip -o $(_ABS_DIST)/gecko.ap_ && \
     rm $(_ABS_DIST)/gecko.ap_ && \
+    $(ZIP) -r9D $(_ABS_DIST)/gecko.ap_ assets && \
     $(ZIP) $(if $(ALREADY_SZIPPED),-0 ,$(if $(MOZ_ENABLE_SZIP),-0 ))$(_ABS_DIST)/gecko.ap_ $(ASSET_SO_LIBRARIES) && \
     $(ZIP) -r9D $(_ABS_DIST)/gecko.ap_ $(DIST_FILES) -x $(NON_DIST_FILES) $(SZIP_LIBRARIES) && \
     $(if $(filter-out ./,$(OMNIJAR_DIR)), \
       mkdir -p $(OMNIJAR_DIR) && mv $(OMNIJAR_NAME) $(OMNIJAR_DIR) && ) \
     $(ZIP) -0 $(_ABS_DIST)/gecko.ap_ $(OMNIJAR_DIR)$(OMNIJAR_NAME)) && \
   rm -f $(_ABS_DIST)/gecko.apk && \
   cp $(_ABS_DIST)/gecko.ap_ $(_ABS_DIST)/gecko.apk && \
   $(ZIP) -j0 $(_ABS_DIST)/gecko.apk $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \