# 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/.

# We call mach -> Make -> gradle -> mach, which races to find and
# create .mozconfig files and to generate targets.
ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
.NOTPARALLEL:
endif

MOZ_BUILDID := $(shell awk '{print $$3}' $(DEPTH)/buildid.h)

# Set the appropriate version code, based on the existance of the
# MOZ_APP_ANDROID_VERSION_CODE variable.
ifdef MOZ_APP_ANDROID_VERSION_CODE
    ANDROID_VERSION_CODE:=$(MOZ_APP_ANDROID_VERSION_CODE)
else
    ANDROID_VERSION_CODE:=$(shell $(PYTHON) \
      $(topsrcdir)/python/mozbuild/mozbuild/android_version_code.py \
        --verbose \
        --with-android-cpu-arch=$(ANDROID_CPU_ARCH) \
        $(if $(MOZ_ANDROID_MIN_SDK_VERSION),--with-android-min-sdk=$(MOZ_ANDROID_MIN_SDK_VERSION)) \
        $(if $(MOZ_ANDROID_MAX_SDK_VERSION),--with-android-max-sdk=$(MOZ_ANDROID_MAX_SDK_VERSION)) \
        $(MOZ_BUILDID))
endif

DEFINES += \
  -DANDROID_VERSION_CODE=$(ANDROID_VERSION_CODE) \
  -DMOZ_ANDROID_SHARED_ID="$(MOZ_ANDROID_SHARED_ID)" \
  -DMOZ_BUILDID=$(MOZ_BUILDID) \
  $(NULL)

GARBAGE += \
  classes.dex  \
  gecko.ap_  \
  res/values/strings.xml \
  res/raw/browsersearch.json \
  res/raw/suggestedsites.json \
  .aapt.deps \
  GeneratedJNINatives.h \
  GeneratedJNIWrappers.cpp \
  GeneratedJNIWrappers.h \
  FennecJNINatives.h \
  FennecJNIWrappers.cpp \
  FennecJNIWrappers.h \
  $(NULL)

GARBAGE_DIRS += classes db jars res sync services generated

# The bootclasspath is functionally identical to the classpath, but allows the
# classes given to redefine classes in core packages, such as java.lang.
# android.jar is here as it provides Android's definition of the Java Standard
# Library. The compatability lib here tweaks a few of the core classes to paint
# over changes in behaviour between versions.
JAVA_BOOTCLASSPATH := \
    $(ANDROID_SDK)/android.jar \
    $(NULL)

JAVA_BOOTCLASSPATH := $(subst $(NULL) ,:,$(strip $(JAVA_BOOTCLASSPATH)))

JAVA_CLASSPATH += \
    $(ANDROID_SUPPORT_ANNOTATIONS_JAR_LIB) \
    $(ANDROID_SUPPORT_V4_AAR_LIB) \
    $(ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB) \
    $(ANDROID_APPCOMPAT_V7_AAR_LIB) \
    $(ANDROID_SUPPORT_VECTOR_DRAWABLE_AAR_LIB) \
    $(ANDROID_ANIMATED_VECTOR_DRAWABLE_AAR_LIB) \
    $(ANDROID_CARDVIEW_V7_AAR_LIB) \
    $(ANDROID_DESIGN_AAR_LIB) \
    $(ANDROID_RECYCLERVIEW_V7_AAR_LIB) \
    $(ANDROID_CUSTOMTABS_AAR_LIB) \
    $(ANDROID_PALETTE_V7_AAR_LIB) \
    $(NULL)

# If native devices are enabled, add Google Play Services and some of the v7
# compat libraries.
ifdef MOZ_NATIVE_DEVICES
    JAVA_CLASSPATH += \
        $(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_CAST_AAR_LIB) \
        $(ANDROID_MEDIAROUTER_V7_AAR_LIB) \
        $(ANDROID_MEDIAROUTER_V7_AAR_INTERNAL_LIB) \
        $(NULL)
endif

ifdef MOZ_ANDROID_GCM
    JAVA_CLASSPATH += \
        $(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_GCM_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_MEASUREMENT_AAR_LIB) \
        $(NULL)
endif

ifdef MOZ_INSTALL_TRACKING
    JAVA_CLASSPATH += \
        $(ANDROID_PLAY_SERVICES_ADS_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
        $(NULL)
endif

JAVA_CLASSPATH := $(subst $(NULL) ,:,$(strip $(JAVA_CLASSPATH)))

# Library jars that we're bundling: these are subject to Proguard before inclusion
# into classes.dex.
java_bundled_libs := \
    $(ANDROID_SUPPORT_V4_AAR_LIB) \
    $(ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB) \
    $(ANDROID_APPCOMPAT_V7_AAR_LIB) \
    $(ANDROID_SUPPORT_VECTOR_DRAWABLE_AAR_LIB) \
    $(ANDROID_ANIMATED_VECTOR_DRAWABLE_AAR_LIB) \
    $(ANDROID_CARDVIEW_V7_AAR_LIB) \
    $(ANDROID_DESIGN_AAR_LIB) \
    $(ANDROID_RECYCLERVIEW_V7_AAR_LIB) \
    $(ANDROID_CUSTOMTABS_AAR_LIB) \
    $(ANDROID_PALETTE_V7_AAR_LIB) \
    $(NULL)

ifdef MOZ_NATIVE_DEVICES
    java_bundled_libs += \
        $(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_CAST_AAR_LIB) \
        $(ANDROID_MEDIAROUTER_V7_AAR_LIB) \
        $(ANDROID_MEDIAROUTER_V7_AAR_INTERNAL_LIB) \
        $(NULL)
endif

ifdef MOZ_ANDROID_GCM
    java_bundled_libs += \
        $(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_GCM_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_MEASUREMENT_AAR_LIB) \
        $(NULL)
endif

ifdef MOZ_INSTALL_TRACKING
    java_bundled_libs += \
        $(ANDROID_PLAY_SERVICES_ADS_AAR_LIB) \
        $(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
        $(NULL)
endif

# uniq purloined from http://stackoverflow.com/a/16151140.
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))

java_bundled_libs := $(call uniq,$(java_bundled_libs))
java_bundled_libs := $(subst $(NULL) ,:,$(strip $(java_bundled_libs)))

GECKOVIEW_JARS = \
  constants.jar \
  gecko-R.jar \
  gecko-mozglue.jar \
  gecko-util.jar \
  gecko-view.jar \
  sync-thirdparty.jar \
  $(NULL)

ifdef MOZ_INSTALL_TRACKING
GECKOVIEW_JARS += gecko-thirdparty-adjust_sdk.jar
endif

geckoview_jars_classpath := $(subst $(NULL) ,:,$(strip $(GECKOVIEW_JARS)))

FENNEC_JARS = \
  gecko-browser.jar \
  gecko-thirdparty.jar \
  services.jar \
  ../javaaddons/javaaddons-1.0.jar \
  $(NULL)

ifdef MOZ_WEBRTC
FENNEC_JARS += webrtc.jar
endif

ifdef MOZ_ANDROID_SEARCH_ACTIVITY
FENNEC_JARS += search-activity.jar
endif

ifdef MOZ_ANDROID_MLS_STUMBLER
FENNEC_JARS += ../stumbler/stumbler.jar
endif

# All the jars we're compiling from source. (not to be confused with
# java_bundled_libs, which holds the jars which we're including as binaries).
ALL_JARS = \
  $(GECKOVIEW_JARS) \
  $(FENNEC_JARS) \
  $(NULL)

# The list of jars in Java classpath notation (colon-separated).
all_jars_classpath := $(subst $(NULL) ,:,$(strip $(ALL_JARS)))

include $(topsrcdir)/config/config.mk

library_jars := \
    $(ANDROID_SDK)/android.jar \
    $(NULL)

# Android 23 (Marshmallow) deprecated a part of the Android platform, namely the
# org.apache.http package.  Fennec removed all code that referenced said package
# in order to easily ship to Android 23 devices (and, by extension, all devices
# before Android 23).
#
# Google did not remove all code that referenced said package in their own
# com.google.android.gms namespace!  It turns out that the org.apache.http
# package is not removed, only deprecated and hidden by default.  Google added a
# a `useLibrary` Gradle directive that allows legacy code to reference the
# package, which is still (hidden) in the Android 23 platform.
#
# Fennec code doesn't need to compile against the deprecated package, since our
# code doesn't reference the package anymore.  However, we do need to Proguard
# against the deprecated package.  If we don't, Proguard -- which is a global
# optimization -- sees Google libraries referencing "non-existent" libraries and
# complains.  The solution is to mimic the `useLibraries` directive by declaring
# the legacy package as a provided library jar.
#
# See https://bugzilla.mozilla.org/show_bug.cgi?id=1233238#c19 for symptoms and
# more discussion.
ifdef MOZ_INSTALL_TRACKING
library_jars += $(ANDROID_SDK)/optional/org.apache.http.legacy.jar
endif # MOZ_INSTALL_TRACKING

library_jars := $(subst $(NULL) ,:,$(strip $(library_jars)))

gradle_dir := $(topobjdir)/gradle/build/mobile/android

ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
.gradle.deps: .aapt.deps FORCE
	@$(TOUCH) $@
	$(topsrcdir)/mach gradle \
		app:assembleAutomationDebug app:assembleAutomationDebugAndroidTest -x lint

classes.dex: .gradle.deps
	$(REPORT_BUILD)
	cp $(gradle_dir)/app/intermediates/transforms/dex/automation/debug/folders/1000/1f/main/classes.dex $@
else
classes.dex: .proguard.deps
	$(REPORT_BUILD)
	$(DX) --dex --output=classes.dex jars-proguarded
endif

ifdef MOZ_DISABLE_PROGUARD
  PROGUARD_PASSES=0
else
  ifdef MOZ_DEBUG
    PROGUARD_PASSES=1
  else
    ifndef MOZILLA_OFFICIAL
      PROGUARD_PASSES=1
    else
      PROGUARD_PASSES=6
    endif
  endif
endif

proguard_config_dir=$(topsrcdir)/mobile/android/config/proguard

# This stanza ensures that the set of GeckoView classes does not depend on too
# much of Fennec, where "too much" is defined as the set of potentially
# non-GeckoView classes that GeckoView already depended on at a certain point in
# time.  The idea is to set a high-water mark that is not to be crossed.
classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar
.geckoview.deps: geckoview.ddf $(classycle_jar) $(ALL_JARS)
	$(JAVA) -cp $(classycle_jar) \
		classycle.dependency.DependencyChecker \
		-mergeInnerClasses \
		-dependencies=@$< \
		$(ALL_JARS)
	@$(TOUCH) $@

# First, we delete debugging information from libraries. Having line-number
# information for libraries for which we lack the source isn't useful, so this
# saves us a bit of space. Importantly, Proguard has a bug causing it to
# sometimes corrupt this information if present (which it does for some of the
# included libraries). This corruption prevents dex from completing, so we need
# to get rid of it.  This prevents us from seeing line numbers in stack traces
# for stack frames inside libraries.
#
# This step can occur much earlier than the main Proguard pass: it needs only
# gecko-R.jar to have been compiled (as that's where the library R.java files
# end up), but it does block the main Proguard pass.
.bundled.proguard.deps: gecko-R.jar $(proguard_config_dir)/strip-libs.cfg
	$(REPORT_BUILD)
	@$(TOUCH) $@
	$(JAVA) \
		-Xmx512m -Xms128m \
		-jar $(ANDROID_SDK_ROOT)/tools/proguard/lib/proguard.jar \
		@$(proguard_config_dir)/strip-libs.cfg \
		-injars $(subst ::,:,$(java_bundled_libs))\
		-outjars bundled-jars-nodebug \
		-libraryjars $(library_jars):gecko-R.jar

# We touch the target file before invoking Proguard so that Proguard's
# outputs are fresher than the target, preventing a subsequent
# invocation from thinking Proguard's outputs are stale.  This is safe
# because Make removes the target file if any recipe command fails.
.proguard.deps: .geckoview.deps .bundled.proguard.deps $(ALL_JARS) $(proguard_config_dir)/proguard.cfg
	$(REPORT_BUILD)
	@$(TOUCH) $@
	$(JAVA) \
		-Xmx512m -Xms128m \
		-jar $(ANDROID_SDK_ROOT)/tools/proguard/lib/proguard.jar \
		@$(proguard_config_dir)/proguard.cfg \
		-optimizationpasses $(PROGUARD_PASSES) \
		-injars $(subst ::,:,$(all_jars_classpath)):bundled-jars-nodebug \
		-outjars jars-proguarded \
		-libraryjars $(library_jars)

ANNOTATION_PROCESSOR_JAR_FILES := $(DEPTH)/build/annotationProcessors/annotationProcessors.jar

# This annotation processing step also generates
# GeneratedJNIWrappers.h and GeneratedJNINatives.h
GeneratedJNIWrappers.cpp: $(ANNOTATION_PROCESSOR_JAR_FILES) $(GECKOVIEW_JARS)
	$(JAVA) -classpath $(geckoview_jars_classpath):$(JAVA_BOOTCLASSPATH):$(JAVA_CLASSPATH):$(ANNOTATION_PROCESSOR_JAR_FILES) \
		org.mozilla.gecko.annotationProcessors.AnnotationProcessor \
		Generated $(GECKOVIEW_JARS)

# This annotation processing step also generates
# FennecJNIWrappers.h and FennecJNINatives.h
FennecJNIWrappers.cpp: $(ANNOTATION_PROCESSOR_JAR_FILES) $(FENNEC_JARS)
	$(JAVA) -classpath $(all_jars_classpath):$(JAVA_BOOTCLASSPATH):$(JAVA_CLASSPATH):$(ANNOTATION_PROCESSOR_JAR_FILES) \
		org.mozilla.gecko.annotationProcessors.AnnotationProcessor \
		Fennec $(FENNEC_JARS)

# Certain source files need to be preprocessed.  This special rule
# generates these files into generated/org/mozilla/gecko for
# consumption by the build system and IDEs.

# The list in moz.build looks like
# 'preprocessed/org/mozilla/gecko/AppConstants.java'.  The list in
# constants_PP_JAVAFILES looks like
# 'generated/preprocessed/org/mozilla/gecko/AppConstants.java'.  We
# need to write AppConstants.java.in to
# generated/preprocessed/org/mozilla/gecko.
preprocessed := $(addsuffix .in,$(subst generated/preprocessed/org/mozilla/gecko/,,$(filter generated/preprocessed/org/mozilla/gecko/%,$(constants_PP_JAVAFILES))))

preprocessed_PATH := generated/preprocessed/org/mozilla/gecko
preprocessed_KEEP_PATH := 1
preprocessed_FLAGS := --marker='//\\\#'

PP_TARGETS += preprocessed

include $(topsrcdir)/config/rules.mk

not_android_res_files := \
  *.mkdir.done* \
  *.DS_Store* \
  *\#* \
  *.rej \
  *.orig \
  $(NULL)

# This uses the fact that Android resource directories list all
# resource files one subdirectory below the parent resource directory.
android_res_files := $(filter-out $(not_android_res_files),$(wildcard $(addsuffix /*,$(wildcard $(addsuffix /*,$(ANDROID_RES_DIRS))))))

$(ANDROID_GENERATED_RESFILES): $(call mkdir_deps,$(sort $(dir $(ANDROID_GENERATED_RESFILES))))

# [Comment 1/3] We don't have correct dependencies for strings.xml at
# this point, so we always recursively invoke the submake to check the
# dependencies.  Sigh.  And, with multilocale builds, there will be
# multiple strings.xml files, and we need to rebuild gecko.ap_ if any
# of them change.  But!  mobile/android/base/locales does not have
# enough information to actually build res/values/strings.xml during a
# language repack.  So rather than adding rules into the main
# makefile, and trying to work around the lack of information, we
# force a rebuild of gecko.ap_ during packaging.  See below.

# Since the sub-Make is forced, it doesn't matter that we touch the
# target file before the command.  If in the future we stop forcing
# the sub-Make, touching the target file first is better, because the
# sub-Make outputs will be fresher than the target, and not require
# rebuilding.  This is all safe because Make removes the target file
# if any recipe command fails. It is crucial that the sub-Make touch
# the target files (those depending on .locales.deps) only when there
# contents have changed; otherwise, this will force rebuild them as
# part of every build.
.locales.deps: FORCE
	$(TOUCH) $@
	$(MAKE) -C locales


# This .deps pattern saves an invocation of the sub-Make: the single
# invocation generates strings.xml, browsersearch.json, and
# suggestedsites.json. The trailing semi-colon defines an empty
# recipe: defining no recipe at all causes Make to treat the target
# differently, in a way that defeats our dependencies.
res/values/strings.xml: .locales.deps ;
res/raw/browsersearch.json: .locales.deps ;
res/raw/suggestedsites.json: .locales.deps ;

all_resources = \
  $(DEPTH)/mobile/android/base/AndroidManifest.xml \
  $(android_res_files) \
  $(ANDROID_GENERATED_RESFILES) \
  $(NULL)

# All of generated/org/mozilla/gecko/R.java, gecko.ap_, and R.txt are
# produced by aapt; this saves aapt invocations.  The trailing
# semi-colon defines an empty recipe; defining no recipe at all causes
# Make to treat the target differently, in a way that defeats our
# dependencies.

generated/org/mozilla/gecko/R.java: .aapt.deps ;

# Only add libraries that contain resources here. We (unecessarily) generate an identical R.java which
# is copied into each of these locations, and each of these files contains thousands of fields.
# Each unnecessary copy therefore wastes unnecessary fields in the output dex file.
# Note: usually proguard will help clean this up after the fact, but having too many fields will cause
# dexing to fail, regardless of any later optimisations proguard could later make to bring us back
# under the limit.
# Ideally we would fix our aapt invocations to correctly generate minimal copies of R.java for each
# package, but that seems redundant since gradle builds are able to correctly generate these files.

# If native devices are enabled, add Google Play Services, build their resources
# (no resources) generated/android/support/v4/R.java: .aapt.deps ;
generated/android/support/v7/appcompat/R.java: .aapt.deps ;
# (no resources) generated/android/support/graphics/drawable/animated/R.java: .aapt.deps ;
# (no resources) generated/android/support/graphics/drawable/R.java: .aapt.deps ;
generated/android/support/v7/cardview/R.java: .aapt.deps ;
generated/android/support/design/R.java: .aapt.deps ;
generated/android/support/v7/mediarouter/R.java: .aapt.deps ;
generated/android/support/v7/recyclerview/R.java: .aapt.deps ;
# (no resources) generated/android/support/customtabs/R.java: .aapt.deps ;
# (no resources) generated/android/support/v7/palette/R.java: .aapt.deps ;
generated/com/google/android/gms/R.java: .aapt.deps ;
generated/com/google/android/gms/ads/R.java: .aapt.deps ;
generated/com/google/android/gms/base/R.java: .aapt.deps ;
generated/com/google/android/gms/cast/R.java: .aapt.deps ;
# (no resources) generated/com/google/android/gms/gcm/R.java: .aapt.deps ;
# (no resources) generated/com/google/android/gms/measurement/R.java: .aapt.deps ;

gecko.ap_: .aapt.deps ;
R.txt: .aapt.deps ;

# [Comment 2/3] This tom-foolery provides a target that forces a
# rebuild of gecko.ap_.  This is used during packaging to ensure that
# resources are fresh.  The alternative would be complicated; see
# [Comment 1/3].

gecko-nodeps/R.java: .aapt.nodeps ;
gecko-nodeps.ap_: .aapt.nodeps ;
gecko-nodeps/R.txt: .aapt.nodeps ;

# This ignores the default set of resources ignored by aapt, plus
# files starting with '#'.  (Emacs produces temp files named #temp#.)
# This doesn't actually set the environment variable; it's used as a
# parameter in the aapt invocation below.  Consider updating
# not_android_res_files as well.

ANDROID_AAPT_IGNORE := !.svn:!.git:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~:\#*:*.rej:*.orig

# 1: target file.
# 2: dependencies.
# 3: name of ap_ file to write.
# 4: directory to write R.java into.
# 5: directory to write R.txt into.
# We touch the target file before invoking aapt so that aapt's outputs
# are fresher than the target, preventing a subsequent invocation from
# thinking aapt's outputs are stale.  This is safe because Make
# removes the target file if any recipe command fails.

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 $(ANDROID_EXTRA_PACKAGES),--extra-packages $$(subst $$(NULL) ,:,$$(strip $$(ANDROID_EXTRA_PACKAGES)))) \
		$(if $(ANDROID_EXTRA_RES_DIRS),$$(addprefix -S ,$$(ANDROID_EXTRA_RES_DIRS))) \
		--custom-package org.mozilla.gecko \
		--no-version-vectors \
		-F $(3) \
		-J $(4) \
		--output-text-symbols $(5) \
		--ignore-assets "$$(ANDROID_AAPT_IGNORE)"
endef

# [Comment 3/3] The first of these rules is used during regular
# builds.  The second writes an ap_ file that is only used during
# packaging.  It doesn't write the normal ap_, or R.java, since we
# don't want the packaging step to write anything that would make a
# further no-op build do work.  See also
# toolkit/mozapps/installer/packager.mk.

# .aapt.deps: $(all_resources)
$(eval $(call aapt_command,.aapt.deps,$(all_resources),gecko.ap_,generated/,./))

ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
.aapt.nodeps: FORCE
	cp $(gradle_dir)/app/intermediates/res/resources-automation-debug.ap_ gecko-nodeps.ap_
else
# .aapt.nodeps: $(DEPTH)/mobile/android/base/AndroidManifest.xml FORCE
$(eval $(call aapt_command,.aapt.nodeps,$(DEPTH)/mobile/android/base/AndroidManifest.xml FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/))
endif

# Override the Java settings with some specific android settings
include $(topsrcdir)/config/android-common.mk

update-generated-wrappers:
	@cp $(CURDIR)/GeneratedJNIWrappers.cpp \
	    $(CURDIR)/GeneratedJNIWrappers.h \
	    $(CURDIR)/GeneratedJNINatives.h $(topsrcdir)/widget/android
	@echo Updated generated JNI code

update-fennec-wrappers:
	@cp $(CURDIR)/FennecJNIWrappers.cpp \
	    $(CURDIR)/FennecJNIWrappers.h \
	    $(CURDIR)/FennecJNINatives.h $(topsrcdir)/widget/android/fennec
	@echo Updated Fennec JNI code

.PHONY: update-generated-wrappers

# This target is only used by IDE integrations. It rebuilds resources
# that end up in omni.ja using the equivalent of |mach build faster|,
# does most of the packaging step, and then updates omni.ja in
# place. If you're not using an IDE, you should be using |mach build
# mobile/android && mach package|.
$(ABS_DIST)/fennec/$(OMNIJAR_NAME): FORCE
	$(REPORT_BUILD)
	$(MAKE) -C ../../../faster
	$(MAKE) -C ../installer stage-package
	$(MKDIR) -p $(@D)
	rsync --update $(DIST)/fennec/$(notdir $(OMNIJAR_NAME)) $@
	$(RM) $(DIST)/fennec/$(notdir $(OMNIJAR_NAME))

# Targets built very early during a Gradle build.
gradle-targets: $(foreach f,$(constants_PP_JAVAFILES),$(f))
gradle-targets: $(DEPTH)/mobile/android/base/AndroidManifest.xml
gradle-targets: $(ANDROID_GENERATED_RESFILES)

ifndef MOZILLA_OFFICIAL
# Local developers update omni.ja during their builds.  There's a
# chicken-and-egg problem here.
gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
else
# In automation, omni.ja is built only during packaging.
gradle-omnijar:
endif

.PHONY: gradle-targets gradle-omnijar

# GeneratedJNIWrappers.cpp target also generates
#   GeneratedJNIWrappers.h and GeneratedJNINatives.h
# FennecJNIWrappers.cpp target also generates
#   FennecJNIWrappers.h and FennecJNINatives.h
ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
libs:: GeneratedJNIWrappers.cpp
	@(diff GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp >/dev/null && \
	  diff GeneratedJNIWrappers.h $(topsrcdir)/widget/android/GeneratedJNIWrappers.h >/dev/null && \
	  diff GeneratedJNINatives.h $(topsrcdir)/widget/android/GeneratedJNINatives.h >/dev/null) || \
	 (echo '*****************************************************' && \
	  echo '***   Error: The generated JNI code has changed   ***' && \
	  echo '* To update generated code in the tree, please run  *' && \
	  echo && \
	  echo '  make -C $(CURDIR) update-generated-wrappers' && \
	  echo && \
	  echo '* Repeat the build, and check in any changes.       *' && \
	  echo '*****************************************************' && \
	  exit 1)

libs:: FennecJNIWrappers.cpp
	@(diff FennecJNIWrappers.cpp $(topsrcdir)/widget/android/fennec/FennecJNIWrappers.cpp >/dev/null && \
	  diff FennecJNIWrappers.h $(topsrcdir)/widget/android/fennec/FennecJNIWrappers.h >/dev/null && \
	  diff FennecJNINatives.h $(topsrcdir)/widget/android/fennec/FennecJNINatives.h >/dev/null) || \
	 (echo '*****************************************************' && \
	  echo '***     Error: The Fennec JNI code has changed    ***' && \
	  echo '* To update generated code in the tree, please run  *' && \
	  echo && \
	  echo '  make -C $(CURDIR) update-fennec-wrappers' && \
	  echo && \
	  echo '* Repeat the build, and check in any changes.       *' && \
	  echo '*****************************************************' && \
	  exit 1)
endif

libs:: classes.dex
	$(INSTALL) classes.dex $(FINAL_TARGET)

# Generate Java binder interfaces from AIDL files.
aidl_src_path := $(srcdir)/aidl
aidl_target_path := generated
media_pkg := org/mozilla/gecko/media

$(aidl_target_path)/$(media_pkg)/%.java:$(aidl_src_path)/$(media_pkg)/%.aidl
	@echo "Processing AIDL: $< => $@"
	$(AIDL) -p$(ANDROID_SDK)/framework.aidl -I$(aidl_src_path) -o$(aidl_target_path) $<