Merge "releasetools: Make rangelib Python 3 compatibile."
diff --git a/core/Makefile b/core/Makefile
index 83021d4..0d83b81 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1113,7 +1113,7 @@
 # $(2) - Plain text output file
 # $(3) - HTML/XML output file
 # $(4) - File title
-# $(5) - Directory to use.  Notice files are all $(4)/src.  Other
+# $(5) - Directory to use.  Notice files are all $(5)/src.  Other
 #		 directories in there will be used for scratch
 # $(6) - Dependencies for the output files
 #
diff --git a/envsetup.sh b/envsetup.sh
index 2fa5660..941c5f7 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -768,218 +768,6 @@
     fi
 }
 
-function m()
-{
-    local T=$(gettop)
-    if [ "$T" ]; then
-        _wrap_build $T/build/soong/soong_ui.bash --make-mode $@
-    else
-        echo "Couldn't locate the top of the tree.  Try setting TOP."
-        return 1
-    fi
-}
-
-function findmakefile()
-{
-    local TOPFILE=build/make/core/envsetup.mk
-    local HERE=$PWD
-    if [ "$1" ]; then
-        \cd $1
-    fi;
-    local T=
-    while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
-        T=`PWD= /bin/pwd`
-        if [ -f "$T/Android.mk" -o -f "$T/Android.bp" ]; then
-            echo $T/Android.mk
-            \cd $HERE
-            return
-        fi
-        \cd ..
-    done
-    \cd $HERE
-    return 1
-}
-
-function mm()
-{
-    local T=$(gettop)
-    # If we're sitting in the root of the build tree, just do a
-    # normal build.
-    if [ -f build/soong/soong_ui.bash ]; then
-        _wrap_build $T/build/soong/soong_ui.bash --make-mode $@
-    else
-        # Find the closest Android.mk file.
-        local M=$(findmakefile)
-        local MODULES=
-        local GET_INSTALL_PATH=
-        local ARGS=
-        # Remove the path to top as the makefilepath needs to be relative
-        local M=`echo $M|sed 's:'$T'/::'`
-        if [ ! "$T" ]; then
-            echo "Couldn't locate the top of the tree.  Try setting TOP."
-            return 1
-        elif [ ! "$M" ]; then
-            echo "Couldn't locate a makefile from the current directory."
-            return 1
-        else
-            local ARG
-            for ARG in $@; do
-                case $ARG in
-                  GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;;
-                esac
-            done
-            if [ -n "$GET_INSTALL_PATH" ]; then
-              MODULES=
-              ARGS=GET-INSTALL-PATH-IN-$(dirname ${M})
-              ARGS=${ARGS//\//-}
-            else
-              MODULES=MODULES-IN-$(dirname ${M})
-              # Convert "/" to "-".
-              MODULES=${MODULES//\//-}
-              ARGS=$@
-            fi
-            if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then
-              MODULES=tidy_only
-            fi
-            ONE_SHOT_MAKEFILE=$M _wrap_build $T/build/soong/soong_ui.bash --make-mode $MODULES $ARGS
-        fi
-    fi
-}
-
-function mmm()
-{
-    local T=$(gettop)
-    if [ "$T" ]; then
-        local MAKEFILE=
-        local MODULES=
-        local MODULES_IN_PATHS=
-        local ARGS=
-        local DIR TO_CHOP
-        local DIR_MODULES
-        local GET_INSTALL_PATH=
-        local GET_INSTALL_PATHS=
-        local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
-        local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
-        for DIR in $DIRS ; do
-            DIR_MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`
-            DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
-            # Remove the leading ./ and trailing / if any exists.
-            DIR=${DIR#./}
-            DIR=${DIR%/}
-            local M
-            if [ "$DIR_MODULES" = "" ]; then
-                M=$(findmakefile $DIR)
-            else
-                # Only check the target directory if a module is specified.
-                if [ -f $DIR/Android.mk -o -f $DIR/Android.bp ]; then
-                    local HERE=$PWD
-                    cd $DIR
-                    M=`PWD= /bin/pwd`
-                    M=$M/Android.mk
-                    cd $HERE
-                fi
-            fi
-            if [ "$M" ]; then
-                # Remove the path to top as the makefilepath needs to be relative
-                local M=`echo $M|sed 's:'$T'/::'`
-                if [ "$DIR_MODULES" = "" ]; then
-                    MODULES_IN_PATHS="$MODULES_IN_PATHS MODULES-IN-$(dirname ${M})"
-                    GET_INSTALL_PATHS="$GET_INSTALL_PATHS GET-INSTALL-PATH-IN-$(dirname ${M})"
-                else
-                    MODULES="$MODULES $DIR_MODULES"
-                fi
-                MAKEFILE="$MAKEFILE $M"
-            else
-                case $DIR in
-                  showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
-                  GET-INSTALL-PATH) GET_INSTALL_PATH=$DIR;;
-                  *) if [ -d $DIR ]; then
-                         echo "No Android.mk in $DIR.";
-                     else
-                         echo "Couldn't locate the directory $DIR";
-                     fi
-                     return 1;;
-                esac
-            fi
-        done
-        if [ -n "$GET_INSTALL_PATH" ]; then
-          ARGS=${GET_INSTALL_PATHS//\//-}
-          MODULES=
-          MODULES_IN_PATHS=
-        fi
-        if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then
-          MODULES=tidy_only
-          MODULES_IN_PATHS=
-        fi
-        # Convert "/" to "-".
-        MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
-        ONE_SHOT_MAKEFILE="$MAKEFILE" _wrap_build $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $MODULES $MODULES_IN_PATHS $ARGS
-    else
-        echo "Couldn't locate the top of the tree.  Try setting TOP."
-        return 1
-    fi
-}
-
-function mma()
-{
-  local T=$(gettop)
-  if [ -f build/soong/soong_ui.bash ]; then
-    _wrap_build $T/build/soong/soong_ui.bash --make-mode $@
-  else
-    if [ ! "$T" ]; then
-      echo "Couldn't locate the top of the tree.  Try setting TOP."
-      return 1
-    fi
-    local M=$(findmakefile || echo $(realpath $PWD)/Android.mk)
-    # Remove the path to top as the makefilepath needs to be relative
-    local M=`echo $M|sed 's:'$T'/::'`
-    local MODULES_IN_PATHS=MODULES-IN-$(dirname ${M})
-    # Convert "/" to "-".
-    MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
-    _wrap_build $T/build/soong/soong_ui.bash --make-mode $@ $MODULES_IN_PATHS
-  fi
-}
-
-function mmma()
-{
-  local T=$(gettop)
-  if [ "$T" ]; then
-    local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
-    local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
-    local MY_PWD=`PWD= /bin/pwd`
-    if [ "$MY_PWD" = "$T" ]; then
-      MY_PWD=
-    else
-      MY_PWD=`echo $MY_PWD|sed 's:'$T'/::'`
-    fi
-    local DIR=
-    local MODULES_IN_PATHS=
-    local ARGS=
-    for DIR in $DIRS ; do
-      if [ -d $DIR ]; then
-        # Remove the leading ./ and trailing / if any exists.
-        DIR=${DIR#./}
-        DIR=${DIR%/}
-        if [ "$MY_PWD" != "" ]; then
-          DIR=$MY_PWD/$DIR
-        fi
-        MODULES_IN_PATHS="$MODULES_IN_PATHS MODULES-IN-$DIR"
-      else
-        case $DIR in
-          showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
-          *) echo "Couldn't find directory $DIR"; return 1;;
-        esac
-      fi
-    done
-    # Convert "/" to "-".
-    MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
-    _wrap_build $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $ARGS $MODULES_IN_PATHS
-  else
-    echo "Couldn't locate the top of the tree.  Try setting TOP."
-    return 1
-  fi
-}
-
 function croot()
 {
     local T=$(gettop)
@@ -1665,6 +1453,41 @@
     return $ret
 }
 
+function _trigger_build()
+(
+    local -r bc="$1"; shift
+    if T="$(gettop)"; then
+      _wrap_build "$T/build/soong/soong_ui.bash" --build-mode --${bc} --dir="$(pwd)" "$@"
+    else
+      echo "Couldn't locate the top of the tree. Try setting TOP."
+    fi
+)
+
+function m()
+(
+    _trigger_build "all-modules" "$@"
+)
+
+function mm()
+(
+    _trigger_build "modules-in-a-dir-no-deps" "$@"
+)
+
+function mmm()
+(
+    _trigger_build "modules-in-dirs-no-deps" "$@"
+)
+
+function mma()
+(
+    _trigger_build "modules-in-a-dir" "$@"
+)
+
+function mmma()
+(
+    _trigger_build "modules-in-dirs" "$@"
+)
+
 function make()
 {
     _wrap_build $(get_make_command "$@") "$@"
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index 96fd07b..702ef3c 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -50,6 +50,9 @@
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
 
+# Setup a vendor image to let PRODUCT_PROPERTY_OVERRIDES does not affect GSI
+BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
+
 # Disable 64 bit mediadrmserver
 TARGET_ENABLE_MEDIADRM_64 :=
 
diff --git a/target/product/gsi_common.mk b/target/product/gsi_common.mk
index 064cf03..7578f92 100644
--- a/target/product/gsi_common.mk
+++ b/target/product/gsi_common.mk
@@ -29,9 +29,9 @@
     ro.apex.updatable=false
 
 # Additional settings used in all AOSP builds
-PRODUCT_PROPERTY_OVERRIDES += \
+PRODUCT_PRODUCT_PROPERTIES += \
     ro.config.ringtone=Ring_Synth_04.ogg \
-    ro.config.notification_sound=pixiedust.ogg
+    ro.config.notification_sound=pixiedust.ogg \
 
 # The mainline checking whitelist, should be clean up
 PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 8dcbd0b..7cff831 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -863,7 +863,7 @@
     A Image object. If it is a sparse image and reset_file_map is False, the
     image will have file_map info loaded.
   """
-  if info_dict == None:
+  if info_dict is None:
     info_dict = LoadInfoDict(input_zip)
 
   is_sparse = info_dict.get("extfs_sparse_flag")
@@ -1568,6 +1568,15 @@
       perms = 0o100644
   else:
     zinfo = zinfo_or_arcname
+    # Python 2 and 3 behave differently when calling ZipFile.writestr() with
+    # zinfo.external_attr being 0. Python 3 uses `0o600 << 16` as the value for
+    # such a case (since
+    # https://github.com/python/cpython/commit/18ee29d0b870caddc0806916ca2c823254f1a1f9),
+    # which seems to make more sense. Otherwise the entry will have 0o000 as the
+    # permission bits. We follow the logic in Python 3 to get consistent
+    # behavior between using the two versions.
+    if not zinfo.external_attr:
+      zinfo.external_attr = 0o600 << 16
 
   # If compress_type is given, it overrides the value in zinfo.
   if compress_type is not None:
@@ -1600,7 +1609,7 @@
   Raises:
     AssertionError: In case of non-zero return from 'zip'.
   """
-  if isinstance(entries, basestring):
+  if isinstance(entries, str):
     entries = [entries]
   cmd = ["zip", "-d", zip_filename] + entries
   RunAndCheckOutput(cmd)
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 7ce361b..11ac9f5 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -41,7 +41,7 @@
   # Generate a long string with holes, e.g. 'xyz\x00abc\x00...'.
   for _ in range(0, size, step_size):
     yield os.urandom(block_size)
-    yield '\0' * (step_size - block_size)
+    yield b'\0' * (step_size - block_size)
 
 
 class CommonZipTest(test_utils.ReleaseToolsTestCase):
@@ -72,7 +72,7 @@
     # Verify the zip contents.
     entry = zip_file.open(arcname)
     sha1_hash = sha1()
-    for chunk in iter(lambda: entry.read(4 * MiB), ''):
+    for chunk in iter(lambda: entry.read(4 * MiB), b''):
       sha1_hash.update(chunk)
     self.assertEqual(expected_hash, sha1_hash.hexdigest())
     self.assertIsNone(zip_file.testzip())
@@ -97,8 +97,8 @@
     try:
       sha1_hash = sha1()
       for data in contents:
-        sha1_hash.update(data)
-        test_file.write(data)
+        sha1_hash.update(bytes(data))
+        test_file.write(bytes(data))
       test_file.close()
 
       expected_stat = os.stat(test_file_name)
@@ -136,8 +136,11 @@
         expected_mode = extra_args.get("perms", 0o644)
       else:
         arcname = zinfo_or_arcname.filename
-        expected_mode = extra_args.get("perms",
-                                       zinfo_or_arcname.external_attr >> 16)
+        if zinfo_or_arcname.external_attr:
+          zinfo_perms = zinfo_or_arcname.external_attr >> 16
+        else:
+          zinfo_perms = 0o600
+        expected_mode = extra_args.get("perms", zinfo_perms)
 
       common.ZipWriteStr(zip_file, zinfo_or_arcname, contents, **extra_args)
       common.ZipClose(zip_file)
@@ -262,6 +265,10 @@
         "perms": 0o600,
         "compress_type": zipfile.ZIP_STORED,
     })
+    self._test_ZipWriteStr(zinfo, random_string, {
+        "perms": 0o000,
+        "compress_type": zipfile.ZIP_STORED,
+    })
 
   def test_ZipWriteStr_large_file(self):
     # zipfile.writestr() doesn't work when the str size is over 2GiB even with
@@ -274,9 +281,9 @@
     })
 
   def test_ZipWriteStr_resets_ZIP64_LIMIT(self):
-    self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, "foo", "")
+    self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, 'foo', b'')
     zinfo = zipfile.ZipInfo(filename="foo")
-    self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, zinfo, "")
+    self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, zinfo, b'')
 
   def test_bug21309935(self):
     zip_file = tempfile.NamedTemporaryFile(delete=False)