Bug 1160563 - Part 2: Make ANDROID_ASSETS_DIRS a moz.build variable. r=gps, a=sledru
authorNick Alexander <nalexander@mozilla.com>
Wed, 12 Aug 2015 11:04:03 -0700
changeset 295062 39fcc0e11d27adc301394a094a5db2f3c9fd41b8
parent 295061 84e994df984952273c452887f1effd7756023707
child 295063 7703f7784afd4a7dfc7d67907abd0840d7a1fb2e
push id5628
push usermozilla@noorenberghe.ca
push dateMon, 21 Sep 2015 23:09:25 +0000
reviewersgps, sledru
bugs1160563
milestone42.0a2
Bug 1160563 - Part 2: Make ANDROID_ASSETS_DIRS a moz.build variable. r=gps, a=sledru We have had singular ANDROID_ASSETS_DIR in Makefile.in for a while. Fennec itself does not use the existing Makefile.in Android code, for complicated historical reasons. This makes the existing variable moz.build-only; generalizes the existing variable to an ordered list; and adds the equivalent use of the new list to the Fennec build, with a simple example asset. This patch also updates the packager to include assets packed into the gecko.ap_. Without the packager change, the assets/ directory in the ap_ gets left out of the final apk. This whole approach is totally non-standard but is more or less required to support our single-locale repack scheme.
build/mobile/robocop/Makefile.in
build/mobile/robocop/moz.build
config/makefiles/java-build.mk
mobile/android/app/assets/example_asset.txt
mobile/android/base/Makefile.in
mobile/android/base/moz.build
mobile/android/mach_commands.py
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/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -6,18 +6,16 @@ mobile-tests := mobile/android/tests/bro
 TESTPATH     := $(topsrcdir)/$(mobile-tests)
 
 ANDROID_APK_NAME := robocop-debug
 
 ANDROID_EXTRA_JARS += \
   $(srcdir)/robotium-solo-4.3.1.jar \
   $(NULL)
 
-ANDROID_ASSETS_DIR := $(TESTPATH)/assets
-
 _JAVA_HARNESS := \
   Actions.java \
   Assert.java \
   Driver.java \
   Element.java \
   FennecInstrumentationTestRunner.java \
   FennecNativeActions.java \
   FennecMochitestAssert.java \
--- a/build/mobile/robocop/moz.build
+++ b/build/mobile/robocop/moz.build
@@ -2,16 +2,19 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
 
 base = '/mobile/android/tests/browser/robocop/'
+
+ANDROID_ASSETS_DIRS += [base + 'assets']
+
 TEST_HARNESS_FILES.testing.mochitest += [
     base + 'robocop.ini',
     base + 'robocop_autophone.ini',
 ]
 TEST_HARNESS_FILES.testing.mochitest.tests.robocop += [base + x for x in [
     '*.html',
     '*.jpg',
     '*.mp4',
--- a/config/makefiles/java-build.mk
+++ b/config/makefiles/java-build.mk
@@ -13,17 +13,17 @@ GENERATED_DIRS += classes
 export:: classes
 classes: $(call mkdir_deps,classes)
 endif #} JAVAFILES
 
 
 ifdef ANDROID_APK_NAME #{
 android_res_dirs := $(or $(ANDROID_RES_DIRS),$(srcdir)/res)
 _ANDROID_RES_FLAG := $(addprefix -S ,$(android_res_dirs))
-_ANDROID_ASSETS_FLAG := $(addprefix -A ,$(ANDROID_ASSETS_DIR))
+_ANDROID_ASSETS_FLAG := $(if $(ANDROID_ASSETS_DIRS),$(addprefix -A ,$(ANDROID_ASSETS_DIRS)))
 android_manifest := $(or $(ANDROID_MANIFEST_FILE),AndroidManifest.xml)
 
 GENERATED_DIRS += classes
 
 classes.dex: $(call mkdir_deps,classes)
 classes.dex: R.java
 classes.dex: $(ANDROID_APK_NAME).ap_
 classes.dex: $(ANDROID_EXTRA_JARS)
@@ -40,17 +40,17 @@ classes.dex: $(JAVAFILES)
 
 R.java: .aapt.deps ;
 $(ANDROID_APK_NAME).ap_: .aapt.deps ;
 
 # This uses the fact that Android resource directories list all
 # resource files one subdirectory below the parent resource directory.
 android_res_files := $(wildcard $(addsuffix /*,$(wildcard $(addsuffix /*,$(android_res_dirs)))))
 
-.aapt.deps: $(android_manifest) $(android_res_files) $(wildcard $(ANDROID_ASSETS_DIR))
+.aapt.deps: $(android_manifest) $(android_res_files) $(wildcard $(ANDROID_ASSETS_DIRS))
 	@$(TOUCH) $@
 	$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar $(_ANDROID_RES_FLAG) $(_ANDROID_ASSETS_FLAG) \
 		-J ${@D} \
 		-F $(ANDROID_APK_NAME).ap_
 
 $(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
 	cp $< $@
 	$(ZIP) -0 $@ classes.dex
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/assets/example_asset.txt
@@ -0,0 +1,1 @@
+This is an example asset.
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -415,16 +415,17 @@ define aapt_command
 $(1): $$(call mkdir_deps,$(filter-out ./,$(dir $(3) $(4) $(5)))) $(2)
 	@$$(TOUCH) $$@
 	$$(AAPT) package -f -m \
 		-M AndroidManifest.xml \
 		-I $(ANDROID_SDK)/android.jar \
 		$(if $(MOZ_ANDROID_MAX_SDK_VERSION),--max-res-version $(MOZ_ANDROID_MAX_SDK_VERSION),) \
 		--auto-add-overlay \
 		$$(addprefix -S ,$$(ANDROID_RES_DIRS)) \
+		$$(addprefix -A ,$$(ANDROID_ASSETS_DIRS)) \
 		$(if $(extra_res_dirs),$$(addprefix -S ,$$(extra_res_dirs)),) \
 		$(if $(extra_packages),--extra-packages $$(extra_packages),) \
 		--custom-package org.mozilla.gecko \
 		--non-constant-id \
 		-F $(3) \
 		-J $(4) \
 		--output-text-symbols $(5) \
 		$(if $(MOZ_ANDROID_RESOURCE_CONSTRAINED),-c $(CONSTRAINED_AAPT_CONFIGURATIONS),) \
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -758,16 +758,20 @@ ANDROID_RES_DIRS += [
     '!res',
 ]
 
 ANDROID_GENERATED_RESFILES += [
     'res/raw/suggestedsites.json',
     'res/values/strings.xml',
 ]
 
+ANDROID_ASSETS_DIRS += [
+    '/mobile/android/app/assets',
+]
+
 # We do not expose MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN here because that
 # would leak the value to build logs.  Instead we expose the token quietly where
 # appropriate in Makefile.in.
 for var in ('MOZ_ANDROID_ANR_REPORTER', 'MOZ_LINKER_EXTRACT', 'MOZILLA_OFFICIAL', 'MOZ_DEBUG',
             'MOZ_ANDROID_SEARCH_ACTIVITY', 'MOZ_NATIVE_DEVICES', 'MOZ_ANDROID_MLS_STUMBLER',
             'MOZ_ANDROID_SHARE_OVERLAY', 'MOZ_ANDROID_DOWNLOADS_INTEGRATION', 'MOZ_INSTALL_TRACKING',
             'MOZ_ANDROID_TAB_QUEUE', 'MOZ_ANDROID_FIREFOX_ACCOUNT_PROFILES'):
     if CONFIG[var]:
--- a/mobile/android/mach_commands.py
+++ b/mobile/android/mach_commands.py
@@ -137,16 +137,17 @@ class MachCommands(MachCommandBase):
         srcdir('base/src/main/java/org/mozilla/gecko', 'mobile/android/base')
         srcdir('base/src/main/java/org/mozilla/mozstumbler', 'mobile/android/stumbler/java/org/mozilla/mozstumbler')
         srcdir('base/src/main/java/org/mozilla/search', 'mobile/android/search/java/org/mozilla/search')
         srcdir('base/src/main/java/org/mozilla/javaaddons', 'mobile/android/javaaddons/java/org/mozilla/javaaddons')
         srcdir('base/src/webrtc_audio_device/java', 'media/webrtc/trunk/webrtc/modules/audio_device/android/java/src')
         srcdir('base/src/webrtc_video_capture/java', 'media/webrtc/trunk/webrtc/modules/video_capture/android/java/src')
         srcdir('base/src/webrtc_video_render/java', 'media/webrtc/trunk/webrtc/modules/video_render/android/java/src')
         srcdir('base/src/main/res', 'mobile/android/base/resources')
+        srcdir('base/src/main/assets', 'mobile/android/app/assets')
         srcdir('base/src/crashreporter/res', 'mobile/android/base/crashreporter/res')
 
         manifest_path = os.path.join(self.topobjdir, 'mobile', 'android', 'gradle.manifest')
         with FileAvoidWrite(manifest_path) as f:
             m.write(fileobj=f)
 
         self.virtualenv_manager.ensure()
         code = self.run_process([
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -21,16 +21,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 (
+    AndroidAssetsDirs,
     AndroidResDirs,
     AndroidEclipseProjectData,
     BrandingFiles,
     ConfigFileSubstitution,
     ContextDerived,
     ContextWrapped,
     Defines,
     DistFiles,
@@ -66,16 +67,17 @@ from ..frontend.data import (
 )
 from ..util import (
     ensureParentDir,
     FileAvoidWrite,
 )
 from ..makeutil import Makefile
 
 MOZBUILD_VARIABLES = [
+    b'ANDROID_ASSETS_DIRS',
     b'ANDROID_GENERATED_RESFILES',
     b'ANDROID_RES_DIRS',
     b'ASFLAGS',
     b'CMSRCS',
     b'CMMSRCS',
     b'CPP_UNIT_TESTS',
     b'DIRS',
     b'DIST_INSTALL',
@@ -598,16 +600,20 @@ class RecursiveMakeBackend(CommonBackend
             # underlying Makefile.in.
             for f in obj.files:
                 backend_file.write('DIST_FILES += %s\n' % f)
 
         elif isinstance(obj, AndroidResDirs):
             for p in obj.paths:
                 backend_file.write('ANDROID_RES_DIRS += %s\n' % p.full_path)
 
+        elif isinstance(obj, AndroidAssetsDirs):
+            for p in obj.paths:
+                backend_file.write('ANDROID_ASSETS_DIRS += %s\n' % p.full_path)
+
         else:
             return
         obj.ack()
 
     def _fill_root_mk(self):
         """
         Create two files, root.mk and root-deps.mk, the first containing
         convenience variables, and the other dependency definitions for a
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -694,16 +694,24 @@ VARIABLES = {
     'ANDROID_RES_DIRS': (ContextDerivedTypedListWithItems(Path, List), list,
         """Android resource directories.
 
         This variable contains a list of directories containing static
         files to package into a 'res' directory and merge into an APK
         file.
         """, 'export'),
 
+    'ANDROID_ASSETS_DIRS': (ContextDerivedTypedListWithItems(Path, List), list,
+        """Android assets directories.
+
+        This variable contains a list of directories containing static
+        files to package into an 'assets' directory and merge into an
+        APK file.
+        """, 'export'),
+
     'ANDROID_ECLIPSE_PROJECT_TARGETS': (dict, dict,
         """Defines Android Eclipse project targets.
 
         This variable should not be populated directly. Instead, it should
         populated by calling add_android_eclipse{_library}_project().
         """, 'export'),
 
     'SOURCES': (ContextDerivedTypedListWithItems(Path, StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': List})), list,
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -970,8 +970,19 @@ class AndroidResDirs(ContextDerived):
 
     __slots__ = (
         'paths',
     )
 
     def __init__(self, context, paths):
         ContextDerived.__init__(self, context)
         self.paths = paths
+
+class AndroidAssetsDirs(ContextDerived):
+    """Represents Android assets directories."""
+
+    __slots__ = (
+        'paths',
+    )
+
+    def __init__(self, context, paths):
+        ContextDerived.__init__(self, context)
+        self.paths = paths
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -19,16 +19,17 @@ from mozbuild.util import (
 )
 
 import mozpack.path as mozpath
 import manifestparser
 import reftest
 import mozinfo
 
 from .data import (
+    AndroidAssetsDirs,
     AndroidResDirs,
     BrandingFiles,
     ConfigFileSubstitution,
     ContextWrapped,
     Defines,
     DistFiles,
     DirectoryTraversal,
     Exports,
@@ -695,24 +696,28 @@ class TreeMetadataEmitter(LoggingMixin):
             yield obj
 
         for name, jar in context.get('JAVA_JAR_TARGETS', {}).items():
             yield ContextWrapped(context, jar)
 
         for name, data in context.get('ANDROID_ECLIPSE_PROJECT_TARGETS', {}).items():
             yield ContextWrapped(context, data)
 
-        paths = context.get('ANDROID_RES_DIRS')
-        if paths:
+        for (symbol, cls) in [
+                ('ANDROID_RES_DIRS', AndroidResDirs),
+                ('ANDROID_ASSETS_DIRS', AndroidAssetsDirs)]:
+            paths = context.get(symbol)
+            if not paths:
+                continue
             for p in paths:
                 if isinstance(p, SourcePath) and not os.path.isdir(p.full_path):
                     raise SandboxValidationError('Directory listed in '
-                        'ANDROID_RES_DIRS is not a directory: \'%s\'' %
-                            p.full_path, context)
-            yield AndroidResDirs(context, paths)
+                        '%s is not a directory: \'%s\'' %
+                            (symbol, p.full_path), context)
+            yield cls(context, paths)
 
         if passthru.variables:
             yield passthru
 
     def _create_substitution(self, cls, context, path):
         if os.path.isabs(path):
             path = path[1:]
 
--- a/toolkit/mozapps/installer/upload-files.mk
+++ b/toolkit/mozapps/installer/upload-files.mk
@@ -465,16 +465,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 && \