Upstream version 9.37.190.0
[platform/framework/web/crosswalk.git] / src / xwalk / app / tools / android / customize.py
old mode 100644 (file)
new mode 100755 (executable)
index a28c6ce..510dd63
@@ -4,21 +4,53 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import compress_js_and_css
+import fnmatch
 import json
 import optparse
 import os
 import re
 import shutil
+import stat
 import sys
 
+from app_info import AppInfo
+from customize_launch_screen import CustomizeLaunchScreen
 from handle_xml import AddElementAttribute
 from handle_xml import AddElementAttributeAndText
-from handle_xml import AddThemeStyle
 from handle_xml import EditElementAttribute
-from handle_xml import RemoveThemeStyle
+from handle_xml import EditElementValueByNodeName
 from handle_permissions import HandlePermissions
 from xml.dom import minidom
 
+
+def VerifyAppName(value, mode='default'):
+  descrpt = 'The app'
+  sample = 'helloworld, hello world, hello_world, hello_world1'
+  regex = r'[a-zA-Z][\w ]*$'
+
+  if len(value) >= 128:
+    print('To be safe, the length of package name or app name '
+          'should be less than 128.')
+    sys.exit(6)
+  if mode == 'packagename':
+    regex = r'^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$'
+    descrpt = 'Each part of package'
+    sample = 'org.xwalk.example, org.xwalk.example_'
+
+  if not re.match(regex, value):
+    print('Error: %s name should be started with letters and should not '
+          'contain invalid characters.\n'
+          'It may contain lowercase letters, numbers, blank spaces and '
+          'underscores\n'
+          'Sample: %s' % (descrpt, sample))
+    sys.exit(6)
+
+
+def ReplaceSpaceWithUnderscore(value):
+  return value.replace(' ', '_')
+
+
 def ReplaceInvalidChars(value, mode='default'):
   """ Replace the invalid chars with '_' for input string.
   Args:
@@ -31,96 +63,158 @@ def ReplaceInvalidChars(value, mode='default'):
     invalid_chars = '\/:.*?"<>|- '
   for c in invalid_chars:
     if mode == 'apkname' and c in value:
-      print "Illegal character: '%s' is replaced with '_'" % c
-    value = value.replace(c,'_')
+      print("Illegal character: '%s' is replaced with '_'" % c)
+    value = value.replace(c, '_')
   return value
 
 
-def Prepare(options, sanitized_name):
-  if os.path.exists(sanitized_name):
-    shutil.rmtree(sanitized_name)
-  shutil.copytree('app_src', sanitized_name)
-  shutil.rmtree(os.path.join(sanitized_name, 'src'))
-  src_root = os.path.join('app_src', 'src', 'org', 'xwalk', 'app', 'template')
+def GetFilesByExt(path, ext, sub_dir=True):
+  if os.path.exists(path):
+    file_list = []
+    for name in os.listdir(path):
+      full_name = os.path.join(path, name)
+      st = os.lstat(full_name)
+      if stat.S_ISDIR(st.st_mode) and sub_dir:
+        file_list += GetFilesByExt(full_name, ext)
+      elif os.path.isfile(full_name):
+        if fnmatch.fnmatch(full_name, ext):
+          file_list.append(full_name)
+    return file_list
+  else:
+    return []
+
+
+def ParseParameterForCompressor(option, value, values, parser):
+  if ((not values or values.startswith('-'))
+      and value.find('--compressor') != -1):
+    values = 'all'
+  val = values
+  if parser.rargs and not parser.rargs[0].startswith('-'):
+    val = parser.rargs[0]
+    parser.rargs.pop(0)
+  setattr(parser.values, option.dest, val)
+
+
+def CompressSourceFiles(app_root, compressor):
+  js_list = []
+  css_list = []
+  js_ext = '*.js'
+  css_ext = '*.css'
+
+  if compressor == 'all' or compressor == 'js':
+    js_list = GetFilesByExt(app_root, js_ext)
+    compress_js_and_css.CompressJavaScript(js_list)
+
+  if compressor == 'all' or compressor == 'css':
+    css_list = GetFilesByExt(app_root, css_ext)
+    compress_js_and_css.CompressCss(css_list)
+
+
+def Prepare(app_info, compressor):
+  name = app_info.android_name
+  package = app_info.package
+  app_root = app_info.app_root
+  if os.path.exists(name):
+    shutil.rmtree(name)
+  shutil.copytree('template', name)
+  shutil.rmtree(os.path.join(name, 'src'))
+  src_root = os.path.join('template', 'src', 'org', 'xwalk', 'app', 'template')
   src_activity = os.path.join(src_root, 'AppTemplateActivity.java')
   if not os.path.isfile(src_activity):
     print ('Please make sure that the java file'
            ' of activity does exist.')
     sys.exit(7)
-  root_path =  os.path.join(sanitized_name, 'src',
-                            options.package.replace('.', os.path.sep))
+  root_path = os.path.join(name, 'src', package.replace('.', os.path.sep))
   if not os.path.exists(root_path):
     os.makedirs(root_path)
-  dest_activity = sanitized_name + 'Activity.java'
+  dest_activity = name + 'Activity.java'
   shutil.copyfile(src_activity, os.path.join(root_path, dest_activity))
-  if options.app_root:
-    assets_path = os.path.join(sanitized_name, 'assets')
-    shutil.rmtree(assets_path)
-    os.makedirs(assets_path)
-    app_src_path = os.path.join(assets_path, 'www')
-    shutil.copytree(options.app_root, app_src_path)
+  if app_root:
+    assets_path = os.path.join(name, 'assets', 'www')
+    if os.path.isdir(assets_path):
+      shutil.rmtree(assets_path)
+    shutil.copytree(app_root, assets_path)
+    if compressor:
+      CompressSourceFiles(assets_path, compressor)
 
 
-def CustomizeStringXML(options, sanitized_name):
-  strings_path = os.path.join(sanitized_name, 'res', 'values', 'strings.xml')
+def CustomizeStringXML(name, description):
+  strings_path = os.path.join(name, 'res', 'values', 'strings.xml')
   if not os.path.isfile(strings_path):
     print ('Please make sure strings_xml'
-           ' exists under app_src folder.')
+           ' exists under template folder.')
     sys.exit(6)
 
-  if options.description:
+  if description:
     xmldoc = minidom.parse(strings_path)
     AddElementAttributeAndText(xmldoc, 'string', 'name', 'description',
-                               options.description)
-    strings_file = open(strings_path, 'wb')
-    xmldoc.writexml(strings_file)
+                               description)
+    strings_file = open(strings_path, 'w')
+    xmldoc.writexml(strings_file, encoding='utf-8')
     strings_file.close()
 
 
-def CustomizeXML(options, sanitized_name):
-  manifest_path = os.path.join(sanitized_name, 'AndroidManifest.xml')
+def CustomizeThemeXML(name, fullscreen, manifest):
+  theme_path = os.path.join(name, 'res', 'values-v17', 'theme.xml')
+  if not os.path.isfile(theme_path):
+    print('Error: theme.xml is missing in the build tool.')
+    sys.exit(6)
+
+  theme_xmldoc = minidom.parse(theme_path)
+  if fullscreen:
+    EditElementValueByNodeName(theme_xmldoc, 'item',
+                               'android:windowFullscreen', 'true')
+  has_background = CustomizeLaunchScreen(manifest, name)
+  if has_background:
+    EditElementValueByNodeName(theme_xmldoc, 'item',
+                               'android:windowBackground',
+                               '@drawable/launchscreen_bg')
+  theme_file = open(theme_path, 'w')
+  theme_xmldoc.writexml(theme_file, encoding='utf-8')
+  theme_file.close()
+
+
+def CustomizeXML(app_info, description, icon_dict, manifest, permissions):
+  app_version = app_info.app_version
+  app_versionCode = app_info.app_versionCode
+  name = app_info.android_name
+  orientation = app_info.orientation
+  package = app_info.package
+  app_name = app_info.app_name
+  manifest_path = os.path.join(name, 'AndroidManifest.xml')
   if not os.path.isfile(manifest_path):
     print ('Please make sure AndroidManifest.xml'
-           ' exists under app_src folder.')
+           ' exists under template folder.')
     sys.exit(6)
 
-  CustomizeStringXML(options, sanitized_name)
+  CustomizeStringXML(name, description)
+  CustomizeThemeXML(name, app_info.fullscreen_flag, manifest)
   xmldoc = minidom.parse(manifest_path)
-  EditElementAttribute(xmldoc, 'manifest', 'package', options.package)
-  if options.app_version:
+  EditElementAttribute(xmldoc, 'manifest', 'package', package)
+  if app_versionCode:
+    EditElementAttribute(xmldoc, 'manifest', 'android:versionCode',
+                         str(app_versionCode))
+  if app_version:
     EditElementAttribute(xmldoc, 'manifest', 'android:versionName',
-                         options.app_version)
-  if options.description:
+                         app_version)
+  if description:
     EditElementAttribute(xmldoc, 'manifest', 'android:description',
                          "@string/description")
-  HandlePermissions(options, xmldoc)
-  EditElementAttribute(xmldoc, 'application', 'android:label', options.name)
-  activity_name = options.package + '.' + sanitized_name + 'Activity'
+  HandlePermissions(permissions, xmldoc)
+  EditElementAttribute(xmldoc, 'application', 'android:label', app_name)
+  activity_name = package + '.' + name + 'Activity'
   EditElementAttribute(xmldoc, 'activity', 'android:name', activity_name)
-  EditElementAttribute(xmldoc, 'activity', 'android:label', options.name)
-  if options.orientation:
+  EditElementAttribute(xmldoc, 'activity', 'android:label', app_name)
+  if orientation:
     EditElementAttribute(xmldoc, 'activity', 'android:screenOrientation',
-                         options.orientation)
-  if options.fullscreen:
-    AddThemeStyle(xmldoc, 'activity', 'android:theme', 'Fullscreen')
-  else:
-    RemoveThemeStyle(xmldoc, 'activity', 'android:theme', 'Fullscreen')
-  if options.icon and os.path.isfile(options.icon):
-    drawable_path = os.path.join(sanitized_name, 'res', 'drawable')
-    if not os.path.exists(drawable_path):
-      os.makedirs(drawable_path)
-    icon_file = os.path.basename(options.icon)
-    icon_file = ReplaceInvalidChars(icon_file)
-    shutil.copyfile(options.icon, os.path.join(drawable_path, icon_file))
-    icon_name = os.path.splitext(icon_file)[0]
-    EditElementAttribute(xmldoc, 'application',
-                         'android:icon', '@drawable/%s' % icon_name)
-  elif options.icon and (not os.path.isfile(options.icon)):
-    print ('Please make sure the icon file does exist!')
-    sys.exit(6)
-
-  file_handle = open(os.path.join(sanitized_name, 'AndroidManifest.xml'), 'wb')
-  xmldoc.writexml(file_handle)
+                         orientation)
+  icon_name = CustomizeIcon(name, app_info.app_root, app_info.icon, icon_dict)
+  if icon_name:
+    EditElementAttribute(xmldoc, 'application', 'android:icon',
+                         '@drawable/%s' % icon_name)
+
+  file_handle = open(os.path.join(name, 'AndroidManifest.xml'), 'w')
+  xmldoc.writexml(file_handle, encoding='utf-8')
   file_handle.close()
 
 
@@ -134,48 +228,60 @@ def ReplaceString(file_path, src, dest):
   file_handle.close()
 
 
-def SetVariable(file_path, variable, value):
+def SetVariable(file_path, string_line, variable, value):
   function_string = ('%sset%s(%s);\n' %
                     ('        ', variable, value))
   temp_file_path = file_path + '.backup'
   file_handle = open(temp_file_path, 'w+')
   for line in open(file_path):
     file_handle.write(line)
-    if (line.find('public void onCreate(Bundle savedInstanceState)') >= 0):
+    if (line.find(string_line) >= 0):
       file_handle.write(function_string)
   file_handle.close()
   shutil.move(temp_file_path, file_path)
 
 
-def CustomizeJava(options, sanitized_name):
-  root_path =  os.path.join(sanitized_name, 'src',
-                            options.package.replace('.', os.path.sep))
-  dest_activity = os.path.join(root_path, sanitized_name + 'Activity.java')
-  ReplaceString(dest_activity, 'org.xwalk.app.template', options.package)
-  ReplaceString(dest_activity, 'AppTemplate', sanitized_name)
-  manifest_file = os.path.join(sanitized_name, 'assets/www', 'manifest.json')
+def CustomizeJava(app_info, app_url, app_local_path, keep_screen_on):
+  name = app_info.android_name
+  package = app_info.package
+  root_path = os.path.join(name, 'src', package.replace('.', os.path.sep))
+  dest_activity = os.path.join(root_path, name + 'Activity.java')
+  ReplaceString(dest_activity, 'org.xwalk.app.template', package)
+  ReplaceString(dest_activity, 'AppTemplate', name)
+  manifest_file = os.path.join(name, 'assets/www', 'manifest.json')
   if os.path.isfile(manifest_file):
     ReplaceString(
         dest_activity,
         'loadAppFromUrl("file:///android_asset/www/index.html")',
         'loadAppFromManifest("file:///android_asset/www/manifest.json")')
   else:
-    if options.app_url:
-      if re.search(r'^http(|s)', options.app_url):
+    if app_url:
+      if re.search(r'^http(|s)', app_url):
         ReplaceString(dest_activity, 'file:///android_asset/www/index.html',
-                      options.app_url)
-    elif options.app_local_path:
-      if os.path.isfile(os.path.join(sanitized_name, 'assets/www',
-                                     options.app_local_path)):
+                      app_url)
+    elif app_local_path:
+      if os.path.isfile(os.path.join(name, 'assets/www', app_local_path)):
         ReplaceString(dest_activity, 'file:///android_asset/www/index.html',
-                      'app://' + options.package + '/' + options.app_local_path)
+                      'app://' + package + '/' + app_local_path)
       else:
         print ('Please make sure that the relative path of entry file'
                ' is correct.')
         sys.exit(8)
 
-  if options.enable_remote_debugging:
-    SetVariable(dest_activity, 'RemoteDebugging', 'true')
+  if app_info.remote_debugging:
+    SetVariable(dest_activity,
+                'public void onCreate(Bundle savedInstanceState)',
+                'RemoteDebugging', 'true')
+  if app_info.fullscreen_flag:
+    SetVariable(dest_activity,
+                'super.onCreate(savedInstanceState)',
+                'IsFullscreen', 'true')
+  if keep_screen_on:
+    ReplaceString(
+        dest_activity,
+        'super.onCreate(savedInstanceState);',
+        'super.onCreate(savedInstanceState);\n        ' +
+        'getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);')
 
 
 def CopyExtensionFile(extension_name, suffix, src_path, dest_path):
@@ -183,8 +289,8 @@ def CopyExtensionFile(extension_name, suffix, src_path, dest_path):
   dest_extension_path = os.path.join(dest_path, extension_name)
   if os.path.exists(dest_extension_path):
     # TODO: Refine it by renaming it internally.
-    print ('Error: duplicated extension names "%s" are found. Please rename it.'
-           % extension_name)
+    print('Error: duplicated extension names "%s" are found. Please rename it.'
+          % extension_name)
     sys.exit(9)
   else:
     os.mkdir(dest_extension_path)
@@ -193,13 +299,13 @@ def CopyExtensionFile(extension_name, suffix, src_path, dest_path):
   src_file = os.path.join(src_path, file_name)
   dest_file = os.path.join(dest_extension_path, file_name)
   if not os.path.isfile(src_file):
+    print('Error: %s was not found in %s.' % (file_name, src_path))
     sys.exit(9)
-    print 'Error: %s is not found in %s.' % (file_name, src_path)
   else:
     shutil.copyfile(src_file, dest_file)
 
 
-def CustomizeExtensions(options, sanitized_name):
+def CustomizeExtensions(app_info, extensions):
   """Copy the files from external extensions and merge them into APK.
 
   The directory of one external extension should be like:
@@ -215,9 +321,10 @@ def CustomizeExtensions(options, sanitized_name):
   For .json files, the'll be merged into one file called
   extensions-config.json and copied into assets/.
   """
-  if not options.extensions:
+  if not extensions:
     return
-  apk_path = options.name
+  name = app_info.android_name
+  apk_path = name
   apk_assets_path = os.path.join(apk_path, 'assets')
   extensions_string = 'xwalk-extensions'
 
@@ -230,11 +337,11 @@ def CustomizeExtensions(options, sanitized_name):
                                           'extensions-config.json')
 
   # Split the paths into a list.
-  extension_paths = options.extensions.split(os.pathsep)
+  extension_paths = extensions.split(os.pathsep)
   extension_json_list = []
   for source_path in extension_paths:
     if not os.path.exists(source_path):
-      print 'Error: can\'t find the extension directory \'%s\'.' % source_path
+      print('Error: can\'t find the extension directory \'%s\'.' % source_path)
       sys.exit(9)
     # Remove redundant separators to avoid empty basename.
     source_path = os.path.normpath(source_path)
@@ -250,16 +357,17 @@ def CustomizeExtensions(options, sanitized_name):
     file_name = extension_name + '.json'
     src_file = os.path.join(source_path, file_name)
     if not os.path.isfile(src_file):
-      print 'Error: %s is not found in %s.' % (file_name, source_path)
+      print('Error: %s is not found in %s.' % (file_name, source_path))
       sys.exit(9)
     else:
-      src_file_handle = file(src_file)
+      src_file_handle = open(src_file)
       src_file_content = src_file_handle.read()
       json_output = json.JSONDecoder().decode(src_file_content)
       # Below 3 properties are used by runtime. See extension manager.
       # And 'permissions' will be merged.
-      if ((not 'name' in json_output) or (not 'class' in json_output)
-          or (not 'jsapi' in json_output)):
+      if not ('name' in json_output and
+              'class' in json_output and
+              'jsapi' in json_output):
         print ('Error: properties \'name\', \'class\' and \'jsapi\' in a json '
                'file are mandatory.')
         sys.exit(9)
@@ -268,7 +376,7 @@ def CustomizeExtensions(options, sanitized_name):
       json_output['jsapi'] = js_path_prefix + json_output['jsapi']
       extension_json_list.append(json_output)
       # Merge the permissions of extensions into AndroidManifest.xml.
-      manifest_path = os.path.join(sanitized_name, 'AndroidManifest.xml')
+      manifest_path = os.path.join(name, 'AndroidManifest.xml')
       xmldoc = minidom.parse(manifest_path)
       if ('permissions' in json_output):
         # Get used permission list to avoid repetition as "--permissions"
@@ -286,8 +394,8 @@ def CustomizeExtensions(options, sanitized_name):
           existingList.append(p)
 
         # Write to the manifest file to save the update.
-        file_handle = open(manifest_path, 'wb')
-        xmldoc.writexml(file_handle)
+        file_handle = open(manifest_path, 'w')
+        xmldoc.writexml(file_handle, encoding='utf-8')
         file_handle.close()
 
   # Write configuration of extensions into the target extensions-config.json.
@@ -298,20 +406,102 @@ def CustomizeExtensions(options, sanitized_name):
     extension_json_file.close()
 
 
+def GenerateCommandLineFile(app_info, xwalk_command_line):
+  if xwalk_command_line == '':
+    return
+  assets_path = os.path.join(app_info.android_name, 'assets')
+  file_path = os.path.join(assets_path, 'xwalk-command-line')
+  command_line_file = open(file_path, 'w')
+  command_line_file.write('xwalk ' + xwalk_command_line)
+
+
+def CustomizeIconByDict(name, app_root, icon_dict):
+  icon_name = None
+  drawable_dict = {'ldpi': [1, 37], 'mdpi': [37, 72], 'hdpi': [72, 96],
+                   'xhdpi': [96, 120], 'xxhdpi': [120, 144],
+                   'xxxhdpi': [144, 168]}
+  if not icon_dict:
+    return icon_name
+
+  try:
+    icon_dict = dict((int(k), v) for k, v in icon_dict.items())
+  except ValueError:
+    print('The key of icon in the manifest file should be a number.')
+
+  if len(icon_dict) > 0:
+    icon_list = sorted(icon_dict.items(), key=lambda d: d[0])
+    for kd, vd in drawable_dict.items():
+      for item in icon_list:
+        if item[0] >= vd[0] and item[0] < vd[1]:
+          drawable_path = os.path.join(name, 'res', 'drawable-' + kd)
+          if not os.path.exists(drawable_path):
+            os.makedirs(drawable_path)
+          icon = os.path.join(app_root, item[1])
+          if icon and os.path.isfile(icon):
+            icon_name = os.path.basename(icon)
+            icon_suffix = icon_name.split('.')[-1]
+            shutil.copyfile(icon, os.path.join(drawable_path,
+                                               'icon.' + icon_suffix))
+            icon_name = 'icon'
+          elif icon and (not os.path.isfile(icon)):
+            print('Error: "%s" does not exist.' % icon)
+            sys.exit(6)
+          break
+  return icon_name
+
+
+def CustomizeIconByOption(name, icon):
+  if os.path.isfile(icon):
+    drawable_path = os.path.join(name, 'res', 'drawable')
+    if not os.path.exists(drawable_path):
+      os.makedirs(drawable_path)
+    icon_file = os.path.basename(icon)
+    icon_file = ReplaceInvalidChars(icon_file)
+    shutil.copyfile(icon, os.path.join(drawable_path, icon_file))
+    icon_name = os.path.splitext(icon_file)[0]
+    return icon_name
+  else:
+    print('Error: "%s" does not exist.')
+    sys.exit(6)
+
+
+def CustomizeIcon(name, app_root, icon, icon_dict):
+  icon_name = None
+  if icon:
+    icon_name = CustomizeIconByOption(name, icon)
+  else:
+    icon_name = CustomizeIconByDict(name, app_root, icon_dict)
+  return icon_name
+
+
+def CustomizeAll(app_info, description, icon_dict, permissions, app_url,
+                 app_local_path, keep_screen_on, extensions, manifest,
+                 xwalk_command_line='', compressor=None):
+  try:
+    Prepare(app_info, compressor)
+    CustomizeXML(app_info, description, icon_dict, manifest, permissions)
+    CustomizeJava(app_info, app_url, app_local_path, keep_screen_on)
+    CustomizeExtensions(app_info, extensions)
+    GenerateCommandLineFile(app_info, xwalk_command_line)
+  except SystemExit as ec:
+    print('Exiting with error code: %d' % ec.code)
+    sys.exit(ec.code)
+
+
 def main():
   parser = optparse.OptionParser()
   info = ('The package name. Such as: '
           '--package=com.example.YourPackage')
   parser.add_option('--package', help=info)
-  info = ('The apk name. Such as: --name=YourApplicationName')
+  info = ('The apk name. Such as: --name="Your Application Name"')
   parser.add_option('--name', help=info)
   info = ('The version of the app. Such as: --app-version=TheVersionNumber')
   parser.add_option('--app-version', help=info)
+  info = ('The versionCode of the app. Such as: --app-versionCode=24')
+  parser.add_option('--app-versionCode', type='int', help=info)
   info = ('The application description. Such as:'
           '--description=YourApplicationdDescription')
   parser.add_option('--description', help=info)
-  info = ('The path of icon. Such as: --icon=/path/to/your/customized/icon')
-  parser.add_option('--icon', help=info)
   info = ('The permission list. Such as: --permissions="geolocation"'
           'For more permissions, such as:'
           '--permissions="geolocation:permission2"')
@@ -330,10 +520,12 @@ def main():
   parser.add_option('--app-local-path', help=info)
   parser.add_option('--enable-remote-debugging', action='store_true',
                     dest='enable_remote_debugging', default=False,
-                    help = 'Enable remote debugging.')
+                    help='Enable remote debugging.')
   parser.add_option('-f', '--fullscreen', action='store_true',
                     dest='fullscreen', default=False,
                     help='Make application fullscreen.')
+  parser.add_option('--keep-screen-on', action='store_true', default=False,
+                    help='Support keeping screen on')
   info = ('The path list for external extensions separated by os separator.'
           'On Linux and Mac, the separator is ":". On Windows, it is ";".'
           'Such as: --extensions="/path/to/extension1:/path/to/extension2"')
@@ -344,15 +536,50 @@ def main():
           'http://developer.android.com/guide/topics/manifest/'
           'activity-element.html#screen')
   parser.add_option('--orientation', help=info)
+  parser.add_option('--manifest', help='The manifest path')
+  info = ('Use command lines.'
+          'Crosswalk is powered by Chromium and supports Chromium command line.'
+          'For example, '
+          '--xwalk-command-line=\'--chromium-command-1 --xwalk-command-2\'')
+  parser.add_option('--xwalk-command-line', default='', help=info)
+  info = ('Minify and obfuscate javascript and css.'
+          '--compressor: compress javascript and css.'
+          '--compressor=js: compress javascript.'
+          '--compressor=css: compress css.')
+  parser.add_option('--compressor', dest='compressor', action='callback',
+                    callback=ParseParameterForCompressor,
+                    type='string', nargs=0, help=info)
   options, _ = parser.parse_args()
-  sanitized_name = ReplaceInvalidChars(options.name, 'apkname')
   try:
-    Prepare(options, sanitized_name)
-    CustomizeXML(options, sanitized_name)
-    CustomizeJava(options, sanitized_name)
-    CustomizeExtensions(options, sanitized_name)
-  except SystemExit, ec:
-    print 'Exiting with error code: %d' % ec.code
+    icon_dict = {144: 'icons/icon_144.png',
+                 72: 'icons/icon_72.png',
+                 96: 'icons/icon_96.png',
+                 48: 'icons/icon_48.png'}
+    app_info = AppInfo()
+    if options.name is not None:
+      app_info.android_name = options.name
+    if options.app_root is None:
+      app_info.app_root = os.path.join('test_data', 'manifest')
+    else:
+      app_info.app_root = options.app_root
+    if options.package is not None:
+      app_info.package = options.package
+    if options.orientation is not None:
+      app_info.orientation = options.orientation
+    if options.app_version is not None:
+      app_info.app_version = options.app_version
+    if options.enable_remote_debugging is not None:
+      app_info.remote_debugging = options.enable_remote_debugging
+    if options.fullscreen is not None:
+      app_info.fullscreen_flag = options.fullscreen
+    app_info.icon = os.path.join('test_data', 'manifest', 'icons',
+                                 'icon_96.png')
+    CustomizeAll(app_info, options.description, icon_dict,
+                 options.permissions, options.app_url, options.app_local_path,
+                 options.keep_screen_on, options.extensions, None,
+                 options.xwalk_command_line, options.compressor)
+  except SystemExit as ec:
+    print('Exiting with error code: %d' % ec.code)
     return ec.code
   return 0