Upstream version 6.34.113.0
[platform/framework/web/crosswalk.git] / src / xwalk / app / tools / android / make_apk.py
index 96e2544..8c4901f 100755 (executable)
@@ -15,7 +15,7 @@ import subprocess
 import sys
 
 sys.path.append('scripts/gyp')
-from customize import ReplaceInvalidChars
+from customize import ReplaceInvalidChars, CustomizeAll
 from dex import AddExeExtensions
 from handle_permissions import permission_mapping_table
 from manifest_json_parser import HandlePermissionList
@@ -26,14 +26,15 @@ def CleanDir(path):
     shutil.rmtree(path)
 
 
-def RunCommand(command, shell=False):
+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,
                           stderr=subprocess.STDOUT, shell=shell)
   if not shell:
     output = proc.communicate()[0]
     result = proc.returncode
-    print(output.decode("utf-8"))
+    if verbose:
+      print(output.decode("utf-8").strip())
     if result != 0:
       print ('Command "%s" exited with non-zero exit code %d'
              % (' '.join(command), result))
@@ -110,15 +111,7 @@ def ParseManifest(options):
     sys.exit(9)
   if parser.GetAppRoot():
     options.app_root = parser.GetAppRoot()
-    temp_dict = parser.GetIcons()
-    try:
-      icon_dict = dict((int(k), v) for k, v in temp_dict.items())
-    except ValueError:
-      print('The key of icon in the manifest file should be a number.')
-    # TODO(junmin): add multiple icons support.
-    if icon_dict:
-      icon_file = max(iter(icon_dict.items()), key=operator.itemgetter(0))[1]
-      options.icon = os.path.join(options.app_root, icon_file)
+    options.icon_dict = parser.GetIcons()
   if parser.GetFullScreenFlag().lower() == 'true':
     options.fullscreen = True
   elif parser.GetFullScreenFlag().lower() == 'false':
@@ -160,13 +153,14 @@ def FindExtensionJars(root_path):
         extension_jars.append(extension_jar)
   return extension_jars
 
+
 # Follows the recommendation from
 # http://software.intel.com/en-us/blogs/2012/11/12/how-to-publish-
 # your-apps-on-google-play-for-x86-based-android-devices-using
 def MakeVersionCode(options):
   ''' Construct a version code'''
   if options.app_versionCode:
-    return '--app-versionCode=%s' % options.app_versionCode
+    return options.app_versionCode
 
   # First digit is ABI, ARM=2, x86=6
   abi = '0'
@@ -183,57 +177,38 @@ def MakeVersionCode(options):
       sys.exit(12)
   # zero pad to 7 digits, middle digits can be used for other
   # features, according to recommendation in URL
-  return '--app-versionCode=%s%s' % (abi, b.zfill(7))
+  return '%s%s' % (abi, b.zfill(7))
+
 
 def Customize(options):
-  package = '--package=org.xwalk.app.template'
+  package = 'org.xwalk.app.template'
   if options.package:
-    package = '--package=%s' % options.package
-  name = '--name=AppTemplate'
+    package = options.package
+  name = 'AppTemplate'
   if options.name:
-    name = '--name=%s' % options.name
-  app_version = '--app-version=1.0.0'
+    name = options.name
+  app_version = ''
   if options.app_version:
-    app_version = '--app-version=%s' % options.app_version
+    app_version = options.app_version
   app_versionCode = MakeVersionCode(options)
-  description = ''
-  if options.description:
-    description = '--description=%s' % options.description
-  permissions = ''
-  if options.permissions:
-    permissions = '--permissions=%s' % options.permissions
-  icon = ''
-  if options.icon:
-    icon = '--icon=%s' % os.path.expanduser(options.icon)
-  app_url =  ''
-  if options.app_url:
-    app_url = '--app-url=%s' % options.app_url
   app_root = ''
   if options.app_root:
-    app_root = '--app-root=%s' % os.path.expanduser(options.app_root)
-  app_local_path = ''
-  if options.app_local_path:
-    app_local_path = '--app-local-path=%s' % options.app_local_path
+    app_root = os.path.expanduser(options.app_root)
   remote_debugging = ''
   if options.enable_remote_debugging:
     remote_debugging = '--enable-remote-debugging'
   fullscreen_flag = ''
   if options.fullscreen:
     fullscreen_flag = '-f'
-  extensions_list = ''
-  if options.extensions:
-    extensions_list = '--extensions=%s' % options.extensions
-  orientation = '--orientation=unspecified'
+  orientation = 'unspecified'
   if options.orientation:
-    orientation = '--orientation=%s' % options.orientation
-  default_image = ''
-  if options.launch_screen_img:
-    default_image = '--launch-screen-img=' + options.launch_screen_img
-  cmd = ['python', 'customize.py', package,
-          name, app_version, app_versionCode, description, icon, permissions,
-          app_url, remote_debugging, app_root, app_local_path, fullscreen_flag,
-          extensions_list, orientation, default_image]
-  RunCommand(cmd)
+    orientation = options.orientation
+  CustomizeAll(app_versionCode, options.description, options.icon_dict,
+               options.permissions, options.app_url, app_root,
+               options.app_local_path, remote_debugging,
+               fullscreen_flag, options.extensions,
+               options.launch_screen_img, package, name, app_version,
+               orientation)
 
 
 def Execution(options, sanitized_name):
@@ -302,7 +277,7 @@ def Execution(options, sanitized_name):
   # Check whether ant is installed.
   try:
     cmd = ['ant', '-version']
-    RunCommand(cmd, True)
+    RunCommand(cmd, shell=True)
   except EnvironmentError:
     print('Please install ant first.')
     sys.exit(4)
@@ -364,12 +339,12 @@ def Execution(options, sanitized_name):
          '-Dbasedir=.',
          '-buildfile',
          os.path.join('scripts', 'ant', 'apk-codegen.xml')]
-  RunCommand(cmd)
+  RunCommand(cmd, options.verbose)
 
   # Check whether java is installed.
   try:
     cmd = ['java', '-version']
-    RunCommand(cmd, True)
+    RunCommand(cmd, shell=True)
   except EnvironmentError:
     print('Please install Oracle JDK first.')
     sys.exit(5)
@@ -412,7 +387,7 @@ def Execution(options, sanitized_name):
          '-Dbasedir=.',
          '-buildfile',
          xml_path]
-  RunCommand(cmd)
+  RunCommand(cmd, options.verbose)
 
   dex_path = '--dex-path=' + os.path.join(os.getcwd(), 'out', 'classes.dex')
   app_runtime_jar = os.path.join(os.getcwd(),
@@ -469,7 +444,7 @@ def Execution(options, sanitized_name):
          '-Dbasedir=.',
          '-buildfile',
          'scripts/ant/apk-package.xml']
-  RunCommand(cmd)
+  RunCommand(cmd, options.verbose)
 
   apk_path = '--unsigned-apk-path=' + os.path.join('out', 'app-unsigned.apk')
   final_apk_path = '--final-apk-path=' + \
@@ -488,28 +463,29 @@ def Execution(options, sanitized_name):
   if options.app_version:
     package_name += ('_' + options.app_version)
   if options.mode == 'shared':
-    dst_file = '%s.apk' % package_name
+    dst_file = os.path.join(options.target_dir, '%s.apk' % package_name)
   elif options.mode == 'embedded':
-    dst_file = '%s_%s.apk' % (package_name, options.arch)
+    dst_file = os.path.join(options.target_dir,
+                            '%s_%s.apk' % (package_name, options.arch))
   shutil.copyfile(src_file, dst_file)
   CleanDir('out')
   if options.mode == 'embedded':
     os.remove(pak_des_path)
 
 
-def PrintPackageInfo(app_name, app_version, arch = ''):
-  package_name_version = app_name
+def PrintPackageInfo(target_dir, app_name, app_version, arch = ''):
+  package_name_version = os.path.join(target_dir, app_name)
   if app_version != '':
     package_name_version += ('_' + app_version)
   if arch == '':
     print ('A non-platform specific APK for the web application "%s" was '
-           'generated successfully at %s.apk. It requires a shared Crosswalk '
+           'generated successfully at\n%s.apk. It requires a shared Crosswalk '
            'Runtime to be present.'
            % (app_name, package_name_version))
   else:
     print ('An APK for the web application "%s" including the Crosswalk '
            'Runtime built for %s was generated successfully, which can be '
-           'found at %s_%s.apk.'
+           'found at\n%s_%s.apk.'
            % (app_name, arch, package_name_version, arch))
 
 
@@ -520,11 +496,12 @@ def MakeApk(options, sanitized_name):
     app_version = options.app_version
   if options.mode == 'shared':
     Execution(options, sanitized_name)
-    PrintPackageInfo(sanitized_name, app_version)
+    PrintPackageInfo(options.target_dir, sanitized_name, app_version)
   elif options.mode == 'embedded':
     if options.arch:
       Execution(options, sanitized_name)
-      PrintPackageInfo(sanitized_name, app_version, options.arch)
+      PrintPackageInfo(options.target_dir, sanitized_name,
+                       app_version, options.arch)
     else:
       # If the arch option is unspecified, all of available platform APKs
       # will be generated.
@@ -540,11 +517,13 @@ def MakeApk(options, sanitized_name):
           Execution(options, sanitized_name)
           packaged_archs.append(options.arch)
       for arch in packaged_archs:
-        PrintPackageInfo(sanitized_name, app_version, arch)
+        PrintPackageInfo(options.target_dir, sanitized_name,
+                         app_version, arch)
   else:
     print('Unknown mode for packaging the application. Abort!')
     sys.exit(11)
 
+
 def parse_optional_arg(default_value):
   def func(option, value, values, parser):
     del value
@@ -557,11 +536,15 @@ def parse_optional_arg(default_value):
     setattr(parser.values, option.dest, val)
   return func
 
+
 def main(argv):
   parser = optparse.OptionParser()
   parser.add_option('-v', '--version', action='store_true',
                     dest='version', default=False,
                     help='The version of this python tool.')
+  parser.add_option('--verbose', action="store_true",
+                    dest='verbose', default=False,
+                    help='Print debug messages.')
   info = ('The packaging mode of the web application. The value \'shared\' '
           'means that the runtime is shared across multiple application '
           'instances and that the runtime needs to be distributed separately. '
@@ -644,6 +627,8 @@ def main(argv):
   info = ('The list of permissions to be used by web application. For example, '
           '--permissions=geolocation:webgl')
   group.add_option('--permissions', help=info)
+  info = ('Packaging tool will move the output APKS to the target directory')
+  group.add_option('--target-dir', default=os.getcwd(), help=info)
   parser.add_option_group(group)
   group = optparse.OptionGroup(parser, 'Keystore Options',
       'The keystore is a signature from web developer, it\'s used when '
@@ -706,22 +691,34 @@ def main(argv):
     if options.permissions:
       permission_list = options.permissions.split(':')
     else:
-      print ('Warning: all supported permissions on Android port are added. '
-             'Refer to https://github.com/crosswalk-project/'
-             'crosswalk-website/wiki/Crosswalk-manifest')
+      print('Warning: all supported permissions on Android port are added. '
+            'Refer to https://github.com/crosswalk-project/'
+            'crosswalk-website/wiki/Crosswalk-manifest')
       permission_list = permission_mapping_table.keys()
     options.permissions = HandlePermissionList(permission_list)
-
+    options.icon_dict = {}
   else:
     try:
       ParseManifest(options)
     except SystemExit as ec:
       return ec.code
 
+  if (options.app_root and options.app_local_path and not
+      os.path.isfile(os.path.join(options.app_root, options.app_local_path))):
+    print('Please make sure that the local path file of launching app '
+          'does exist.')
+    sys.exit(7)
+
   options.name = ReplaceInvalidChars(options.name, 'apkname')
   options.package = ReplaceInvalidChars(options.package)
   sanitized_name = ReplaceInvalidChars(options.name, 'apkname')
 
+  if options.target_dir:
+    target_dir = os.path.abspath(os.path.expanduser(options.target_dir))
+    options.target_dir = target_dir
+    if not os.path.isdir(target_dir):
+      os.makedirs(target_dir)
+
   try:
     compress = compress_js_and_css.CompressJsAndCss(options.app_root)
     if options.compressor == 'all':