DO NOT MERGE - Merge pi-dev@5234907 into stage-aosp-master

Bug: 120848293
Change-Id: I42ca5fc87e33de6757f646f59ac3eeeaae7b7992
diff --git a/Android.bp b/Android.bp
index f161d8f..b6dc00e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -25,8 +25,7 @@
         "-Wstrict-prototypes",
         "-DPy_BUILD_CORE",
         "-Werror",
-        "-Wno-error=invalid-source-encoding",
-        "-Wno-error=macro-redefined",
+        "-Wno-invalid-source-encoding",
         "-Wno-int-conversion",
         "-Wno-missing-field-initializers",
         "-Wno-null-pointer-arithmetic",
@@ -212,21 +211,53 @@
     ],
 }
 
-cc_binary {
-    name: "py2-launcher",
+cc_defaults {
+    name: "py2-launcher-defaults",
     defaults: ["py2-interp-defaults"],
     cflags: [
         "-DVERSION=\"2.7\"",
         "-DVPATH=\"\"",
         "-DPREFIX=\"\"",
         "-DEXEC_PREFIX=\"\"",
-        "-DPYTHONPATH=\"\"",
+        "-DPYTHONPATH=\"..:\"",
+        "-DANDROID_SKIP_ZIP_PATH",
+        "-DANDROID_SKIP_EXEC_PREFIX_PATH",
+        "-DANDROID_LIB_PYTHON_PATH=\"internal/stdlib\"",
         "-DDATE=\"Dec 31 1969\"",
         "-DTIME=\"23:59:59\"",
     ],
+    static_libs: [
+        "libbase",
+        "libcrypto",
+        "libexpat",
+        "libssl",
+        "libz",
+    ],
+    target: {
+        linux_glibc_x86_64: {
+            host_ldlibs: ["-lutil"],
+        },
+        darwin: {
+            host_ldlibs: [
+                "-framework SystemConfiguration",
+                "-framework CoreFoundation",
+            ],
+        },
+        host: {
+            static_libs: ["libsqlite"],
+        },
+        // Use shared libsqlite for device side, otherwise
+        // the executable size will be really huge.
+        android: {
+            shared_libs: ["libsqlite"],
+        },
+    },
+}
+
+cc_library_static {
+    name: "py2-launcher-lib",
+    defaults: ["py2-launcher-defaults"],
     srcs: [
-        "Launcher/launcher_main.cpp",
-        "Launcher/launcher_internal.cpp",
         "Modules/gcmodule.c",
         "Modules/getpath.c",
         "Modules/config.c",
@@ -242,13 +273,10 @@
         "Modules/_weakref.c",
         "Modules/zipimport.c",
         "Modules/symtablemodule.c",
-    ],
-    local_include_dirs: [
-        "Launcher",
+        "Modules/main.c",
     ],
     // NOTE: Please update Modules/config.c if new lib get added in the static_libs.
-    static_libs: [
-        "libbase",
+    whole_static_libs: [
         // Be careful the order of these three static libraries below due to
         // missing symbols issues.
         "py2-interp-object",
@@ -308,29 +336,39 @@
         "py2-c-module-_sqlite3",
         "py2-c-module-_ctypes_test",
         "py2-c-module-_ctypes",
-        "libcrypto",
-        "libexpat",
-        "libssl",
-        "libz",
     ],
     target: {
-        linux_glibc_x86_64: {
-            host_ldlibs: ["-lutil"],
-            static_libs: [
-                "libsqlite",
-            ],
+        darwin: {
+            whole_static_libs: ["py2-c-module-_scproxy"],
         },
-        darwin_x86_64: {
-            static_libs: [
-                "libsqlite",
-            ],
+    },
+}
+
+cc_binary {
+    name: "py2-launcher",
+    defaults: ["py2-launcher-defaults"],
+    srcs: ["Launcher/launcher_main.cpp"],
+    static_libs: ["py2-launcher-lib"],
+}
+
+cc_binary {
+    name: "py2-launcher-autorun",
+    defaults: ["py2-launcher-defaults"],
+    srcs: ["Launcher/launcher_main.cpp"],
+    static_libs: ["py2-launcher-lib"],
+    cflags: ["-DANDROID_AUTORUN"],
+}
+
+python_binary_host {
+    name: "py2-cmd",
+    autorun: false,
+    version: {
+        py2: {
+            enabled: true,
+            embedded_launcher: true,
         },
-        // Use shared libsqlite for device side, otherwise
-        // the executable size will be really huge.
-        android: {
-            shared_libs: [
-                "libsqlite",
-            ],
+        py3: {
+            enabled: false,
         },
     },
 }
@@ -809,7 +847,7 @@
         android: {
             shared_libs: [
                 "libsqlite",
-            ]
+            ],
         },
     },
 }
@@ -866,7 +904,7 @@
                 "Modules/_ctypes/libffi/src/arm/ffi.c",
                 "Modules/_ctypes/libffi/src/arm/sysv.S",
                 "Modules/_ctypes/libffi/src/arm/trampoline.S",
-            ]
+            ],
         },
         arm64: {
             // arithmetic on a pointer in _ctypes/libffi/src/aarch64/ffi.c
@@ -878,7 +916,7 @@
             srcs: [
                 "Modules/_ctypes/libffi/src/aarch64/ffi.c",
                 "Modules/_ctypes/libffi/src/aarch64/sysv.S",
-            ]
+            ],
         },
     },
     target: {
@@ -910,3 +948,14 @@
         },
     },
 }
+
+cc_library_host_static {
+    name: "py2-c-module-_scproxy",
+    defaults: ["py2-interp-defaults"],
+    srcs: ["Mac/Modules/_scproxy.c"],
+    target: {
+        linux: {
+            enabled: false,
+        },
+    },
+}
diff --git a/Launcher/launcher_internal.cpp b/Launcher/launcher_internal.cpp
deleted file mode 100644
index 7d5b25a..0000000
--- a/Launcher/launcher_internal.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// 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.
-
-#include "launcher_internal.h"
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-extern "C" {
-// Cpython built-in C functions.
-/*
-   read_directory(archive) -> files dict (new reference)
-
-   Given a path to a Zip archive, build a dict, mapping file names
-   (local to the archive, using SEP as a separator) to toc entries.
-*/
-PyObject *read_directory(const char *archive);
-
-/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
-   data as a new reference. */
-PyObject *get_data(const char *archive, PyObject *toc_entry);
-}
-
-namespace android {
-namespace cpython2 {
-namespace python_launcher {
-namespace internal {
-
-int RunModule(const char *module, int set_argv0) {
-  PyObject *runpy, *runmodule, *runargs, *result;
-  runpy = PyImport_ImportModule("runpy");
-  if (runpy == NULL) {
-    fprintf(stderr, "Could not import runpy module\n");
-    return -1;
-  }
-  runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
-  if (runmodule == NULL) {
-    fprintf(stderr, "Could not access runpy._run_module_as_main\n");
-    Py_DECREF(runpy);
-    return -1;
-  }
-  runargs = Py_BuildValue("(si)", module, set_argv0);
-  if (runargs == NULL) {
-    fprintf(stderr,
-            "Could not create arguments for runpy._run_module_as_main\n");
-    Py_DECREF(runpy);
-    Py_DECREF(runmodule);
-    return -1;
-  }
-  result = PyObject_Call(runmodule, runargs, NULL);
-  if (result == NULL) {
-    PyErr_Print();
-  }
-  Py_DECREF(runpy);
-  Py_DECREF(runmodule);
-  Py_DECREF(runargs);
-  if (result == NULL) {
-    return -1;
-  }
-  Py_DECREF(result);
-  return 0;
-}
-
-std::string GetEntryPointFilePath(const char *launcher_path) {
-  PyObject *files;
-  files = read_directory(launcher_path);
-  if (files == NULL) {
-    return std::string();
-  }
-  PyObject *toc_entry;
-  // Return value: Borrowed reference.
-  toc_entry = PyDict_GetItemString(files, ENTRYPOINT_FILE);
-  if (toc_entry == NULL) {
-    Py_DECREF(files);
-    return std::string();
-  }
-  PyObject *py_data;
-  py_data = get_data(launcher_path, toc_entry);
-  if (py_data == NULL) {
-    Py_DECREF(files);
-    return std::string();
-  }
-  // PyString_AsString returns a NUL-terminated representation of the "py_data",
-  // "data" must not be modified in any way. And it must not be deallocated.
-  char *data = PyString_AsString(py_data);
-  if (data == NULL) {
-    Py_DECREF(py_data);
-    Py_DECREF(files);
-    return std::string();
-  }
-
-  char *res = strdup(data); /* deep copy of data */
-  Py_DECREF(py_data);
-  Py_DECREF(files);
-
-  return std::string(res);
-}
-
-int RunModuleNameFromEntryPoint(const char *launcher_path, std::string entrypoint) {
-  if (entrypoint.empty()) {
-    return -1;
-  }
-  // Has to pass to free to avoid a memory leak after use.
-  char *arr = strdup(entrypoint.c_str());
-
-  if (AddPathToPythonSysPath(launcher_path) < 0) {
-    free(arr);
-    return -1;
-  }
-  int ret =  RunModule(arr, 0);
-  free(arr);
-  return ret;
-}
-
-int AddPathToPythonSysPath(const char *path) {
-  if (path == NULL) {
-    return -1;
-  }
-  PyObject *py_path;
-  py_path = PyString_FromString(path);
-  if (py_path == NULL) {
-    return -1;
-  }
-  PyObject *sys_path;
-  // Return value: Borrowed reference.
-  sys_path = PySys_GetObject(const_cast<char*>("path"));
-  if (sys_path == NULL) {
-    Py_DECREF(py_path);
-    return -1;
-  }
-  PyList_Insert(sys_path, 0, py_path);
-  Py_DECREF(py_path);
-  return 0;
-}
-
-int RunMainFromImporter(const char *launcher_path) {
-  PyObject *py_launcher_path, *importer;
-  py_launcher_path = PyString_FromString(launcher_path);
-  if (py_launcher_path == NULL) {
-    return -1;
-  }
-  importer = PyImport_GetImporter(py_launcher_path);
-  if (importer == NULL) {
-    Py_DECREF(py_launcher_path);
-    return -1;
-  }
-  if (importer != Py_None && importer->ob_type != &PyNullImporter_Type) {
-    /* Launcher path is usable as an import source, so
-       put it in sys.path[0] and import __main__ */
-    if (AddPathToPythonSysPath(launcher_path) < 0) {
-      Py_DECREF(importer);
-      Py_DECREF(py_launcher_path);
-      return -1;
-    }
-  }
-  Py_DECREF(importer);
-  Py_DECREF(py_launcher_path);
-  return RunModule("__main__", 0);
-}
-}  // namespace internal
-
-int RunEntryPointOrMainModule(const char *launcher_path) {
-  std::string entrypoint = internal::GetEntryPointFilePath(launcher_path);
-  if (entrypoint.empty()) {
-    // If entry point can not be found or can not be executed, we try to
-    // run __main__.py within the .par file.
-    fprintf(stderr, "Cannot find valid entry point to execute par file!\n");
-    fprintf(stdout, "Start trying to run __main__ module within par file.\n");
-    return internal::RunMainFromImporter(launcher_path);
-  }
-  return internal::RunModuleNameFromEntryPoint(launcher_path, entrypoint);
-}
-}  // namespace python_launcher
-}  // namespace cpython2
-}  // namespace android
diff --git a/Launcher/launcher_internal.h b/Launcher/launcher_internal.h
deleted file mode 100644
index aa5f2dd..0000000
--- a/Launcher/launcher_internal.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// 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.
-
-#ifndef ANDROID_CPYTHON2_PYTHON_LAUNCHER_INTERNAL_H
-#define ANDROID_CPYTHON2_PYTHON_LAUNCHER_INTERNAL_H
-
-#include <Python.h>
-
-#include <string>
-
-namespace android {
-namespace cpython2 {
-namespace python_launcher {
-
-namespace internal{
-#define ENTRYPOINT_FILE "entry_point.txt"
-
-// Use "runpy" module to locate and run Python script using Python module
-// namespace rather than the filesystem.
-// The caller owns "module" pointer, which cannot be NULL.
-int RunModule(const char *module, int set_argv0);
-
-// Get valid entrypoint file path.
-// The caller owns "launcher_path" pointer, which cannot be NULL.
-// Return non-empty string as success. Otherwise, return empty string.
-std::string GetEntryPointFilePath(const char *launcher_path);
-
-// Run the Python script embedded in ENTRYPOINT_FILE.
-// The caller owns "launcher_path" pointer, which cannot be NULL.
-int RunModuleNameFromEntryPoint(const char *launcher_path, std::string entrypoint);
-
-// Add path to Python sys.path list.
-// The caller owns "path" pointer, which cannot be NULL.
-int AddPathToPythonSysPath(const char *path);
-
-// Run __main__ module within the hermetic .par file.
-// The caller owns "launcher_path" pointer, which cannot be NULL.
-// Return 0 as success. Otherwise, return -1.
-int RunMainFromImporter(const char *launcher_path);
-}  // namespace internal
-
-// Try to run the Python script embedded in ENTRYPOINT_FILE. Otherwise,
-// run __main__ module as fallback.
-// The caller owns "launcher_path" pointer, which cannot be NULL.
-int RunEntryPointOrMainModule(const char *launcher_path);
-}  // namespace python_launcher
-}  // namespace cpython2
-}  // namespace android
-
-#endif  // ANDROID_CPYTHON2_PYTHON_LAUNCHER_INTERNAL_H
diff --git a/Launcher/launcher_main.cpp b/Launcher/launcher_main.cpp
index a49998c..0a34c18 100644
--- a/Launcher/launcher_main.cpp
+++ b/Launcher/launcher_main.cpp
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "launcher_internal.h"
-
 #include <Python.h>
 #include <android-base/file.h>
 #include <osdefs.h>
@@ -22,103 +20,49 @@
 #include <string>
 
 int main(int argc, char *argv[]) {
-  int result = 0 /* Used to mark if current program runs with success/failure. */;
-
-  // Clear PYTHONPATH and PYTHONHOME so Python doesn't attempt to check the local
-  // disk for Python modules to load. The value of PYTHONHOME will replace "prefix"
-  // and "exe_prefix" based on the description in getpath.c.
-  // Please don't use PYTHONPATH and PYTHONHOME within user program.
-  // TODO(nanzhang): figure out if unsetenv("PYTHONPATH") is better.
-  unsetenv(const_cast<char *>("PYTHONPATH"));
-  // TODO(nanzhang): figure out if Py_SetPythonHome() is better.
-  unsetenv(const_cast<char *>("PYTHONHOME"));
   // PYTHONEXECUTABLE is only used on MacOs X, when the Python interpreter
   // embedded in an application bundle. It is not sure that we have this use case
-  // for Android hermetic Python. So override this environment variable to empty
-  // for now to make our self-contained environment more strict.
+  // for Android hermetic Python. So remove this environment variable to make
+  // our self-contained environment more strict.
   // For user (.py) program, it can access hermetic .par file path through
   // sys.argv[0].
   unsetenv(const_cast<char *>("PYTHONEXECUTABLE"));
 
+  // Always enable Python "-s" option. We don't need user-site directories,
+  // everything's supposed to be hermetic.
+  Py_NoUserSiteDirectory = 1;
+
+  // Ignore PYTHONPATH and PYTHONHOME from the environment. Unless we're not
+  // running from inside the zip file, in which case the user may have
+  // specified a PYTHONPATH.
+#ifdef ANDROID_AUTORUN
+  Py_IgnoreEnvironmentFlag = 1;
+#endif
+
+  Py_DontWriteBytecodeFlag = 1;
+
   // Resolving absolute path based on argv[0] is not reliable since it may
   // include something unusable, too bad.
   // android::base::GetExecutablePath() also handles for Darwin/Windows.
   std::string executable_path = android::base::GetExecutablePath();
 
-  argv[0] = strdup(executable_path.c_str());
-  // argv[0] is used for setting internal path, and Python sys.argv[0]. It
-  // should not exceed MAXPATHLEN defined for CPython.
-  if (!argv[0] || strlen(argv[0]) > MAXPATHLEN) {
-    fprintf(stderr, "The executable path %s is NULL or of invalid length.\n", argv[0]);
-    return 1;
+  // Set the equivalent of PYTHONHOME internally.
+  Py_SetPythonHome(strdup(executable_path.c_str()));
+
+#ifdef ANDROID_AUTORUN
+  argc += 1;
+  char **new_argv = reinterpret_cast<char**>(calloc(argc, sizeof(*argv)));
+
+  // Inject the path to our binary into argv[1] so the Py_Main won't parse any
+  // other options, and will execute the __main__.py script inside the zip file
+  // attached to our executable.
+  new_argv[0] = argv[0];
+  new_argv[1] = strdup(executable_path.c_str());
+  for (int i = 1; i < argc - 1; i++) {
+    new_argv[i+1] = argv[i];
   }
+  argv = new_argv;
+#endif
 
-  // For debugging/logging purpose, set stdin/stdout/stderr unbuffered through
-  // environment variable.
-  // TODO(nanzhang): Set Py_VerboseFlag if more debugging requests needed.
-  const char *unbuffered_env = getenv("PYTHONUNBUFFERED");
-  if (unbuffered_env && unbuffered_env[0]) {
-    #if defined(MS_WINDOWS) || defined(__CYGWIN__)
-      _setmode(fileno(stdin), O_BINARY);
-      _setmode(fileno(stdout), O_BINARY);
-    #endif
-    #ifdef HAVE_SETVBUF
-      setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
-      setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
-      setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
-    #else /* !HAVE_SETVBUF */
-      setbuf(stdin,  (char *)NULL);
-      setbuf(stdout, (char *)NULL);
-      setbuf(stderr, (char *)NULL);
-    #endif /* !HAVE_SETVBUF */
-  }
-  //For debugging/logging purpose, Warning control.
-  //Python’s warning machinery by default prints warning messages to sys.stderr.
-  //The full form of argument is:action:message:category:module:line
-  char *warnings_env = getenv("PYTHONWARNINGS");
-  if (warnings_env && warnings_env[0]) {
-      char *warnings_buf, *warning;
-
-      // Note: "new" operation; we need free this chuck of data after use.
-      warnings_buf = new char[strlen(warnings_env) + 1];
-      if (warnings_buf == NULL)
-          Py_FatalError(
-             "not enough memory to copy PYTHONWARNINGS");
-      strcpy(warnings_buf, warnings_env);
-      for (warning = strtok(warnings_buf, ",");
-           warning != NULL;
-           warning = strtok(NULL, ","))
-          PySys_AddWarnOption(warning);
-      delete[] warnings_buf;
-  }
-
-  // Always enable Python "-s" option. We don't need user-site directories,
-  // everything's supposed to be hermetic.
-  Py_NoUserSiteDirectory = 1;
-
-  Py_SetProgramName(argv[0]);
-  Py_Initialize();
-  PySys_SetArgvEx(argc, argv, 0);
-
-  // Set sys.executable to None. The real executable is available as
-  // sys.argv[0], and too many things assume sys.executable is a regular Python
-  // binary, which isn't available. By setting it to None we get clear errors
-  // when people try to use it.
-  if (PySys_SetObject(const_cast<char *>("executable"), Py_None) < 0) {
-    PyErr_Print();
-    result = 1;
-    goto error;
-  }
-
-  result = android::cpython2::python_launcher::RunEntryPointOrMainModule(argv[0]);
-  if (result < 0) {
-    PyErr_Print();
-    goto error;
-  }
-
-error:
-  Py_Finalize();
-
-  free(argv[0]);
-  exit(abs(result));
+  return Py_Main(argc, argv);
 }
diff --git a/Lib/Android.bp b/Lib/Android.bp
index 4fb6372..48e5caa 100644
--- a/Lib/Android.bp
+++ b/Lib/Android.bp
@@ -20,6 +20,7 @@
         "*.py",
         "compiler/**/*.py",
         "ctypes/**/*.py",
+        "distutils/**/*.py",
         "email/**/*.py",
         "encodings/**/*.py",
         "hotshot/**/*.py",
diff --git a/Modules/config.c b/Modules/config.c
index 677c063..2255347 100644
--- a/Modules/config.c
+++ b/Modules/config.c
@@ -81,6 +81,9 @@
 extern void init_sqlite3(void);
 extern void init_ctypes(void);
 extern void init_ctypes_test(void);
+#ifdef __APPLE__
+extern void init_scproxy(void);
+#endif
 
 /* -- ADDMODULE MARKER 1 -- */
 
@@ -150,6 +153,9 @@
     {"_sqlite3", init_sqlite3},
     {"_ctypes", init_ctypes},
     {"_ctypes_test", init_ctypes_test},
+#ifdef __APPLE__
+    {"_scproxy", init_scproxy},
+#endif
 
 /* -- ADDMODULE MARKER 2 -- */
 
diff --git a/Modules/getpath.c b/Modules/getpath.c
index e9d969b..27f3381 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -104,19 +104,15 @@
 #define LANDMARK "os.py"
 #endif
 
-#ifndef INTERNALDIR
-#define INTERNALDIR "internal"
-#endif
-
-#ifndef STDLIBDIR
-#define STDLIBDIR "stdlib"
-#endif
-
 static char prefix[MAXPATHLEN+1];
 static char exec_prefix[MAXPATHLEN+1];
 static char progpath[MAXPATHLEN+1];
 static char *module_search_path = NULL;
+#ifdef ANDROID_LIB_PYTHON_PATH
+static char lib_python[] = ANDROID_LIB_PYTHON_PATH;
+#else
 static char lib_python[] = "lib/python" VERSION;
+#endif
 
 static void
 reduce(char *dir)
@@ -263,11 +259,8 @@
         return 1;
     }
 
-    // GOOGLE(nanzhang): Always set prefix with hermetic executable full path.
-    strcpy(prefix, argv0_path);
-    return 1;
-
     /* Check to see if argv[0] is in the build directory */
+    strcpy(prefix, argv0_path);
     joinpath(prefix, "Modules/Setup");
     if (isfile(prefix)) {
         /* Check VPATH to see if argv0_path is in the build directory. */
@@ -325,13 +318,10 @@
         return 1;
     }
 
-    // GOOGLE(nanzhang): Always set exec_prefix with hermetic executable full path.
-    strcpy(exec_prefix, argv0_path);
-    return 1;
-
     /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
        is written by setup.py and contains the relative path to the location
        of shared library modules. */
+    strcpy(exec_prefix, argv0_path);
     joinpath(exec_prefix, "pybuilddir.txt");
     if (isfile(exec_prefix)) {
       FILE *f = fopen(exec_prefix, "r");
@@ -377,62 +367,19 @@
 calculate_path(void)
 {
     extern char *Py_GetProgramName(void);
+
     static char delimiter[2] = {DELIM, '\0'};
     static char separator[2] = {SEP, '\0'};
     char *pythonpath = PYTHONPATH;
+    char *rtpypath = Py_GETENV("PYTHONPATH");
     char *home = Py_GetPythonHome();
-    // We have overrided argv[0] using the full path to the hermetic Python
-    // launcher itself. And then Py_SetProgramName(argv[0]) was invoked at
-    // launcher_main.cpp. The launcher_main.cpp has guaranteed that
-    // strlen(Py_GetProgramName()) must not exceed MAXPATHLEN.
+    char *path = getenv("PATH");
     char *prog = Py_GetProgramName();
     char argv0_path[MAXPATHLEN+1];
-    char *buf;
-    size_t bufsz;
-
-    strncpy(progpath, prog, MAXPATHLEN);
-    progpath[MAXPATHLEN] = '\0' /* In case of no NUL-termination. */;
-    strncpy(argv0_path, prog, MAXPATHLEN);
-    argv0_path[MAXPATHLEN] = '\0' /* In case of no NUL-termination. */;
-
-    // We don't reduce the path of prefix, and exec_prefix.
-    search_for_prefix(argv0_path, home);
-    search_for_exec_prefix(argv0_path, home);
-
-    // Calculate size of return buffer.
-    bufsz = strlen(prog) + 1 + sizeof(INTERNALDIR) /* 1 is for SEP */;
-    bufsz += strlen(prog) + 1 + sizeof(INTERNALDIR) + 1 + sizeof(STDLIBDIR) /* 1 is for SEP */;
-
-    /* This is the only malloc call in this file */
-    buf = (char *)PyMem_Malloc(bufsz);
-
-    if (buf == NULL) {
-        /* We can't exit, so print a warning and limp along */
-        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
-        fprintf(stderr, "Using default static PYTHONPATH.\n");
-        exit(1);
-    } else {
-        buf[0] = '\0';
-        strcat(buf, prefix);
-        strcat(buf, separator);
-        strcat(buf, INTERNALDIR);
-        strcat(buf, delimiter);
-
-        strcat(buf, prefix);
-        strcat(buf, separator);
-        strcat(buf, INTERNALDIR);
-        strcat(buf, separator);
-        strcat(buf, STDLIBDIR);
-
-        module_search_path = buf;
-    }
-    // GOOGLE(nanzhang): Don't need all the code below for embedded Python launcher.
-    return;
-
-    char *path = getenv("PATH");
-    char *rtpypath = Py_GETENV("PYTHONPATH");
     char zip_path[MAXPATHLEN+1];
     int pfound, efound; /* 1 if found; -1 if found build directory */
+    char *buf;
+    size_t bufsz;
     size_t prefixsz;
     char *defpath = pythonpath;
 #ifdef WITH_NEXT_FRAMEWORK
@@ -620,8 +567,12 @@
         defpath = delim + 1;
     }
 
+#ifndef ANDROID_SKIP_ZIP_PATH
     bufsz += strlen(zip_path) + 1;
+#endif
+#ifndef ANDROID_SKIP_EXEC_PREFIX_PATH
     bufsz += strlen(exec_prefix) + 1;
+#endif
 
     /* This is the only malloc call in this file */
     buf = (char *)PyMem_Malloc(bufsz);
@@ -642,8 +593,10 @@
             buf[0] = '\0';
 
         /* Next is the default zip path */
+#ifndef ANDROID_SKIP_ZIP_PATH
         strcat(buf, zip_path);
         strcat(buf, delimiter);
+#endif
 
         /* Next goes merge of compile-time $PYTHONPATH with
          * dynamically located prefix.
@@ -672,10 +625,12 @@
             }
             defpath = delim + 1;
         }
+#ifndef ANDROID_SKIP_EXEC_PREFIX_PATH
         strcat(buf, delimiter);
 
         /* Finally, on goes the directory for dynamic-load modules */
         strcat(buf, exec_prefix);
+#endif
 
         /* And publish the results */
         module_search_path = buf;
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 0a7cd0f..1691773 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -43,11 +43,9 @@
 static PyObject *ZipImportError;
 static PyObject *zip_directory_cache = NULL;
 
-// GOOGLE(nanzhang): Changed two functions below to be visible to launcher so
-// that launcher can access the zip metadata section.
 /* forward decls */
-PyObject *read_directory(const char *archive);
-PyObject *get_data(const char *archive, PyObject *toc_entry);
+static PyObject *read_directory(const char *archive);
+static PyObject *get_data(const char *archive, PyObject *toc_entry);
 static PyObject *get_module_code(ZipImporter *self, char *fullname,
                                  int *p_ispackage, char **p_modpath);
 
@@ -704,7 +702,7 @@
    Directories can be recognized by the trailing SEP in the name,
    data_size and file_offset are 0.
 */
-PyObject *
+static PyObject *
 read_directory(const char *archive)
 {
     PyObject *files = NULL;
@@ -914,7 +912,7 @@
 
 /* Given a path to a Zip file and a toc_entry, return the (uncompressed)
    data as a new reference. */
-PyObject *
+static PyObject *
 get_data(const char *archive, PyObject *toc_entry)
 {
     PyObject *raw_data = NULL, *data, *decompress;
diff --git a/Python/thread.c b/Python/thread.c
index 3b69f96..8ac40f9 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -62,6 +62,9 @@
 #endif /* _POSIX_THREADS */
 
 
+#ifdef dprintf
+#undef dprintf
+#endif
 #ifdef Py_DEBUG
 static int thread_debug = 0;
 #define dprintf(args)   (void)((thread_debug & 1) && printf args)