Merge "Generate lsdump without sdump"
diff --git a/apps/Development/src/com/android/development/Connectivity.java b/apps/Development/src/com/android/development/Connectivity.java
index 2b62acb..c5d6b5f 100644
--- a/apps/Development/src/com/android/development/Connectivity.java
+++ b/apps/Development/src/com/android/development/Connectivity.java
@@ -47,7 +47,6 @@
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.ServiceManager;
-import android.os.ServiceManagerNative;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.os.Bundle;
diff --git a/build/Android.bp b/build/Android.bp
index 8f80280..7815f39 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -22,7 +22,7 @@
     java_resources: [
         ":notices-for-framework-stubs",
     ],
-    no_standard_libs: true,
+    sdk_version: "none",
     system_modules: "none",
     java_version: "1.8",
     compile_dex: true,
diff --git a/build/sdk-android-arm64-v8a.atree b/build/sdk-android-arm64-v8a.atree
index 56fba15..5cf331b 100644
--- a/build/sdk-android-arm64-v8a.atree
+++ b/build/sdk-android-arm64-v8a.atree
@@ -20,4 +20,4 @@
 ${HOST_OUT}/development/sys-img-${TARGET_CPU_ABI}/images_arm64-v8a_source.properties system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/source.properties
 
 # feature control config file
-development/sys-img/advancedFeatures.ini.arm system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
+device/generic/goldfish/data/etc/advancedFeatures.ini.arm system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
diff --git a/build/sdk-android-armeabi-v7a.atree b/build/sdk-android-armeabi-v7a.atree
index a05229c..2e20dcd 100644
--- a/build/sdk-android-armeabi-v7a.atree
+++ b/build/sdk-android-armeabi-v7a.atree
@@ -24,4 +24,4 @@
 development/sys-img/images_armeabi-v7a_hardware.ini    system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/hardware.ini
 
 # feature control config file
-development/sys-img/advancedFeatures.ini.arm system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
+device/generic/goldfish/data/etc/advancedFeatures.ini.arm system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
diff --git a/build/sdk-android-armeabi.atree b/build/sdk-android-armeabi.atree
index 293ea4c..8ea6e7e 100644
--- a/build/sdk-android-armeabi.atree
+++ b/build/sdk-android-armeabi.atree
@@ -21,4 +21,4 @@
 ${HOST_OUT}/development/sys-img-${TARGET_CPU_ABI}/images_armeabi_source.properties system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/source.properties
 
 # feature control config file
-development/sys-img/advancedFeatures.ini.arm system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
+device/generic/goldfish/data/etc/advancedFeatures.ini.arm system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
diff --git a/build/sdk-android-x86.atree b/build/sdk-android-x86.atree
index 81a0778..da92d9e 100644
--- a/build/sdk-android-x86.atree
+++ b/build/sdk-android-x86.atree
@@ -21,4 +21,4 @@
 ${HOST_OUT}/development/sys-img-${TARGET_CPU_ABI}/images_${TARGET_ARCH}_source.properties system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/source.properties
 
 # feature control config file
-development/sys-img/advancedFeatures.ini system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
+device/generic/goldfish/data/etc/advancedFeatures.ini system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
diff --git a/build/sdk-android-x86_64.atree b/build/sdk-android-x86_64.atree
index 286ffb9..d78bfb4 100644
--- a/build/sdk-android-x86_64.atree
+++ b/build/sdk-android-x86_64.atree
@@ -21,4 +21,4 @@
 ${HOST_OUT}/development/sys-img-${TARGET_CPU_ABI}/images_${TARGET_ARCH}_source.properties system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/source.properties
 
 # feature control config file
-development/sys-img/advancedFeatures.ini system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
+device/generic/goldfish/data/etc/advancedFeatures.ini system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/advancedFeatures.ini
diff --git a/vndk/tools/image-diff-tool/Android.bp b/vndk/tools/image-diff-tool/Android.bp
new file mode 100644
index 0000000..663be36
--- /dev/null
+++ b/vndk/tools/image-diff-tool/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+python_binary_host {
+    name: "system_product_image_diff",
+    main: "diff.py",
+    srcs: [
+        "diff.py",
+    ],
+    version: {
+        py2: {
+            enabled: false,
+        },
+        py3: {
+            enabled: true,
+        },
+    }
+}
diff --git a/vndk/tools/image-diff-tool/OWNERS b/vndk/tools/image-diff-tool/OWNERS
new file mode 100644
index 0000000..d364f8e
--- /dev/null
+++ b/vndk/tools/image-diff-tool/OWNERS
@@ -0,0 +1,2 @@
+jeongik@google.com
+justinyun@google.com
diff --git a/vndk/tools/image-diff-tool/diff.py b/vndk/tools/image-diff-tool/diff.py
new file mode 100644
index 0000000..c2f0884
--- /dev/null
+++ b/vndk/tools/image-diff-tool/diff.py
@@ -0,0 +1,102 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+import sys
+from collections import defaultdict
+from concurrent import futures
+from glob import glob
+from operator import itemgetter
+import hashlib
+import argparse
+
+tpe = futures.ThreadPoolExecutor()
+
+def strip_and_sha1sum(filepath):
+  def silent_call(cmd):
+    return subprocess.call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0
+  objdump = lambda: silent_call(["objdump", "-a", filepath])
+  strip_all = lambda: silent_call(["llvm-strip", "--strip-all", "-keep-section=.ARM.attributes", filepath, "-o", filepath + ".tmp"])
+  remove_build_id = lambda: silent_call(["llvm-strip", "-remove-section=.note.gnu.build-id", filepath + ".tmp", "-o", filepath + ".tmp.no-build-id"])
+
+  def sha1sum(f):
+    with open(f, 'rb') as fin:
+      return hashlib.sha1(fin.read()).hexdigest()
+
+  if objdump():
+    try:
+      if strip_all() and remove_build_id():
+        return sha1sum(filepath + ".tmp.no-build-id")
+      else:
+        return sha1sum(filepath)
+    finally:
+      if os.path.exists(filepath + ".tmp"):
+        os.remove(filepath + ".tmp")
+      if os.path.exists(filepath + ".tmp.no-build-id"):
+        os.remove(filepath + ".tmp.no-build-id")
+  else:
+    return sha1sum(filepath)
+
+
+def main(targets, search_paths):
+  def get_target_name(path):
+    return os.path.basename(os.path.normpath(path))
+  artifact_target_map = defaultdict(list)
+  for target in targets:
+    def valid_path(p):
+      if os.path.isdir(p) or not os.path.exists(p):
+        return False
+      for s in search_paths:
+        if os.path.join(target, s).lower() + os.path.sep in p.lower():
+          return True
+      return False
+    paths = [path for path in glob(os.path.join(
+        target, "**", "*"), recursive=True) if valid_path(path)]
+
+    def run(path):
+      return strip_and_sha1sum(path), path[len(target):]
+    results = map(futures.Future.result, [tpe.submit(run, p) for p in paths])
+
+    for sha1, f in results:
+      basename = os.path.split(os.path.dirname(f))[1] + os.path.basename(f)
+      artifact_target_map[(sha1, basename)].append((get_target_name(target), f))
+
+  def pretty_print(p, ts):
+    assert(len({t for t, _ in ts}) == len(ts))
+    return ";".join({f for _, f in ts}) + ", " + p[0][:10] + ", " + ";".join(map(itemgetter(0), ts)) + "\n"
+  header = "filename, sha1sum, targets\n"
+  common = sorted([pretty_print(p, ts)
+                   for p, ts in artifact_target_map.items() if len(ts) == len(targets)])
+  diff = sorted([pretty_print(p, ts)
+                 for p, ts in artifact_target_map.items() if len(ts) < len(targets)])
+
+  with open("common.csv", 'w') as fout:
+    fout.write(header)
+    fout.writelines(common)
+  with open("diff.csv", 'w') as fout:
+    fout.write(header)
+    fout.writelines(diff)
+
+
+if __name__ == "__main__":
+  parser = argparse.ArgumentParser(prog="system_product_image_diff", usage="system_product_image_diff -t model1 model2 model3 -s system product")
+  parser.add_argument("-t", "--target", nargs='+', required=True)
+  parser.add_argument("-s", "--search_path", nargs='+', required=True)
+
+  args = parser.parse_args()
+  if len(args.target) < 2:
+    parser.error("The number of targets has to be at least two.")
+  main(args.target, args.search_path)