#!/usr/bin/env python
#
# Copyright (C) 2008 The Android Open Source Project
#
# 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.
#

"""Creates optimized versions of APK files.

A tool and associated functions to communicate with an Android
emulator instance, run commands, and scrape out files.

Requires at least python2.4.
"""

import array
import datetime
import optparse
import os
import posix
import select
import signal
import struct
import subprocess
import sys
import tempfile
import time
import zlib


_emulator_popen = None
_DEBUG_READ = 1


def EnsureTempDir(path=None):
  """Creates a temporary directory and returns its path.

  Creates any necessary parent directories.

  Args:
    path: If specified, used as the temporary directory.  If not specified,
          a safe temporary path is created.  The caller is responsible for
          deleting the directory.

  Returns:
    The path to the new directory, or None if a problem occurred.
  """
  if path is None:
    path = tempfile.mkdtemp('', 'dexpreopt-')
  elif not os.path.exists(path):
    os.makedirs(path)
  elif not os.path.isdir(path):
    return None
  return path


def CreateZeroedFile(path, length):
  """Creates the named file and writes <length> zero bytes to it.

  Unlinks the file first if it already exists.
  Creates its containing directory if necessary.

  Args:
    path: The path to the file to create.
    length: The number of zero bytes to write to the file.

  Returns:
    True on success.
  """
  subprocess.call(['rm', '-f', path])
  d = os.path.dirname(path)
  if d and not os.path.exists(d): os.makedirs(os.path.dirname(d))
  # TODO: redirect child's stdout to /dev/null
  ret = subprocess.call(['dd', 'if=/dev/zero', 'of=%s' % path,
                         'bs=%d' % length, 'count=1'])
  return not ret  # i.e., ret == 0;  i.e., the child exited successfully.


def StartEmulator(exe_name='emulator', kernel=None,
                  ramdisk=None, image=None, userdata=None, system=None):
  """Runs the emulator with the specified arguments.

  Args:
    exe_name: The name of the emulator to run.  May be absolute, relative,
              or unqualified (and left to exec() to find).
    kernel: If set, passed to the emulator as "-kernel".
    ramdisk: If set, passed to the emulator as "-ramdisk".
    image: If set, passed to the emulator as "-system".
    userdata: If set, passed to the emulator as "-initdata" and "-data".
    system: If set, passed to the emulator as "-sysdir".

  Returns:
    A subprocess.Popen that refers to the emulator process, or None if
    a problem occurred.
  """
  #exe_name = './stuff'
  args = [exe_name]
  if kernel: args += ['-kernel', kernel]
  if ramdisk: args += ['-ramdisk', ramdisk]
  if image: args += ['-system', image]
  if userdata: args += ['-initdata', userdata, '-data', userdata]
  if system: args += ['-sysdir', system]
  args += ['-partition-size', '128']
  args += ['-no-window', '-netfast', '-noaudio']

  _USE_PIPE = True

  if _USE_PIPE:
    # Use dedicated fds instead of stdin/out to talk to the
    # emulator so that the emulator doesn't try to tty-cook
    # the data.
    em_stdin_r, em_stdin_w = posix.pipe()
    em_stdout_r, em_stdout_w = posix.pipe()
    args += ['-shell-serial', 'fdpair:%d:%d' % (em_stdin_r, em_stdout_w)]
  else:
    args += ['-shell']

  # This is a work-around for the ARMv7 emulation bug.
  # XXX: It only works by chance, if any ! A real emulation fix is on the way
  args += ['-qemu', '-singlestep']

  # Ensure that this environment variable isn't set;
  # if it is, the emulator will print the log to stdout.
  if os.environ.get('ANDROID_LOG_TAGS'):
    del os.environ['ANDROID_LOG_TAGS']

  try:
    # bufsize=1 line-buffered, =0 unbuffered,
    # <0 system default (fully buffered)
    Trace('Running emulator: %s' % ' '.join(args))
    if _USE_PIPE:
      ep = subprocess.Popen(args)
    else:
      ep = subprocess.Popen(args, close_fds=True,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    if ep:
      if _USE_PIPE:
        # Hijack the Popen.stdin/.stdout fields to point to our
        # pipes.  These are the same fields that would have been set
        # if we called Popen() with stdin=subprocess.PIPE, etc.
        # Note that these names are from the point of view of the
        # child process.
        #
        # Since we'll be using select.select() to read data a byte
        # at a time, it's important that these files are unbuffered
        # (bufsize=0).  If Popen() took care of the pipes, they're
        # already unbuffered.
        ep.stdin = os.fdopen(em_stdin_w, 'w', 0)
        ep.stdout = os.fdopen(em_stdout_r, 'r', 0)
      return ep
  except OSError, e:
    print >>sys.stderr, 'Could not start emulator:', e
  return None


def IsDataAvailable(fo, timeout=0):
  """Indicates whether or not data is available to be read from a file object.

  Args:
    fo: A file object to read from.
    timeout: The number of seconds to wait for data, or zero for no timeout.

  Returns:
    True iff data is available to be read.
  """
  return select.select([fo], [], [], timeout) == ([fo], [], [])


def ConsumeAvailableData(fo):
  """Reads data from a file object while it's available.

  Stops when no more data is immediately available or upon reaching EOF.

  Args:
    fo: A file object to read from.

  Returns:
    An unsigned byte array.array of the data that was read.
  """
  buf = array.array('B')
  while IsDataAvailable(fo):
    try:
      buf.fromfile(fo, 1)
    except EOFError:
      break
  return buf


def ShowTimeout(timeout, end_time):
    """For debugging, display the timeout info.

    Args:
      timeout: the timeout in seconds.
      end_time: a time.time()-based value indicating when the timeout should
                expire.
    """
    if _DEBUG_READ:
      if timeout:
        remaining = end_time - time.time()
        Trace('ok, time remaining %.1f of %.1f' % (remaining, timeout))
      else:
        Trace('ok (no timeout)')


def WaitForString(inf, pattern, timeout=0, max_len=0, eat_to_eol=True,
                  reset_on_activity=False):
  """Reads from a file object and returns when the pattern matches the data.

  Reads a byte at a time to avoid consuming extra data, so do not call
  this function when you expect the pattern to match a large amount of data.

  Args:
    inf: The file object to read from.
    pattern: The string to look for in the input data.
             May be a tuple of strings.
    timeout: How long to wait, in seconds. No timeout if it evaluates to False.
    max_len: Return None if this many bytes have been read without matching.
             No upper bound if it evaluates to False.
    eat_to_eol: If true, the input data will be consumed until a '\\n' or EOF
                is encountered.
    reset_on_activity: If True, reset the timeout whenever a character is
                       read.

  Returns:
    The input data matching the expression as an unsigned char array,
    or None if the operation timed out or didn't match after max_len bytes.

  Raises:
    IOError: An error occurred reading from the input file.
  """
  if timeout:
    end_time = time.time() + timeout
  else:
    end_time = 0

  if _DEBUG_READ:
    Trace('WaitForString: "%s", %.1f' % (pattern, timeout))

  buf = array.array('B')  # unsigned char array
  eating = False
  while True:
    if end_time:
      remaining = end_time - time.time()
      if remaining <= 0:
        Trace('Timeout expired after %.1f seconds' % timeout)
        return None
    else:
      remaining = None

    if IsDataAvailable(inf, remaining):
      if reset_on_activity and timeout:
        end_time = time.time() + timeout

      buf.fromfile(inf, 1)
      if _DEBUG_READ:
        c = buf.tostring()[-1:]
        ci = ord(c)
        if ci < 0x20: c = '.'
        if _DEBUG_READ > 1:
          print 'read [%c] 0x%02x' % (c, ci)

      if not eating:
        if buf.tostring().endswith(pattern):
          if eat_to_eol:
            if _DEBUG_READ > 1:
              Trace('Matched; eating to EOL')
            eating = True
          else:
            ShowTimeout(timeout, end_time)
            return buf
        if _DEBUG_READ > 2:
          print '/%s/ ? "%s"' % (pattern, buf.tostring())
      else:
        if buf.tostring()[-1:] == '\n':
          ShowTimeout(timeout, end_time)
          return buf

      if max_len and len(buf) >= max_len: return None


def WaitForEmulator(ep, timeout=0):
  """Waits for the emulator to start up and print the first prompt.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    timeout: How long to wait, in seconds. No timeout if it evaluates to False.

  Returns:
    True on success, False if the timeout occurred.
  """
  # Prime the pipe; the emulator doesn't start without this.
  print >>ep.stdin, ''

  # Wait until the console is ready and the first prompt appears.
  buf = WaitForString(ep.stdout, '#', timeout=timeout, eat_to_eol=False)
  if buf:
    Trace('Saw the prompt: "%s"' % buf.tostring())
    return True
  return False


def WaitForPrompt(ep, prompt=None, timeout=0, reset_on_activity=False):
  """Blocks until the prompt appears on ep.stdout or the timeout elapses.

  Args:
    ep: A subprocess.Popen connection to the emulator process.
    prompt: The prompt to wait for.  If None, uses ep.prompt.
    timeout: How many seconds to wait for the prompt.  Waits forever
             if timeout is zero.
    reset_on_activity: If True, reset the timeout whenever a character is
                       read.

  Returns:
    A string containing the data leading up to the prompt.  The string
    will always end in '\\n'.  Returns None if the prompt was not seen
    within the timeout, or if some other error occurred.
  """
  if not prompt: prompt = ep.prompt
  if prompt:
    #Trace('waiting for prompt "%s"' % prompt)
    data = WaitForString(ep.stdout, prompt,
                         timeout=timeout, reset_on_activity=reset_on_activity)
    if data:
      # data contains everything on ep.stdout up to and including the prompt,
      # plus everything up 'til the newline.  Scrape out the prompt
      # and everything that follows, and ensure that the result ends
      # in a newline (which is important if it would otherwise be empty).
      s = data.tostring()
      i = s.rfind(prompt)
      s = s[:i]
      if s[-1:] != '\n':
        s += '\n'
      if _DEBUG_READ:
        print 'WaitForPrompt saw """\n%s"""' % s
      return s
  return None


def ReplaceEmulatorPrompt(ep, prompt=None):
  """Replaces PS1 in the emulator with a different value.

  This is useful for making the prompt unambiguous; i.e., something
  that probably won't appear in the output of another command.

  Assumes that the emulator is already sitting at a prompt,
  waiting for shell input.

  Puts the new prompt in ep.prompt.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    prompt: The new prompt to use

  Returns:
    True on success, False if the timeout occurred.
  """
  if not prompt:
    prompt = '-----DEXPREOPT-PROMPT-----'
  print >>ep.stdin, 'PS1="%s\n"' % prompt
  ep.prompt = prompt

  # Eat the command echo.
  data = WaitForPrompt(ep, timeout=2)
  if not data:
    return False

  # Make sure it's actually there.
  return WaitForPrompt(ep, timeout=2)


def RunEmulatorCommand(ep, cmd, timeout=0):
  """Sends the command to the emulator's shell and waits for the result.

  Assumes that the emulator is already sitting at a prompt,
  waiting for shell input.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    cmd: The shell command to run in the emulator.
    timeout: The number of seconds to wait for the command to complete,
             or zero for no timeout.

  Returns:
    If the command ran and returned to the console prompt before the
    timeout, returns the output of the command as a string.
    Returns None otherwise.
  """
  ConsumeAvailableData(ep.stdout)

  Trace('Running "%s"' % cmd)
  print >>ep.stdin, '%s' % cmd

  # The console will echo the command.
  #Trace('Waiting for echo')
  if WaitForString(ep.stdout, cmd, timeout=timeout):
    #Trace('Waiting for completion')
    return WaitForPrompt(ep, timeout=timeout, reset_on_activity=True)

  return None


def ReadFileList(ep, dir_list, timeout=0):
  """Returns a list of emulator files in each dir in dir_list.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    dir_list: List absolute paths to directories to read.
    timeout: The number of seconds to wait for the command to complete,
             or zero for no timeout.

  Returns:
    A list of absolute paths to files in the named directories,
    in the context of the emulator's filesystem.
    None on failure.
  """
  ret = []
  for d in dir_list:
    output = RunEmulatorCommand(ep, 'ls ' + d, timeout=timeout)
    if not output:
      Trace('Could not ls ' + d)
      return None
    ret += ['%s/%s' % (d, f) for f in output.splitlines()]
  return ret


def DownloadDirectoryHierarchy(ep, src, dest, timeout=0):
  """Recursively downloads an emulator directory to the local filesystem.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    src: The path on the emulator's filesystem to download from.
    dest: The path on the local filesystem to download to.
    timeout: The number of seconds to wait for the command to complete,
             or zero for no timeout. (CURRENTLY IGNORED)

  Returns:
    True iff the files downloaded successfully, False otherwise.
  """
  ConsumeAvailableData(ep.stdout)

  if not os.path.exists(dest):
    os.makedirs(dest)

  cmd = 'afar %s' % src
  Trace('Running "%s"' % cmd)
  print >>ep.stdin, '%s' % cmd

  # The console will echo the command.
  #Trace('Waiting for echo')
  if not WaitForString(ep.stdout, cmd, timeout=timeout):
    return False

  #TODO: use a signal to support timing out?

  #
  # Android File Archive format:
  #
  # magic[5]: 'A' 'F' 'A' 'R' '\n'
  # version[4]: 0x00 0x00 0x00 0x01
  # for each file:
  #     file magic[4]: 'F' 'I' 'L' 'E'
  #     namelen[4]: Length of file name, including NUL byte (big-endian)
  #     name[*]: NUL-terminated file name
  #     datalen[4]: Length of file (big-endian)
  #     data[*]: Unencoded file data
  #     adler32[4]: adler32 of the unencoded file data (big-endian)
  #     file end magic[4]: 'f' 'i' 'l' 'e'
  # end magic[4]: 'E' 'N' 'D' 0x00
  #

  # Read the header.
  HEADER = array.array('B', 'AFAR\n\000\000\000\001')
  buf = array.array('B')
  buf.fromfile(ep.stdout, len(HEADER))
  if buf != HEADER:
    Trace('Header does not match: "%s"' % buf)
    return False

  # Read the file entries.
  FILE_START = array.array('B', 'FILE')
  FILE_END = array.array('B', 'file')
  END = array.array('B', 'END\000')
  while True:
    # Entry magic.
    buf = array.array('B')
    buf.fromfile(ep.stdout, 4)
    if buf == FILE_START:
      # Name length (4 bytes, big endian)
      buf = array.array('B')
      buf.fromfile(ep.stdout, 4)
      (name_len,) = struct.unpack('>I', buf)
      #Trace('name len %d' % name_len)

      # Name, NUL-terminated.
      buf = array.array('B')
      buf.fromfile(ep.stdout, name_len)
      buf.pop()  # Remove trailing NUL byte.
      file_name = buf.tostring()
      Trace('FILE: %s' % file_name)

      # File length (4 bytes, big endian)
      buf = array.array('B')
      buf.fromfile(ep.stdout, 4)
      (file_len,) = struct.unpack('>I', buf)

      # File data.
      data = array.array('B')
      data.fromfile(ep.stdout, file_len)
      #Trace('FILE: read %d bytes from %s' % (file_len, file_name))

      # adler32 (4 bytes, big endian)
      buf = array.array('B')
      buf.fromfile(ep.stdout, 4)
      (adler32,) = struct.unpack('>i', buf)  # adler32 wants a signed int ('i')
      data_adler32 = zlib.adler32(data)
      # Because of a difference in behavior of zlib.adler32 on 32-bit and 64-bit
      # systems (one returns signed values, the other unsigned), we take the
      # modulo 2**32 of the checksums, and compare those.
      # See also http://bugs.python.org/issue1202
      if (adler32 % (2**32)) != (data_adler32 % (2**32)):
        Trace('adler32 does not match: calculated 0x%08x != expected 0x%08x' %
              (data_adler32, adler32))
        return False

      # File end magic.
      buf = array.array('B')
      buf.fromfile(ep.stdout, 4)
      if buf != FILE_END:
        Trace('Unexpected file end magic "%s"' % buf)
        return False

      # Write to the output file
      out_file_name = dest + '/' + file_name[len(src):]
      p = os.path.dirname(out_file_name)
      if not os.path.exists(p): os.makedirs(p)
      fo = file(out_file_name, 'w+b')
      fo.truncate(0)
      Trace('FILE: Writing %d bytes to %s' % (len(data), out_file_name))
      data.tofile(fo)
      fo.close()

    elif buf == END:
      break
    else:
      Trace('Unexpected magic "%s"' % buf)
      return False

  return WaitForPrompt(ep, timeout=timeout, reset_on_activity=True)


def ReadBootClassPath(ep, timeout=0):
  """Reads and returns the default bootclasspath as a list of files.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    timeout: The number of seconds to wait for the command to complete,
             or zero for no timeout.

  Returns:
    The bootclasspath as a list of strings.
    None on failure.
  """
  bcp = RunEmulatorCommand(ep, 'echo $BOOTCLASSPATH', timeout=timeout)
  if not bcp:
    Trace('Could not find bootclasspath')
    return None
  return bcp.strip().split(':')  # strip trailing newline


def RunDexoptOnFileList(ep, files, dest_root, move=False, timeout=0):
  """Creates the corresponding .odex file for all jar/apk files in 'files'.
  Copies the .odex file to a location under 'dest_root'.  If 'move' is True,
  the file is moved instead of copied.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    files: The list of files to optimize
    dest_root: directory to copy/move odex files to.  Must already exist.
    move: if True, move rather than copy files
    timeout: The number of seconds to wait for the command to complete,
             or zero for no timeout.

  Returns:
    True on success, False on failure.
  """
  for jar_file in files:
    if jar_file.endswith('.apk') or jar_file.endswith('.jar'):
      odex_file = jar_file[:jar_file.rfind('.')] + '.odex'
      cmd = 'dexopt-wrapper %s %s' % (jar_file, odex_file)
      if not RunEmulatorCommand(ep, cmd, timeout=timeout):
        Trace('"%s" failed' % cmd)
        return False

      # Always copy the odex file.  There's no cp(1), so we
      # cat out to the new file.
      dst_odex = dest_root + odex_file
      cmd = 'cat %s > %s' % (odex_file, dst_odex)  # no cp(1)
      if not RunEmulatorCommand(ep, cmd, timeout=timeout):
        Trace('"%s" failed' % cmd)
        return False

      # Move it if we're asked to.  We can't use mv(1) because
      # the files tend to move between filesystems.
      if move:
        cmd = 'rm %s' % odex_file
        if not RunEmulatorCommand(ep, cmd, timeout=timeout):
          Trace('"%s" failed' % cmd)
          return False
  return True


def InstallCacheFiles(cache_system_dir, out_system_dir):
  """Install files in cache_system_dir to the proper places in out_system_dir.

  cache_system_dir contains various files from /system, plus .odex files
  for most of the .apk/.jar files that live there.
  This function copies each .odex file from the cache dir to the output dir
  and removes "classes.dex" from each appropriate .jar/.apk.

  E.g., <cache_system_dir>/app/NotePad.odex would be copied to
  <out_system_dir>/app/NotePad.odex, and <out_system_dir>/app/NotePad.apk
  would have its classes.dex file removed.

  Args:
    cache_system_dir: The directory containing the cache files scraped from
                      the emulator.
    out_system_dir: The local directory that corresponds to "/system"
                    on the device filesystem. (the root of system.img)

  Returns:
    True if everything succeeded, False if any problems occurred.
  """
  # First, walk through cache_system_dir and copy every .odex file
  # over to out_system_dir, ensuring that the destination directory
  # contains the corresponding source file.
  for root, dirs, files in os.walk(cache_system_dir):
    for name in files:
      if name.endswith('.odex'):
        odex_file = os.path.join(root, name)

        # Find the path to the .odex file's source apk/jar file.
        out_stem = odex_file[len(cache_system_dir):odex_file.rfind('.')]
        out_stem = out_system_dir + out_stem;
        jar_file = out_stem + '.jar'
        if not os.path.exists(jar_file):
          jar_file = out_stem + '.apk'
        if not os.path.exists(jar_file):
          Trace('Cannot find source .jar/.apk for %s: %s' %
                (odex_file, out_stem + '.{jar,apk}'))
          return False

        # Copy the cache file next to the source file.
        cmd = ['cp', odex_file, out_stem + '.odex']
        ret = subprocess.call(cmd)
        if ret:  # non-zero exit status
          Trace('%s failed' % ' '.join(cmd))
          return False

  # Walk through the output /system directory, making sure
  # that every .jar/.apk has an odex file.  While we do this,
  # remove the classes.dex entry from each source archive.
  for root, dirs, files in os.walk(out_system_dir):
    for name in files:
      if name.endswith('.apk') or name.endswith('.jar'):
        jar_file = os.path.join(root, name)
        odex_file = jar_file[:jar_file.rfind('.')] + '.odex'
        if not os.path.exists(odex_file):
          if root.endswith('/system/app') or root.endswith('/system/framework'):
            Trace('jar/apk %s has no .odex file %s' % (jar_file, odex_file))
            return False
          else:
            continue

        # Attempting to dexopt a jar with no classes.dex currently
        # creates a 40-byte odex file.
        # TODO: use a more reliable check
        if os.path.getsize(odex_file) > 100:
          # Remove classes.dex from the .jar file.
          cmd = ['zip', '-dq', jar_file, 'classes.dex']
          ret = subprocess.call(cmd)
          if ret:  # non-zero exit status
            Trace('"%s" failed' % ' '.join(cmd))
            return False
        else:
          # Some of the apk files don't contain any code.
          if not name.endswith('.apk'):
            Trace('%s has a zero-length odex file' % jar_file)
            return False
          cmd = ['rm', odex_file]
          ret = subprocess.call(cmd)
          if ret:  # non-zero exit status
            Trace('"%s" failed' % ' '.join(cmd))
            return False

  return True


def KillChildProcess(p, sig=signal.SIGTERM, timeout=0):
  """Waits for a child process to die without getting stuck in wait().

  After Jean Brouwers's 2004 post to python-list.

  Args:
    p: A subprocess.Popen representing the child process to kill.
    sig: The signal to send to the child process.
    timeout: How many seconds to wait for the child process to die.
             If zero, do not time out.

  Returns:
    The exit status of the child process, if it was successfully killed.
    The final value of p.returncode if it wasn't.
  """
  os.kill(p.pid, sig)
  if timeout > 0:
    while p.poll() < 0:
      if timeout > 0.5:
        timeout -= 0.25
        time.sleep(0.25)
      else:
        os.kill(p.pid, signal.SIGKILL)
        time.sleep(0.5)
        p.poll()
        break
  else:
    p.wait()
  return p.returncode


def Trace(msg):
  """Prints a message to stdout.

  Args:
    msg: The message to print.
  """
  #print 'dexpreopt: %s' % msg
  when = datetime.datetime.now()
  print '%02d:%02d.%d  dexpreopt: %s' % (when.minute, when.second, when.microsecond, msg)


def KillEmulator():
  """Attempts to kill the emulator process, if it is running.

  Returns:
    The exit status of the emulator process, or None if the emulator
    was not running or was unable to be killed.
  """
  global _emulator_popen
  if _emulator_popen:
    Trace('Killing emulator')
    try:
      ret = KillChildProcess(_emulator_popen, sig=signal.SIGINT, timeout=5)
    except OSError:
      Trace('Could not kill emulator')
      ret = None
    _emulator_popen = None
    return ret
  return None


def Fail(msg=None):
  """Prints an error and causes the process to exit.

  Args:
    msg: Additional error string to print (optional).

  Returns:
    Does not return.
  """
  s = 'dexpreopt: ERROR'
  if msg: s += ': %s' % msg
  print >>sys.stderr, msg
  KillEmulator()
  sys.exit(1)


def PrintUsage(msg=None):
  """Prints commandline usage information for the tool and exits with an error.

  Args:
    msg: Additional string to print (optional).

  Returns:
    Does not return.
  """
  if msg:
    print >>sys.stderr, 'dexpreopt: %s', msg
  print >>sys.stderr, """Usage: dexpreopt <options>
Required options:
    -kernel <kernel file>         Kernel to use when running the emulator
    -ramdisk <ramdisk.img file>   Ramdisk to use when running the emulator
    -image <system.img file>      System image to use when running the
                                      emulator.  /system/app should contain the
                                      .apk files to optimize, and any required
                                      bootclasspath libraries must be present
                                      in the correct locations.
    -system <path>                The product directory, which usually contains
                                      files like 'system.img' (files other than
                                      the kernel in that directory won't
                                      be used)
    -outsystemdir <path>          A fully-populated /system directory, ready
                                      to be modified to contain the optimized
                                      files.  The appropriate .jar/.apk files
                                      will be stripped of their classes.dex
                                      entries, and the optimized .dex files
                                      will be added alongside the packages
                                      that they came from.
Optional:
    -tmpdir <path>                If specified, use this directory for
                                      intermediate objects.  If not specified,
                                      a unique directory under the system
                                      temp dir is used.
  """
  sys.exit(2)


def ParseArgs(argv):
  """Parses commandline arguments.

  Args:
    argv: A list of arguments; typically sys.argv[1:]

  Returns:
    A tuple containing two dictionaries; the first contains arguments
    that will be passsed to the emulator, and the second contains other
    arguments.
  """
  parser = optparse.OptionParser()

  parser.add_option('--kernel', help='Passed to emulator')
  parser.add_option('--ramdisk', help='Passed to emulator')
  parser.add_option('--image', help='Passed to emulator')
  parser.add_option('--system', help='Passed to emulator')
  parser.add_option('--outsystemdir', help='Destination /system directory')
  parser.add_option('--tmpdir', help='Optional temp directory to use')

  options, args = parser.parse_args(args=argv)
  if args: PrintUsage()

  emulator_args = {}
  other_args = {}
  if options.kernel: emulator_args['kernel'] = options.kernel
  if options.ramdisk: emulator_args['ramdisk'] = options.ramdisk
  if options.image: emulator_args['image'] = options.image
  if options.system: emulator_args['system'] = options.system
  if options.outsystemdir: other_args['outsystemdir'] = options.outsystemdir
  if options.tmpdir: other_args['tmpdir'] = options.tmpdir

  return (emulator_args, other_args)


def DexoptEverything(ep, dest_root):
  """Logic for finding and dexopting files in the necessary order.

  Args:
    ep: A subprocess.Popen object referring to the emulator process.
    dest_root: directory to copy/move odex files to

  Returns:
    True on success, False on failure.
  """
  _extra_tests = False
  if _extra_tests:
    if not RunEmulatorCommand(ep, 'ls /system/app', timeout=5):
      Fail('Could not ls')

  # We're very short on space, so remove a bunch of big stuff that we
  # don't need.
  cmd = 'rm -r /system/sounds /system/media /system/fonts /system/xbin'
  if not RunEmulatorCommand(ep, cmd, timeout=40):
    Trace('"%s" failed' % cmd)
    return False

  Trace('Read file list')
  jar_dirs = ['/system/framework', '/system/app']
  files = ReadFileList(ep, jar_dirs, timeout=5)
  if not files:
    Fail('Could not list files in %s' % ' '.join(jar_dirs))
  #Trace('File list:\n"""\n%s\n"""' % '\n'.join(files))

  bcp = ReadBootClassPath(ep, timeout=2)
  if not files:
    Fail('Could not sort by bootclasspath')

  # Remove bootclasspath entries from the main file list.
  for jar in bcp:
    try:
      files.remove(jar)
    except ValueError:
      Trace('File list does not contain bootclasspath entry "%s"' % jar)
      return False

  # Create the destination directories.
  for d in ['', '/system'] + jar_dirs:
    cmd = 'mkdir %s%s' % (dest_root, d)
    if not RunEmulatorCommand(ep, cmd, timeout=4):
      Trace('"%s" failed' % cmd)
      return False

  # First, dexopt the bootclasspath.  Keep their cache files in place.
  Trace('Dexopt %d bootclasspath files' % len(bcp))
  if not RunDexoptOnFileList(ep, bcp, dest_root, timeout=120):
    Trace('Could not dexopt bootclasspath')
    return False

  # dexopt the rest.  To avoid running out of space on the emulator
  # volume, move each cache file after it's been created.
  Trace('Dexopt %d files' % len(files))
  if not RunDexoptOnFileList(ep, files, dest_root, move=True, timeout=120):
    Trace('Could not dexopt files')
    return False

  if _extra_tests:
    if not RunEmulatorCommand(ep, 'ls /system/app', timeout=5):
      Fail('Could not ls')

  return True



def MainInternal():
  """Main function that can be wrapped in a try block.

  Returns:
    Nothing.
  """
  emulator_args, other_args = ParseArgs(sys.argv[1:])

  tmp_dir = EnsureTempDir(other_args.get('tmpdir'))
  if not tmp_dir: Fail('Could not create temp dir')

  Trace('Creating data image')
  userdata = '%s/data.img' % tmp_dir
  if not CreateZeroedFile(userdata, 32 * 1024 * 1024):
    Fail('Could not create data image file')
  emulator_args['userdata'] = userdata

  ep = StartEmulator(**emulator_args)
  if not ep: Fail('Could not start emulator')
  global _emulator_popen
  _emulator_popen = ep

  # TODO: unlink the big userdata file now, since the emulator
  # has it open.

  if not WaitForEmulator(ep, timeout=20): Fail('Emulator did not respond')
  if not ReplaceEmulatorPrompt(ep): Fail('Could not replace prompt')

  dest_root = '/data/dexpreopt-root'
  if not DexoptEverything(ep, dest_root): Fail('Could not dexopt files')

  # Grab the odex files that were left in dest_root.
  cache_system_dir = tmp_dir + '/cache-system'
  if not DownloadDirectoryHierarchy(ep, dest_root + '/system',
                                    cache_system_dir,
                                    timeout=20):
    Fail('Could not download %s/system from emulator' % dest_root)

  if not InstallCacheFiles(cache_system_dir=cache_system_dir,
                           out_system_dir=other_args['outsystemdir']):
    Fail('Could not install files')

  Trace('dexpreopt successful')
  # Success!


def main():
  try:
    MainInternal()
  finally:
    KillEmulator()


if __name__ == '__main__':
  main()
