Update Android framework makefile to build static and shared libs

Also use static lib for testing tools and expose includes needed for
other framework testing tools to statically link in Skia.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1696483002

Review URL: https://codereview.chromium.org/1696483002
diff --git a/gyp/bench.gyp b/gyp/bench.gyp
index 7c5d6df..e9908b5 100644
--- a/gyp/bench.gyp
+++ b/gyp/bench.gyp
@@ -31,10 +31,8 @@
       'conditions': [
         ['skia_android_framework', {
           'libraries': [
-            '-lskia',
-            '-landroid',
+            'skia_static.a',
             '-lhwui',
-            '-lutils',
           ],
           'include_dirs': [
             '../../../frameworks/base/libs/hwui/',
diff --git a/gyp/dm.gyp b/gyp/dm.gyp
index a05d079..831cde7 100644
--- a/gyp/dm.gyp
+++ b/gyp/dm.gyp
@@ -15,10 +15,8 @@
         'conditions': [
           ['skia_android_framework', {
               'libraries': [
-                  '-lskia',
-                  '-landroid',
+                  'skia_static.a',
                   '-lhwui',
-                  '-lutils',
               ],
               'include_dirs': [
                   '../../../frameworks/base/libs/hwui/',
diff --git a/platform_tools/android/bin/gyp_to_android.py b/platform_tools/android/bin/gyp_to_android.py
index 9ce330c..4b9e7ec 100755
--- a/platform_tools/android/bin/gyp_to_android.py
+++ b/platform_tools/android/bin/gyp_to_android.py
@@ -195,6 +195,9 @@
     makefile_writer.write_android_mk(target_dir=target_dir,
         common=common, deviations_from_common=deviations_from_common)
 
+    makefile_writer.write_static_deps_mk(target_dir=target_dir,
+        common=common, deviations_from_common=deviations_from_common)
+
   finally:
     shutil.rmtree(tmp_folder)
 
diff --git a/platform_tools/android/gyp_gen/makefile_writer.py b/platform_tools/android/gyp_gen/makefile_writer.py
index 93af4d2..58fb3a8 100644
--- a/platform_tools/android/gyp_gen/makefile_writer.py
+++ b/platform_tools/android/gyp_gen/makefile_writer.py
@@ -108,7 +108,6 @@
 # NOTE: If neither SK_DEBUG or SK_RELEASE are defined then Skia checks NDEBUG to
 #       determine which build type to use.
 ###############################################################################
-
 """
 )
 
@@ -126,6 +125,45 @@
 """
 )
 
+STATIC_HEADER = (
+"""
+###############################################################################
+# STATIC LIBRARY
+#
+# This target is only to be used internally for only one of two purposes...
+#  (1) statically linking into testing frameworks
+#  (2) as an inclusion target for the libskia.so shared library
+###############################################################################
+
+"""
+)
+
+SHARED_HEADER = (
+"""
+###############################################################################
+# SHARED LIBRARY
+###############################################################################
+
+"""
+)
+
+STATIC_DEPS_INFO = (
+"""
+###############################################################################
+# 
+# This file contains the shared and static dependencies needed by any target 
+# that attempts to statically link Skia (i.e. libskia_static build target).
+#
+# This is a workaround for the fact that the build system does not add these
+# transitive dependencies when it attempts to link libskia_static into another
+# library.
+#
+###############################################################################
+"""
+)
+
+CLEAR_VARS = ("""include $(CLEAR_VARS)\n""")
+LOCAL_PATH = ("""LOCAL_PATH:= $(call my-dir)\n""")
 
 class VarsDictData(object):
   """Helper class to keep a VarsDict along with a name and optional condition.
@@ -144,21 +182,42 @@
     self.condition = condition
     self.name = name
 
-def write_local_path(f):
-  """Add the LOCAL_PATH line to the makefile.
+def write_static_deps_mk(target_dir, common, deviations_from_common):
+  """Given all the variables, write the final make file.
 
   Args:
-    f: File open for writing.
+    target_dir: The full path to the directory to write skia_static_includes.mk,
+      or None to use the current working directory.
+    common: VarsDict holding variables definitions common to all
+      configurations.
+    deviations_from_common: List of VarsDictData, one for each possible
+      configuration. VarsDictData.name will be appended to each key before
+      writing it to the makefile. VarsDictData.condition, if not None, will be
+      written to the makefile as a condition to determine whether to include
+      VarsDictData.vars_dict.
   """
-  f.write('LOCAL_PATH:= $(call my-dir)\n')
+  target_file = 'skia_static_deps.mk'
+  if target_dir:
+    target_file = os.path.join(target_dir, target_file)
+  with open(target_file, 'w') as f:
+    f.write(AUTOGEN_WARNING)
+    f.write(STATIC_DEPS_INFO)
 
-def write_clear_vars(f):
-  """Add the CLEAR_VARS line to the makefile.
+    for data in deviations_from_common:
+      var_dict_shared = data.vars_dict['LOCAL_SHARED_LIBRARIES']
+      var_dict_static = data.vars_dict['LOCAL_STATIC_LIBRARIES']
+      if data.condition and (var_dict_shared or var_dict_static):
+        f.write('ifeq ($(%s), true)\n' % data.condition)
+      write_group(f, 'LOCAL_SHARED_LIBRARIES', var_dict_shared, True)
+      write_group(f, 'LOCAL_STATIC_LIBRARIES', var_dict_static, True)
+      if data.condition and (var_dict_shared or var_dict_static):
+        f.write('endif\n\n')
 
-  Args:
-    f: File open for writing.
-  """
-  f.write('include $(CLEAR_VARS)\n')
+    write_group(f, 'LOCAL_SHARED_LIBRARIES', common['LOCAL_SHARED_LIBRARIES'],
+                True)
+    write_group(f, 'LOCAL_STATIC_LIBRARIES', common['LOCAL_STATIC_LIBRARIES'],
+                True)
+
 
 def write_android_mk(target_dir, common, deviations_from_common):
   """Given all the variables, write the final make file.
@@ -180,11 +239,12 @@
   with open(target_file, 'w') as f:
     f.write(AUTOGEN_WARNING)
     f.write('BASE_PATH := $(call my-dir)\n')
-    write_local_path(f)
+    f.write(LOCAL_PATH)
 
     f.write(DEBUGGING_HELP)
 
-    write_clear_vars(f)
+    f.write(STATIC_HEADER)
+    f.write(CLEAR_VARS)
 
     # need flags to enable feedback driven optimization (FDO) when requested
     # by the build system.
@@ -199,9 +259,11 @@
     f.write('# used for testing\n')
     f.write('#LOCAL_CFLAGS += -g -O0\n\n')
 
-    f.write('ifeq ($(NO_FALLBACK_FONT),true)\n')
-    f.write('\tLOCAL_CFLAGS += -DNO_FALLBACK_FONT\n')
-    f.write('endif\n\n')
+    # update the provided LOCAL_MODULE with a _static suffix
+    local_module = common['LOCAL_MODULE'][0]
+    static_local_module = local_module + '_static'
+    common['LOCAL_MODULE'].reset()
+    common['LOCAL_MODULE'].add(static_local_module)
 
     write_local_vars(f, common, False, None)
 
@@ -212,6 +274,18 @@
       if data.condition:
         f.write('endif\n\n')
 
+    f.write('LOCAL_MODULE_CLASS := STATIC_LIBRARIES\n')
+    f.write('include $(BUILD_STATIC_LIBRARY)\n\n')
+
+    f.write(SHARED_HEADER)
+    f.write(CLEAR_VARS)
+    f.write('LOCAL_MODULE_CLASS := SHARED_LIBRARIES\n')
+    f.write('LOCAL_MODULE := %s\n' % local_module)
+    f.write('LOCAL_WHOLE_STATIC_LIBRARIES := %s\n' % static_local_module)
+    write_group(f, 'LOCAL_EXPORT_C_INCLUDE_DIRS',
+                common['LOCAL_EXPORT_C_INCLUDE_DIRS'], False)
+    f.write('include $(BASE_PATH)/skia_static_deps.mk\n')
     f.write('include $(BUILD_SHARED_LIBRARY)\n')
+
     f.write(SKIA_TOOLS)
 
diff --git a/platform_tools/android/gyp_gen/tool_makefile_writer.py b/platform_tools/android/gyp_gen/tool_makefile_writer.py
index 2fef110..4c1174f 100644
--- a/platform_tools/android/gyp_gen/tool_makefile_writer.py
+++ b/platform_tools/android/gyp_gen/tool_makefile_writer.py
@@ -35,12 +35,13 @@
   with open(target_file, 'w') as f:
     f.write(makefile_writer.AUTOGEN_WARNING)
 
-    makefile_writer.write_local_path(f)
-    makefile_writer.write_clear_vars(f)
+    f.write(makefile_writer.LOCAL_PATH)
+    f.write(makefile_writer.CLEAR_VARS)
 
     makefile_writer.write_local_vars(f, var_dict, False, None)
 
     f.write(SKIA_RESOURCES)
+    f.write('include $(LOCAL_PATH)/../skia_static_deps.mk\n')
     f.write('include $(BUILD_NATIVE_TEST)\n')
 
 
diff --git a/platform_tools/android/tests/expectations/Android.mk b/platform_tools/android/tests/expectations/Android.mk
index c7ac190..861784a 100644
--- a/platform_tools/android/tests/expectations/Android.mk
+++ b/platform_tools/android/tests/expectations/Android.mk
@@ -34,6 +34,14 @@
 #       determine which build type to use.
 ###############################################################################
 
+###############################################################################
+# STATIC LIBRARY
+#
+# This target is only to be used internally for only one of two purposes...
+#  (1) statically linking into testing frameworks
+#  (2) as an inclusion target for the libskia.so shared library
+###############################################################################
+
 include $(CLEAR_VARS)
 LOCAL_FDO_SUPPORT := true
 ifneq ($(strip $(TARGET_FDO_CFLAGS)),)
@@ -45,10 +53,6 @@
 # used for testing
 #LOCAL_CFLAGS += -g -O0
 
-ifeq ($(NO_FALLBACK_FONT),true)
-	LOCAL_CFLAGS += -DNO_FALLBACK_FONT
-endif
-
 LOCAL_CFLAGS += \
 	local_cflags
 
@@ -77,7 +81,7 @@
 	local_module_tags
 
 LOCAL_MODULE := \
-	local_module
+	local_module_static
 
 ifeq ($(COND), true)
 LOCAL_CFLAGS_foo += \
@@ -142,6 +146,22 @@
 LOCAL_MODULE_bar += \
 	local_module_bar
 
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+include $(BUILD_STATIC_LIBRARY)
+
+
+###############################################################################
+# SHARED LIBRARY
+###############################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE := local_module
+LOCAL_WHOLE_STATIC_LIBRARIES := local_module_static
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+	local_export_c_include_dirs
+
+include $(BASE_PATH)/skia_static_deps.mk
 include $(BUILD_SHARED_LIBRARY)
 
 #############################################################
diff --git a/platform_tools/android/tests/expectations/skia_static_deps.mk b/platform_tools/android/tests/expectations/skia_static_deps.mk
new file mode 100644
index 0000000..e7cd246
--- /dev/null
+++ b/platform_tools/android/tests/expectations/skia_static_deps.mk
@@ -0,0 +1,41 @@
+
+###############################################################################
+#
+# THIS FILE IS AUTOGENERATED BY GYP_TO_ANDROID.PY. DO NOT EDIT.
+#
+# For bugs, please contact scroggo@google.com or djsollen@google.com
+#
+###############################################################################
+
+
+###############################################################################
+# 
+# This file contains the shared and static dependencies needed by any target 
+# that attempts to statically link Skia (i.e. libskia_static build target).
+#
+# This is a workaround for the fact that the build system does not add these
+# transitive dependencies when it attempts to link libskia_static into another
+# library.
+#
+###############################################################################
+ifeq ($(COND), true)
+LOCAL_SHARED_LIBRARIES += \
+	local_shared_libraries_foo
+
+LOCAL_STATIC_LIBRARIES += \
+	local_static_libraries_foo
+
+endif
+
+LOCAL_SHARED_LIBRARIES += \
+	local_shared_libraries_bar
+
+LOCAL_STATIC_LIBRARIES += \
+	local_static_libraries_bar
+
+LOCAL_SHARED_LIBRARIES += \
+	local_shared_libraries
+
+LOCAL_STATIC_LIBRARIES += \
+	local_static_libraries
+
diff --git a/platform_tools/android/tests/expectations/tool/Android.mk b/platform_tools/android/tests/expectations/tool/Android.mk
index b5ecbe4..bd13b71 100644
--- a/platform_tools/android/tests/expectations/tool/Android.mk
+++ b/platform_tools/android/tests/expectations/tool/Android.mk
@@ -45,4 +45,5 @@
 # subdirectory in the DATA folder that points to the top level skia resources...
 #  i.e. external/skia/DATA/skia_resources --> ../resources
 LOCAL_PICKUP_FILES := $(LOCAL_PATH)/../DATA
+include $(LOCAL_PATH)/../skia_static_deps.mk
 include $(BUILD_NATIVE_TEST)
diff --git a/platform_tools/android/tests/makefile_writer_tests.py b/platform_tools/android/tests/makefile_writer_tests.py
index 6b72657..42ab4bd 100644
--- a/platform_tools/android/tests/makefile_writer_tests.py
+++ b/platform_tools/android/tests/makefile_writer_tests.py
@@ -111,6 +111,25 @@
                                    common=common_vars_dict,
                                    deviations_from_common=deviations)
 
+def generate_dummy_static_deps_makefile(target_dir):
+  """Create a dummy makefile that prints out the static dependencies.
+
+  Use dummy values unrelated to any gyp files. Its output should remain the
+  same unless/until makefile_writer.write_static_deps_mk changes.
+
+  Args:
+    target_dir: directory in which to write the resulting file
+  """
+  common_vars_dict = generate_dummy_vars_dict(None)
+
+  deviation_params = [('foo', 'COND'), ('bar', None)]
+  deviations = [generate_dummy_vars_dict_data(name, condition)
+                for (name, condition) in deviation_params]
+
+  makefile_writer.write_static_deps_mk(target_dir=target_dir,
+                                       common=common_vars_dict,
+                                       deviations_from_common=deviations)
+
 def generate_dummy_tool_makefile(target_dir):
   """Create a dummy makefile for a tool.
 
@@ -181,6 +200,14 @@
 
     shutil.rmtree(outdir)
 
+  def test_include_static_deps_writer(self):
+    outdir = tempfile.mkdtemp()
+    generate_dummy_static_deps_makefile(outdir)
+
+    filename = test_variables.STATIC_DEPS_MK
+    utils.compare_to_expectation(os.path.join(outdir, filename),
+                                 filename, self.assertTrue, REBASELINE_MSG)
+
   def test_tool_writer(self):
     outdir = tempfile.mkdtemp()
     tool_dir = os.path.join(outdir, TOOL_DIR)
@@ -208,6 +235,7 @@
     with open(os.path.join(utils.EXPECTATIONS_DIR, filename), 'w') as f:
       makefile_writer.write_local_vars(f, vars_dict, append, name)
 
+  generate_dummy_static_deps_makefile(utils.EXPECTATIONS_DIR)
   generate_dummy_tool_makefile(os.path.join(utils.EXPECTATIONS_DIR, TOOL_DIR))
 
 
diff --git a/platform_tools/android/tests/test_variables.py b/platform_tools/android/tests/test_variables.py
index cc0bf1c..05e61ee 100644
--- a/platform_tools/android/tests/test_variables.py
+++ b/platform_tools/android/tests/test_variables.py
@@ -22,3 +22,4 @@
 GYP_GEN_DIR = os.path.join(ANDROID_DIR, 'gyp_gen')
 
 ANDROID_MK = 'Android.mk'
+STATIC_DEPS_MK = 'skia_static_deps.mk'