Upstream version 8.36.169.0
[platform/framework/web/crosswalk.git] / src / xwalk / app / tools / android / make_apk.py
index 2c1bbc1..450da42 100755 (executable)
@@ -28,9 +28,11 @@ def CleanDir(path):
   if os.path.exists(path):
     shutil.rmtree(path)
 
+
 def AllArchitectures():
   return ("x86", "arm")
 
+
 def RunCommand(command, verbose=False, shell=False):
   """Runs the command list, print the output, and propagate its result."""
   proc = subprocess.Popen(command, stdout=subprocess.PIPE,
@@ -47,21 +49,15 @@ def RunCommand(command, verbose=False, shell=False):
 
 
 def Which(name):
-  """Search PATH for executable files with the given name."""
-  result = []
-  exts = [_f for _f in os.environ.get('PATHEXT', '').split(os.pathsep) if _f]
-  path = os.environ.get('PATH', None)
-  if path is None:
-    return []
-  for p in os.environ.get('PATH', '').split(os.pathsep):
-    p = os.path.join(p, name)
-    if os.access(p, os.X_OK):
-      result.append(p)
-    for e in exts:
-      pext = p + e
-      if os.access(pext, os.X_OK):
-        result.append(pext)
-  return result
+  """Searches PATH for executable files with the given name, also taking
+  PATHEXT into account. Returns the first existing match, or None if no matches
+  are found."""
+  for path in os.environ.get('PATH', '').split(os.pathsep):
+    for filename in AddExeExtensions(name):
+      full_path = os.path.join(path, filename)
+      if os.path.isfile(full_path) and os.access(full_path, os.X_OK):
+        return full_path
+  return None
 
 
 def Find(name, path):
@@ -128,6 +124,8 @@ def ParseManifest(options, app_info):
   if parser.GetAppRoot():
     options.app_root = parser.GetAppRoot()
     options.icon_dict = parser.GetIcons()
+  if parser.GetOrientation():
+    options.orientation = parser.GetOrientation()
   if parser.GetFullScreenFlag().lower() == 'true':
     options.fullscreen = True
   elif parser.GetFullScreenFlag().lower() == 'false':
@@ -218,12 +216,13 @@ def Customize(options, app_info):
 
 
 def Execution(options, name):
-  android_path_array = Which('android')
-  if not android_path_array:
-    print('Please install Android SDK first.')
+  android_path = Which('android')
+  if android_path is None:
+    print('The "android" binary could not be found. Check your Android SDK '
+          'installation and your PATH environment variable.')
     sys.exit(1)
 
-  sdk_root_path = os.path.dirname(os.path.dirname(android_path_array[0]))
+  sdk_root_path = os.path.dirname(os.path.dirname(android_path))
 
   try:
     sdk_jar_path = Find('android.jar',
@@ -457,11 +456,29 @@ def Execution(options, name):
          'scripts/ant/apk-package.xml']
   RunCommand(cmd, options.verbose)
 
+  # Find the path of zipalign.
+  # XWALK-2033: zipalign can be in different locations depending on Android
+  # SDK version that used ((eg. /tools, /build-tools/android-4.4W etc),).
+  # So looking up the location of zipalign here instead of hard coding.
+  # Refer to: https://codereview.chromium.org/238253015
+  zipalign_path = ''
+  for zipalign_str in AddExeExtensions('zipalign'):
+    try:
+      zipalign_path = Find(zipalign_str, sdk_root_path)
+      if options.verbose:
+        print('Use %s in %s.' % (zipalign_str, sdk_root_path))
+      break
+    except Exception:
+      pass
+  if not zipalign_path:
+    print('zipalign could not be found in your Android SDK.'
+          ' Make sure it is installed.')
+    sys.exit(10)
   apk_path = '--unsigned-apk-path=' + os.path.join('out', 'app-unsigned.apk')
   final_apk_path = '--final-apk-path=' + \
                    os.path.join('out', name + '.apk')
   cmd = ['python', 'scripts/gyp/finalize_apk.py',
-         '--android-sdk-root=%s' % sdk_root_path,
+         '--zipalign-path=%s' % zipalign_path,
          apk_path,
          final_apk_path,
          '--keystore-path=%s' % key_store,
@@ -553,9 +570,6 @@ def MakeApk(options, app_info):
       if len(packaged_archs) == 0:
         print('No packages created, aborting')
         sys.exit(13)
-  else:
-    print('Unknown mode for packaging the application. Abort!')
-    sys.exit(11)
 
   PrintPackageInfo(options, packaged_archs)
 
@@ -573,7 +587,8 @@ def main(argv):
           'The value \'embedded\' means that the runtime is embedded into the '
           'application itself and distributed along with it.'
           'Set the default mode as \'embedded\'. For example: --mode=embedded')
-  parser.add_option('--mode', default='embedded', help=info)
+  parser.add_option('--mode', choices=('embedded', 'shared'),
+                    default='embedded', help=info)
   info = ('The target architecture of the embedded runtime. Supported values '
           'are \'x86\' and \'arm\'. Note, if undefined, APKs for all possible '
           'architestures will be generated.')
@@ -714,16 +729,26 @@ def main(argv):
       options.name = ReplaceSpaceWithUnderscore(options.name)
     else:
       parser.error('The APK name is required! Please use "--name" option.')
-    if not ((options.app_url and
-             not options.app_root and
-             not options.app_local_path) or
-            (not options.app_url and
-             options.app_root and
-             options.app_local_path)):
-      parser.error('The entry is required. If the entry is a remote url, '
-                   'please use "--app-url" option; If the entry is local, '
-                   'please use "--app-root" and '
-                   '"--app-local-path" options together!')
+
+    # The checks here are really convoluted, but at the moment make_apk
+    # misbehaves any of the following conditions is true.
+    if options.app_url:
+      # 1) --app-url must be passed without either --app-local-path or
+      #    --app-root.
+      if options.app_root or options.app_local_path:
+        parser.error('You must pass either "--app-url" or "--app-local-path" '
+                     'with "--app-root", but not all.')
+    else:
+      # 2) --app-url is not passed but only one of --app-local-path and
+      #    --app-root is set.
+      if bool(options.app_root) != bool(options.app_local_path):
+        parser.error('You must specify both "--app-local-path" and '
+                     '"--app-root".')
+      # 3) None of --app-url, --app-local-path and --app-root are passed.
+      elif not options.app_root and not options.app_local_path:
+        parser.error('You must pass either "--app-url" or "--app-local-path" '
+                     'with "--app-root".')
+
     if options.permissions:
       permission_list = options.permissions.split(':')
     else: