Support uploading Mojo Shell on Android.

This change augments upload_shell_binary.py to allow uploading the shell on
Android as well as on Linux. Future work will make a similar change to
download_shell_binary.py.

R=qsr@chromium.org

Review URL: https://codereview.chromium.org/874243002
diff --git a/mojo/tools/mopy/paths.py b/mojo/tools/mopy/paths.py
index bade8c0..49e1c50 100644
--- a/mojo/tools/mopy/paths.py
+++ b/mojo/tools/mopy/paths.py
@@ -33,9 +33,16 @@
       if Config.GetHostOS() == Config.OS_WINDOWS:
         self.mojo_launcher_path += ".exe"
         self.mojo_shell_path += ".exe"
+      if config and config.target_os == Config.OS_ANDROID:
+        self.target_mojo_shell_path = os.path.join(self.build_dir,
+                                                   "apks",
+                                                   "MojoShell.apk")
+      else:
+        self.target_mojo_shell_path = self.mojo_shell_path
     else:
       self.mojo_launcher_path = None
       self.mojo_shell_path = None
+      self.target_mojo_shell_path = None
 
   def RelPath(self, path):
     """Returns the given path, relative to the current directory."""
diff --git a/mojo/tools/upload_shell_binary.py b/mojo/tools/upload_shell_binary.py
index 83c8847..c7297bb 100755
--- a/mojo/tools/upload_shell_binary.py
+++ b/mojo/tools/upload_shell_binary.py
@@ -11,31 +11,39 @@
 import time
 import zipfile
 
+import mopy.gn as gn
 from mopy.config import Config
 from mopy.paths import Paths
 from mopy.version import Version
 
-paths = Paths(Config(target_os=Config.OS_LINUX, is_debug=False))
+def upload(config, dry_run, verbose):
+  paths = Paths(config)
 
-sys.path.insert(0, os.path.join(paths.src_root, "tools"))
-# pylint: disable=F0401
-import find_depot_tools
+  sys.path.insert(0, os.path.join(paths.src_root, "tools"))
+  # pylint: disable=F0401
+  import find_depot_tools
 
-depot_tools_path = find_depot_tools.add_depot_tools_to_path()
-gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil")
+  depot_tools_path = find_depot_tools.add_depot_tools_to_path()
+  gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil")
 
-def upload(dry_run, verbose):
-  dest = "gs://mojo/shell/" + Version().version + "/linux-x64.zip"
+  zipfile_name = "%s-%s" % (config.target_os, config.target_arch)
+  dest = "gs://mojo/shell/" + Version().version + "/" + zipfile_name + ".zip"
 
   with tempfile.NamedTemporaryFile() as zip_file:
     with zipfile.ZipFile(zip_file, 'w') as z:
-      with open(paths.mojo_shell_path) as shell_binary:
-        zipinfo = zipfile.ZipInfo("mojo_shell")
+      shell_path = paths.target_mojo_shell_path
+      with open(shell_path) as shell_binary:
+        shell_filename = os.path.basename(shell_path)
+        zipinfo = zipfile.ZipInfo(shell_filename)
         zipinfo.external_attr = 0777 << 16L
-        zipinfo.compress_type = zipfile.ZIP_DEFLATED
-        zipinfo.date_time = time.gmtime(os.path.getmtime(paths.mojo_shell_path))
+        compress_type = zipfile.ZIP_DEFLATED
+        if config.target_os == Config.OS_ANDROID:
+          # The APK is already compressed.
+          compress_type = zipfile.ZIP_STORED
+        zipinfo.compress_type = compress_type
+        zipinfo.date_time = time.gmtime(os.path.getmtime(shell_path))
         if verbose:
-          print "zipping %s" % paths.mojo_shell_path
+          print "zipping %s" % shell_path
         z.writestr(zipinfo, shell_binary.read())
     if dry_run:
       print str([gsutil_exe, "cp", zip_file.name, dest])
@@ -49,8 +57,15 @@
       "upload", action="store_true")
   parser.add_argument("-v", "--verbose", help="Verbose mode",
       action="store_true")
+  parser.add_argument("--build_dir",
+                      type=str,
+                      metavar="<build_dir>",
+                      help="The build dir containing the shell to be uploaded",
+                      default="out/Release")
   args = parser.parse_args()
-  upload(args.dry_run, args.verbose)
+
+  config = gn.ConfigForGNArgs(gn.ParseGNConfig(args.build_dir))
+  upload(config, args.dry_run, args.verbose)
   return 0
 
 if __name__ == "__main__":