Merge tag android-5.1.0_r1 into AOSP_5.1_MERGE

Change-Id: If83121d50c15c11988a2a135356290e82fb9e96e
diff --git a/apps/CameraITS/.gitignore b/apps/CameraITS/.gitignore
deleted file mode 100644
index 259969b..0000000
--- a/apps/CameraITS/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-# Ignore files that are created asa result of running the ITS tests.
-
-*.json
-*.yuv
-*.jpg
-*.jpeg
-*.png
-*.pyc
-its.target.cfg
-.DS_Store
-
diff --git a/apps/CameraITS/Android.mk b/apps/CameraITS/Android.mk
deleted file mode 100644
index cc40202..0000000
--- a/apps/CameraITS/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2013 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.
-#
-
-#
-# Build the ItsService and any other device packages
-#
-include $(call all-subdir-makefiles)
-
-
diff --git a/apps/CameraITS/README b/apps/CameraITS/README
deleted file mode 100644
index c7b786c..0000000
--- a/apps/CameraITS/README
+++ /dev/null
@@ -1,286 +0,0 @@
-# Copyright 2013 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.
-
-
-Android Camera Imaging Test Suite (ITS)
-=======================================
-
-1. Introduction
----------------
-
-The ITS is a framework for running tests on the images produced by an Android
-camera. The general goal of each test is to configure the camera in a desired
-manner and capture one or more shots, and then examine the shots to see if
-they contain the expected image data. Many of the tests will require that the
-camera is pointed at a specific target chart or be illuminated at a specific
-intensity.
-
-2. Setup
---------
-
-There are two components to the ITS:
-1. The Android device running ItsService.apk.
-2. A host machine connected to the Android device that runs Python tests.
-
-2.1. Device setup
------------------
-
-Build and install ItsService.apk for your device. After setting up your
-shell for Android builds, from the pdk/apps/CameraITS directory run the
-following commands:
-
-    cd service
-    mma -j32
-    adb install -r <YOUR_OUTPUT_PATH>/ItsService.apk
-
-using whatever path is appropriate to your output ItsService.apk file.
-
-2.2. Host PC setup
-------------------
-
-The first pre-requisite is the Android SDK, as adb is used to communicate with
-the device.
-
-The test framework is based on Python on the host machine. It requires
-Python 2.7 and the scipy/numpy stack, including the Python Imaging Library.
-
-(For Ubuntu users)
-
-    sudo apt-get install python-numpy python-scipy python-matplotlib
-
-(For other users)
-
-All of these pieces can be installed on your host machine separately,
-however it is highly recommended to install a bundled distribution of
-Python that comes with these modules. Some different bundles are listed
-here:
-
-    http://www.scipy.org/install.html
-
-Of these, Anaconda has been verified to work with these scripts, and it is
-available on Mac, Linux, and Windows from here:
-
-    http://continuum.io/downloads
-
-Note that the Anaconda python executable's directory must be at the front of
-your PATH environment variable, assuming that you are using this Python
-distribution. The Anaconda installer may set this up for you automatically.
-
-Once your Python installation is ready, set up the test environment.
-
-2.2.1. Linux + Mac OS X
------------------------
-
-On Linux or Mac OS X, run the following command (in a terminal) from the
-pdk/apps/CameraITS directory, from a bash shell:
-
-    source build/envsetup.sh
-
-This will do some basic sanity checks on your Python installation, and set up
-the PYTHONPATH environment variable.
-
-2.2.2. Windows
---------------
-
-On Windows, the bash script won't run (unless you have cygwin (which has not
-been tested)), but all you need to do is set your PYTHONPATH environment
-variable in your shell to point to the pdk/apps/CameraITS/pymodules directory,
-giving an absolute path. Without this, you'll get "import" errors when running
-the test scripts.
-
-3. Python framework overview
-----------------------------
-
-The Python modules are under the pymodules directory, in the "its" package.
-
-* its.device: encapsulates communication with ItsService.apk service running
-  on the device
-* its.objects: contains a collection of functions for creating Python objects
-  corresponding to the Java objects which ItsService.apk uses
-* its.image: contains a collection of functions (built on numpy arrays) for
-  processing captured images
-* its.error: the exception/error class used in this framework
-* its.target: functions to set and measure the exposure level to use for
-  manual shots in tests, to ensure that the images are exposed well for the
-  target scene
-* its.dng: functions to work with DNG metadata
-
-All of these module have associated unit tests; to run the unit tests, execute
-the modules (rather than importing them).
-
-3.1. Device control
--------------------
-
-The its.device.ItsSession class encapsulates a session with a connected device
-under test (which is running ItsService.apk). The session is over TCP, which is
-forwarded over adb.
-
-As an overview, the ItsSession.do_capture() function takes a Python dictionary
-object as an argument, converts that object to JSON, and sends it to the
-device over tcp which then deserializes from the JSON object representation to
-Camera2 Java objects (CaptureRequests) which are used to specify one or more
-captures. Once the captures are complete, the resultant images are copied back
-to the host machine (over tcp again), along with JSON representations of the
-CaptureResult and other objects that describe the shot that was actually taken.
-
-The Python capture request object(s) can contain key/value entries corresponding
-to any of the Java CaptureRequest object fields.
-
-The output surface's width, height, and format can also be specified. Currently
-supported formats are "jpg", "raw", "raw10", "dng", and "yuv", where "yuv" is
-YUV420 fully planar. The default output surface is a full sensor YUV420 frame.
-
-The metadata that is returned along with the captured images is also in JSON
-format, serialized from the CaptureRequest and CaptureResult objects that were
-passed to the capture listener, as well as the CameraProperties object.
-
-3.2. Image processing and analysis
-----------------------------------
-
-The its.image module is a collection of Python functions, built on top of numpy
-arrays, for manipulating captured images. Some functions of note include:
-
-    load_yuv420_to_rgb_image
-    apply_lut_to_image
-    apply_matrix_to_image
-    write_image
-
-The scripts in the tests directory make use of these modules.
-
-Note that it's important to do heavy image processing using the efficient numpy
-ndarray operations, rather than writing complex loops in standard Python to
-process pixels. Refer to online docs and examples of numpy for information on
-this.
-
-3.3. Tests
-----------
-
-The tests directory contains a number of self-contained test scripts. All
-tests should pass if the tree is in a good state.
-
-Most of the tests save various files in the current directory. To have all the
-output files put into a separate directory, run the script from that directory,
-for example:
-
-    mkdir out
-    cd out
-    python ../tests/scene1/test_linearity.py
-
-Any test can be specified to reboot the camera prior to capturing any shots, by
-adding a "reboot" or "reboot=N" command line argument, where N is the number of
-seconds to wait after rebooting the device before sending any commands; the
-default is 30 seconds.
-
-    python tests/scene1/test_linearity.py reboot
-    python tests/scene1/test_linearity.py reboot=20
-
-It's possible that a test could leave the camera in a bad state, in particular
-if there are any bugs in the HAL or the camera framework. Rebooting the device
-can be used to get it into a known clean state again.
-
-Each test assumes some sort of target or scene. There are multiple scene<N>
-folders under the tests directory, and each contains a README file which
-describes the scene for the scripts in that folder.
-
-By default, camera device id=0 is opened when the script connects to the unit,
-however this can be specified by adding a "camera=1" or similar argument to
-the script command line. On a typical device, camera=0 is the main (rear)
-camera, and camera=1 is the front-facing camera.
-
-    python tests/scene1/test_linearity.py camera=1
-
-The tools/run_all_tests.py script should be executed from the top-level
-CameraITS directory, and it will run all of the tests in an automated fashion,
-saving the generated output files along with the stdout and stderr dumps to
-a temporary directory.
-
-    python tools/run_all_tests.py
-
-This can be run with the "noinit" argument, and in general any args provided
-to this command line will be passed to each script as it is executed.
-
-The tests/inprog directory contains a mix of unfinished, in-progress, and
-incomplete tests. These may or may not be useful in testing a HAL impl.,
-and as these tests are copmleted they will be moved into the scene<N> folders.
-
-When running individual tests from the command line (as in the examples here),
-each test run will ensure that the ItsService is running on the device and is
-ready to accept TCP connections. When using a separate test harness to control
-this infrastructure, the "noinit" command line argument can be provided to
-skip this step; in this case, the test will just try to open a socket to the
-service on the device, and will fail if it's not running and ready.
-
-    python tests/scene1/test_linearity.py noinit
-
-3.4. Target exposure
---------------------
-
-The tools/config.py script is a wrapper for the its.target module, which is
-used to set an exposure level based on the scene that the camera is imaging.
-The purpose of this is to be able to have tests which use hard-coded manual
-exposure controls, while at the same time ensuring that the captured images
-are properly exposed for the test (and aren't clamped to white or black).
-
-If no argument is provided, the script will use the camera to measure the
-scene to determine the exposure level. An argument can be provided to hard-
-code the exposure level.
-
-    python tools/config.py
-    python tools/config.py 16531519962
-
-This creates a file named its.target.cfg in the current directory, storing the
-target exposure level. Tests that use the its.target module will be reusing
-this value, if they are run from the same directory and if they contain the
-"target" command line argument:
-
-    python tests/scene1/test_linearity.py target
-
-If the "target" argument isn't present, then the script won't use any cached
-its.target.cfg values that may be present in the current directory.
-
-3.5. Docs
----------
-
-The pydoc tool can generate HTML docs for the ITS Python modules, using the
-following command (run after PYTHONPATH has been set up as described above):
-
-    pydoc -w its its.device its.image its.error its.objects its.dng its.target
-
-There is a tutorial script in the tests folder (named tutorial.py). It
-illustrates a number of the its.image and its.device primitives, and shows
-how to work with image data in general using this infrastructure. (Its code
-is commented with explanatory remarks.)
-
-    python tests/tutorial.py
-
-3.6. List of command line args
----------------------------------
-
-The above doc sections describe the following command line arguments that may
-be provided when running a test:
-
-    reboot
-    reboot=N
-    target
-    noinit
-    camera=N
-
-4. Known issues
----------------
-
-The Python test scripts don't work if multiple devices are connected to the
-host machine; currently, the its.device module uses a simplistic "adb -d"
-approach to communicating with the device, assuming that there is only one
-device connected. Fixing this is a TODO.
-
diff --git a/apps/CameraITS/build/envsetup.sh b/apps/CameraITS/build/envsetup.sh
deleted file mode 100644
index a95c445..0000000
--- a/apps/CameraITS/build/envsetup.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 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.
-
-# This file should be sourced from bash. Sets environment variables for
-# running tests, and also checks that a number of dependences are present
-# and that the unit tests for the modules passed (indicating that the setup
-# is correct).
-
-[[ "${BASH_SOURCE[0]}" != "${0}" ]] || \
-    { echo ">> Script must be sourced with 'source $0'" >&2; exit 1; }
-
-command -v adb >/dev/null 2>&1 || \
-    echo ">> Require adb executable to be in path" >&2
-
-command -v python >/dev/null 2>&1 || \
-    echo ">> Require python executable to be in path" >&2
-
-python -V 2>&1 | grep -q "Python 2.7" || \
-    echo ">> Require python 2.7" >&2
-
-for M in numpy PIL Image matplotlib pylab
-do
-    python -c "import $M" >/dev/null 2>&1 || \
-        echo ">> Require Python $M module" >&2
-done
-
-export PYTHONPATH="$PWD/pymodules:$PYTHONPATH"
-
-for M in device objects image caps dng target error
-do
-    python "pymodules/its/$M.py" 2>&1 | grep -q "OK" || \
-        echo ">> Unit test for $M failed" >&2
-done
-
diff --git a/apps/CameraITS/pymodules/its/__init__.py b/apps/CameraITS/pymodules/its/__init__.py
deleted file mode 100644
index 59058be..0000000
--- a/apps/CameraITS/pymodules/its/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2013 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.
-
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
deleted file mode 100644
index 6caebc0..0000000
--- a/apps/CameraITS/pymodules/its/caps.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright 2014 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.
-
-import unittest
-import its.objects
-
-def full(props):
-    """Returns whether a device is a FULL capability camera2 device.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return props.has_key("android.info.supportedHardwareLevel") and \
-           props["android.info.supportedHardwareLevel"] == 1
-
-def limited(props):
-    """Returns whether a device is a LIMITED capability camera2 device.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return props.has_key("android.info.supportedHardwareLevel") and \
-           props["android.info.supportedHardwareLevel"] == 0
-
-def legacy(props):
-    """Returns whether a device is a LEGACY capability camera2 device.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return props.has_key("android.info.supportedHardwareLevel") and \
-           props["android.info.supportedHardwareLevel"] == 2
-
-def manual_sensor(props):
-    """Returns whether a device supports MANUAL_SENSOR capabilities.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return    props.has_key("android.request.availableCapabilities") and \
-              1 in props["android.request.availableCapabilities"] \
-           or full(props)
-
-def manual_post_proc(props):
-    """Returns whether a device supports MANUAL_POST_PROCESSING capabilities.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return    props.has_key("android.request.availableCapabilities") and \
-              2 in props["android.request.availableCapabilities"] \
-           or full(props)
-
-def raw(props):
-    """Returns whether a device supports RAW capabilities.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return props.has_key("android.request.availableCapabilities") and \
-           3 in props["android.request.availableCapabilities"]
-
-def raw16(props):
-    """Returns whether a device supports RAW16 output.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return len(its.objects.get_available_output_sizes("raw", props)) > 0
-
-def raw10(props):
-    """Returns whether a device supports RAW10 output.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return len(its.objects.get_available_output_sizes("raw10", props)) > 0
-
-def sensor_fusion(props):
-    """Returns whether the camera and motion sensor timestamps for the device
-    are in the same time domain and can be compared direcctly.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return props.has_key("android.sensor.info.timestampSource") and \
-           props["android.sensor.info.timestampSource"] == 1
-
-def read_3a(props):
-    """Return whether a device supports reading out the following 3A settings:
-        sensitivity
-        exposure time
-        awb gain
-        awb cct
-        focus distance
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    # TODO: check available result keys explicitly
-    return manual_sensor(props) and manual_post_proc(props)
-
-def compute_target_exposure(props):
-    """Return whether a device supports target exposure computation in its.target module.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        Boolean.
-    """
-    return manual_sensor(props) and manual_post_proc(props)
-
-class __UnitTest(unittest.TestCase):
-    """Run a suite of unit tests on this module.
-    """
-    # TODO: Add more unit tests.
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
deleted file mode 100644
index 96c8618..0000000
--- a/apps/CameraITS/pymodules/its/device.py
+++ /dev/null
@@ -1,522 +0,0 @@
-# Copyright 2013 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.
-
-import its.error
-import os
-import os.path
-import sys
-import re
-import json
-import time
-import unittest
-import socket
-import subprocess
-import hashlib
-import numpy
-
-class ItsSession(object):
-    """Controls a device over adb to run ITS scripts.
-
-    The script importing this module (on the host machine) prepares JSON
-    objects encoding CaptureRequests, specifying sets of parameters to use
-    when capturing an image using the Camera2 APIs. This class encapsualtes
-    sending the requests to the device, monitoring the device's progress, and
-    copying the resultant captures back to the host machine when done. TCP
-    forwarded over adb is the transport mechanism used.
-
-    The device must have ItsService.apk installed.
-
-    Attributes:
-        sock: The open socket.
-    """
-
-    # Open a connection to localhost:6000, forwarded to port 6000 on the device.
-    # TODO: Support multiple devices running over different TCP ports.
-    IPADDR = '127.0.0.1'
-    PORT = 6000
-    BUFFER_SIZE = 4096
-
-    # Seconds timeout on each socket operation.
-    SOCK_TIMEOUT = 10.0
-
-    PACKAGE = 'com.android.camera2.its'
-    INTENT_START = 'com.android.camera2.its.START'
-
-    # Definitions for some of the common output format options for do_capture().
-    # Each gets images of full resolution for each requested format.
-    CAP_RAW = {"format":"raw"}
-    CAP_DNG = {"format":"dng"}
-    CAP_YUV = {"format":"yuv"}
-    CAP_JPEG = {"format":"jpeg"}
-    CAP_RAW_YUV = [{"format":"raw"}, {"format":"yuv"}]
-    CAP_DNG_YUV = [{"format":"dng"}, {"format":"yuv"}]
-    CAP_RAW_JPEG = [{"format":"raw"}, {"format":"jpeg"}]
-    CAP_DNG_JPEG = [{"format":"dng"}, {"format":"jpeg"}]
-    CAP_YUV_JPEG = [{"format":"yuv"}, {"format":"jpeg"}]
-    CAP_RAW_YUV_JPEG = [{"format":"raw"}, {"format":"yuv"}, {"format":"jpeg"}]
-    CAP_DNG_YUV_JPEG = [{"format":"dng"}, {"format":"yuv"}, {"format":"jpeg"}]
-
-    # Method to handle the case where the service isn't already running.
-    # This occurs when a test is invoked directly from the command line, rather
-    # than as a part of a separate test harness which is setting up the device
-    # and the TCP forwarding.
-    def __pre_init(self):
-        # TODO: Handle multiple connected devices.
-        adb =  "adb -d"
-
-        # This also includes the optional reboot handling: if the user
-        # provides a "reboot" or "reboot=N" arg, then reboot the device,
-        # waiting for N seconds (default 30) before returning.
-        for s in sys.argv[1:]:
-            if s[:6] == "reboot":
-                duration = 30
-                if len(s) > 7 and s[6] == "=":
-                    duration = int(s[7:])
-                print "Rebooting device"
-                _run("%s reboot" % (adb));
-                _run("%s wait-for-device" % (adb))
-                time.sleep(duration)
-                print "Reboot complete"
-
-        # TODO: Figure out why "--user 0" is needed, and fix the problem.
-        _run('%s shell am force-stop --user 0 %s' % (adb, self.PACKAGE))
-        _run(('%s shell am startservice --user 0 -t text/plain '
-              '-a %s') % (adb, self.INTENT_START))
-
-        # Wait until the socket is ready to accept a connection.
-        proc = subprocess.Popen(
-                adb.split() + ["logcat"],
-                stdout=subprocess.PIPE)
-        logcat = proc.stdout
-        while True:
-            line = logcat.readline().strip()
-            if line.find('ItsService ready') >= 0:
-                break
-        proc.kill()
-
-        # Setup the TCP-over-ADB forwarding.
-        _run('%s forward tcp:%d tcp:%d' % (adb,self.PORT,self.PORT))
-
-    def __init__(self):
-        if "noinit" not in sys.argv:
-            self.__pre_init()
-        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.sock.connect((self.IPADDR, self.PORT))
-        self.sock.settimeout(self.SOCK_TIMEOUT)
-        self.__close_camera()
-        self.__open_camera()
-
-    def __del__(self):
-        if hasattr(self, 'sock') and self.sock:
-            self.__close_camera()
-            self.sock.close()
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, type, value, traceback):
-        return False
-
-    def __read_response_from_socket(self):
-        # Read a line (newline-terminated) string serialization of JSON object.
-        chars = []
-        while len(chars) == 0 or chars[-1] != '\n':
-            ch = self.sock.recv(1)
-            if len(ch) == 0:
-                # Socket was probably closed; otherwise don't get empty strings
-                raise its.error.Error('Problem with socket on device side')
-            chars.append(ch)
-        line = ''.join(chars)
-        jobj = json.loads(line)
-        # Optionally read a binary buffer of a fixed size.
-        buf = None
-        if jobj.has_key("bufValueSize"):
-            n = jobj["bufValueSize"]
-            buf = bytearray(n)
-            view = memoryview(buf)
-            while n > 0:
-                nbytes = self.sock.recv_into(view, n)
-                view = view[nbytes:]
-                n -= nbytes
-            buf = numpy.frombuffer(buf, dtype=numpy.uint8)
-        return jobj, buf
-
-    def __open_camera(self):
-        # Get the camera ID to open as an argument.
-        camera_id = 0
-        for s in sys.argv[1:]:
-            if s[:7] == "camera=" and len(s) > 7:
-                camera_id = int(s[7:])
-        cmd = {"cmdName":"open", "cameraId":camera_id}
-        self.sock.send(json.dumps(cmd) + "\n")
-        data,_ = self.__read_response_from_socket()
-        if data['tag'] != 'cameraOpened':
-            raise its.error.Error('Invalid command response')
-
-    def __close_camera(self):
-        cmd = {"cmdName":"close"}
-        self.sock.send(json.dumps(cmd) + "\n")
-        data,_ = self.__read_response_from_socket()
-        if data['tag'] != 'cameraClosed':
-            raise its.error.Error('Invalid command response')
-
-    def do_vibrate(self, pattern):
-        """Cause the device to vibrate to a specific pattern.
-
-        Args:
-            pattern: Durations (ms) for which to turn on or off the vibrator.
-                The first value indicates the number of milliseconds to wait
-                before turning the vibrator on. The next value indicates the
-                number of milliseconds for which to keep the vibrator on
-                before turning it off. Subsequent values alternate between
-                durations in milliseconds to turn the vibrator off or to turn
-                the vibrator on.
-
-        Returns:
-            Nothing.
-        """
-        cmd = {}
-        cmd["cmdName"] = "doVibrate"
-        cmd["pattern"] = pattern
-        self.sock.send(json.dumps(cmd) + "\n")
-        data,_ = self.__read_response_from_socket()
-        if data['tag'] != 'vibrationStarted':
-            raise its.error.Error('Invalid command response')
-
-    def start_sensor_events(self):
-        """Start collecting sensor events on the device.
-
-        See get_sensor_events for more info.
-
-        Returns:
-            Nothing.
-        """
-        cmd = {}
-        cmd["cmdName"] = "startSensorEvents"
-        self.sock.send(json.dumps(cmd) + "\n")
-        data,_ = self.__read_response_from_socket()
-        if data['tag'] != 'sensorEventsStarted':
-            raise its.error.Error('Invalid command response')
-
-    def get_sensor_events(self):
-        """Get a trace of all sensor events on the device.
-
-        The trace starts when the start_sensor_events function is called. If
-        the test runs for a long time after this call, then the device's
-        internal memory can fill up. Calling get_sensor_events gets all events
-        from the device, and then stops the device from collecting events and
-        clears the internal buffer; to start again, the start_sensor_events
-        call must be used again.
-
-        Events from the accelerometer, compass, and gyro are returned; each
-        has a timestamp and x,y,z values.
-
-        Note that sensor events are only produced if the device isn't in its
-        standby mode (i.e.) if the screen is on.
-
-        Returns:
-            A Python dictionary with three keys ("accel", "mag", "gyro") each
-            of which maps to a list of objects containing "time","x","y","z"
-            keys.
-        """
-        cmd = {}
-        cmd["cmdName"] = "getSensorEvents"
-        self.sock.send(json.dumps(cmd) + "\n")
-        data,_ = self.__read_response_from_socket()
-        if data['tag'] != 'sensorEvents':
-            raise its.error.Error('Invalid command response')
-        return data['objValue']
-
-    def get_camera_properties(self):
-        """Get the camera properties object for the device.
-
-        Returns:
-            The Python dictionary object for the CameraProperties object.
-        """
-        cmd = {}
-        cmd["cmdName"] = "getCameraProperties"
-        self.sock.send(json.dumps(cmd) + "\n")
-        data,_ = self.__read_response_from_socket()
-        if data['tag'] != 'cameraProperties':
-            raise its.error.Error('Invalid command response')
-        return data['objValue']['cameraProperties']
-
-    def do_3a(self, regions_ae=[[0,0,1,1,1]],
-                    regions_awb=[[0,0,1,1,1]],
-                    regions_af=[[0,0,1,1,1]],
-                    do_ae=True, do_awb=True, do_af=True,
-                    lock_ae=False, lock_awb=False,
-                    get_results=False):
-        """Perform a 3A operation on the device.
-
-        Triggers some or all of AE, AWB, and AF, and returns once they have
-        converged. Uses the vendor 3A that is implemented inside the HAL.
-
-        Throws an assertion if 3A fails to converge.
-
-        Args:
-            regions_ae: List of weighted AE regions.
-            regions_awb: List of weighted AWB regions.
-            regions_af: List of weighted AF regions.
-            do_ae: Trigger AE and wait for it to converge.
-            do_awb: Wait for AWB to converge.
-            do_af: Trigger AF and wait for it to converge.
-            lock_ae: Request AE lock after convergence, and wait for it.
-            lock_awb: Request AWB lock after convergence, and wait for it.
-            get_results: Return the 3A results from this function.
-
-        Region format in args:
-            Arguments are lists of weighted regions; each weighted region is a
-            list of 5 values, [x,y,w,h, wgt], and each argument is a list of
-            these 5-value lists. The coordinates are given as normalized
-            rectangles (x,y,w,h) specifying the region. For example:
-                [[0.0, 0.0, 1.0, 0.5, 5], [0.0, 0.5, 1.0, 0.5, 10]].
-            Weights are non-negative integers.
-
-        Returns:
-            Five values are returned if get_results is true::
-            * AE sensitivity; None if do_ae is False
-            * AE exposure time; None if do_ae is False
-            * AWB gains (list); None if do_awb is False
-            * AWB transform (list); None if do_awb is false
-            * AF focus position; None if do_af is false
-            Otherwise, it returns five None values.
-        """
-        print "Running vendor 3A on device"
-        cmd = {}
-        cmd["cmdName"] = "do3A"
-        cmd["regions"] = {"ae": sum(regions_ae, []),
-                          "awb": sum(regions_awb, []),
-                          "af": sum(regions_af, [])}
-        cmd["triggers"] = {"ae": do_ae, "af": do_af}
-        if lock_ae:
-            cmd["aeLock"] = True
-        if lock_awb:
-            cmd["awbLock"] = True
-        self.sock.send(json.dumps(cmd) + "\n")
-
-        # Wait for each specified 3A to converge.
-        ae_sens = None
-        ae_exp = None
-        awb_gains = None
-        awb_transform = None
-        af_dist = None
-        converged = False
-        while True:
-            data,_ = self.__read_response_from_socket()
-            vals = data['strValue'].split()
-            if data['tag'] == 'aeResult':
-                ae_sens, ae_exp = [int(i) for i in vals]
-            elif data['tag'] == 'afResult':
-                af_dist = float(vals[0])
-            elif data['tag'] == 'awbResult':
-                awb_gains = [float(f) for f in vals[:4]]
-                awb_transform = [float(f) for f in vals[4:]]
-            elif data['tag'] == '3aConverged':
-                converged = True
-            elif data['tag'] == '3aDone':
-                break
-            else:
-                raise its.error.Error('Invalid command response')
-        if converged and not get_results:
-            return None,None,None,None,None
-        if (do_ae and ae_sens == None or do_awb and awb_gains == None
-                or do_af and af_dist == None or not converged):
-            raise its.error.Error('3A failed to converge')
-        return ae_sens, ae_exp, awb_gains, awb_transform, af_dist
-
-    def do_capture(self, cap_request, out_surfaces=None):
-        """Issue capture request(s), and read back the image(s) and metadata.
-
-        The main top-level function for capturing one or more images using the
-        device. Captures a single image if cap_request is a single object, and
-        captures a burst if it is a list of objects.
-
-        The out_surfaces field can specify the width(s), height(s), and
-        format(s) of the captured image. The formats may be "yuv", "jpeg",
-        "dng", "raw", or "raw10". The default is a YUV420 frame ("yuv")
-        corresponding to a full sensor frame.
-
-        Note that one or more surfaces can be specified, allowing a capture to
-        request images back in multiple formats (e.g.) raw+yuv, raw+jpeg,
-        yuv+jpeg, raw+yuv+jpeg. If the size is omitted for a surface, the
-        default is the largest resolution available for the format of that
-        surface. At most one output surface can be specified for a given format,
-        and raw+dng, raw10+dng, and raw+raw10 are not supported as combinations.
-
-        Example of a single capture request:
-
-            {
-                "android.sensor.exposureTime": 100*1000*1000,
-                "android.sensor.sensitivity": 100
-            }
-
-        Example of a list of capture requests:
-
-            [
-                {
-                    "android.sensor.exposureTime": 100*1000*1000,
-                    "android.sensor.sensitivity": 100
-                },
-                {
-                    "android.sensor.exposureTime": 100*1000*1000,
-                    "android.sensor.sensitivity": 200
-                }
-            ]
-
-        Examples of output surface specifications:
-
-            {
-                "width": 640,
-                "height": 480,
-                "format": "yuv"
-            }
-
-            [
-                {
-                    "format": "jpeg"
-                },
-                {
-                    "format": "raw"
-                }
-            ]
-
-        The following variables defined in this class are shortcuts for
-        specifying one or more formats where each output is the full size for
-        that format; they can be used as values for the out_surfaces arguments:
-
-            CAP_RAW
-            CAP_DNG
-            CAP_YUV
-            CAP_JPEG
-            CAP_RAW_YUV
-            CAP_DNG_YUV
-            CAP_RAW_JPEG
-            CAP_DNG_JPEG
-            CAP_YUV_JPEG
-            CAP_RAW_YUV_JPEG
-            CAP_DNG_YUV_JPEG
-
-        If multiple formats are specified, then this function returns multuple
-        capture objects, one for each requested format. If multiple formats and
-        multiple captures (i.e. a burst) are specified, then this function
-        returns multiple lists of capture objects. In both cases, the order of
-        the returned objects matches the order of the requested formats in the
-        out_surfaces parameter. For example:
-
-            yuv_cap            = do_capture( req1                           )
-            yuv_cap            = do_capture( req1,        yuv_fmt           )
-            yuv_cap,  raw_cap  = do_capture( req1,        [yuv_fmt,raw_fmt] )
-            yuv_caps           = do_capture( [req1,req2], yuv_fmt           )
-            yuv_caps, raw_caps = do_capture( [req1,req2], [yuv_fmt,raw_fmt] )
-
-        Args:
-            cap_request: The Python dict/list specifying the capture(s), which
-                will be converted to JSON and sent to the device.
-            out_surfaces: (Optional) specifications of the output image formats
-                and sizes to use for each capture.
-
-        Returns:
-            An object, list of objects, or list of lists of objects, where each
-            object contains the following fields:
-            * data: the image data as a numpy array of bytes.
-            * width: the width of the captured image.
-            * height: the height of the captured image.
-            * format: image the format, in ["yuv","jpeg","raw","raw10","dng"].
-            * metadata: the capture result object (Python dictionaty).
-        """
-        cmd = {}
-        cmd["cmdName"] = "doCapture"
-        if not isinstance(cap_request, list):
-            cmd["captureRequests"] = [cap_request]
-        else:
-            cmd["captureRequests"] = cap_request
-        if out_surfaces is not None:
-            if not isinstance(out_surfaces, list):
-                cmd["outputSurfaces"] = [out_surfaces]
-            else:
-                cmd["outputSurfaces"] = out_surfaces
-            formats = [c["format"] if c.has_key("format") else "yuv"
-                       for c in cmd["outputSurfaces"]]
-            formats = [s if s != "jpg" else "jpeg" for s in formats]
-        else:
-            formats = ['yuv']
-        ncap = len(cmd["captureRequests"])
-        nsurf = 1 if out_surfaces is None else len(cmd["outputSurfaces"])
-        if len(formats) > len(set(formats)):
-            raise its.error.Error('Duplicate format requested')
-        if "dng" in formats and "raw" in formats or \
-                "dng" in formats and "raw10" in formats or \
-                "raw" in formats and "raw10" in formats:
-            raise its.error.Error('Different raw formats not supported')
-        print "Capturing %d frame%s with %d format%s [%s]" % (
-                  ncap, "s" if ncap>1 else "", nsurf, "s" if nsurf>1 else "",
-                  ",".join(formats))
-        self.sock.send(json.dumps(cmd) + "\n")
-
-        # Wait for ncap*nsurf images and ncap metadata responses.
-        # Assume that captures come out in the same order as requested in
-        # the burst, however indifidual images of different formats ca come
-        # out in any order for that capture.
-        nbufs = 0
-        bufs = {"yuv":[], "raw":[], "raw10":[], "dng":[], "jpeg":[]}
-        mds = []
-        widths = None
-        heights = None
-        while nbufs < ncap*nsurf or len(mds) < ncap:
-            jsonObj,buf = self.__read_response_from_socket()
-            if jsonObj['tag'] in ['jpegImage', 'yuvImage', 'rawImage', \
-                    'raw10Image', 'dngImage'] and buf is not None:
-                fmt = jsonObj['tag'][:-5]
-                bufs[fmt].append(buf)
-                nbufs += 1
-            elif jsonObj['tag'] == 'captureResults':
-                mds.append(jsonObj['objValue']['captureResult'])
-                outputs = jsonObj['objValue']['outputs']
-                widths = [out['width'] for out in outputs]
-                heights = [out['height'] for out in outputs]
-            else:
-                # Just ignore other tags
-                None
-        rets = []
-        for j,fmt in enumerate(formats):
-            objs = []
-            for i in range(ncap):
-                obj = {}
-                obj["data"] = bufs[fmt][i]
-                obj["width"] = widths[j]
-                obj["height"] = heights[j]
-                obj["format"] = fmt
-                obj["metadata"] = mds[i]
-                objs.append(obj)
-            rets.append(objs if ncap>1 else objs[0])
-        return rets if len(rets)>1 else rets[0]
-
-def _run(cmd):
-    """Replacement for os.system, with hiding of stdout+stderr messages.
-    """
-    with open(os.devnull, 'wb') as devnull:
-        subprocess.check_call(
-                cmd.split(), stdout=devnull, stderr=subprocess.STDOUT)
-
-class __UnitTest(unittest.TestCase):
-    """Run a suite of unit tests on this module.
-    """
-
-    # TODO: Add some unit tests.
-    None
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/apps/CameraITS/pymodules/its/dng.py b/apps/CameraITS/pymodules/its/dng.py
deleted file mode 100644
index f331d02..0000000
--- a/apps/CameraITS/pymodules/its/dng.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# Copyright 2014 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.
-
-import numpy
-import numpy.linalg
-import unittest
-
-# Illuminant IDs
-A = 0
-D65 = 1
-
-def compute_cm_fm(illuminant, gains, ccm, cal):
-    """Compute the ColorMatrix (CM) and ForwardMatrix (FM).
-
-    Given a captured shot of a grey chart illuminated by either a D65 or a
-    standard A illuminant, the HAL will produce the WB gains and transform,
-    in the android.colorCorrection.gains and android.colorCorrection.transform
-    tags respectively. These values have both golden module and per-unit
-    calibration baked in.
-
-    This function is used to take the per-unit gains, ccm, and calibration
-    matrix, and compute the values that the DNG ColorMatrix and ForwardMatrix
-    for the specified illuminant should be. These CM and FM values should be
-    the same for all DNG files captured by all units of the same model (e.g.
-    all Nexus 5 units). The calibration matrix should be the same for all DNGs
-    saved by the same unit, but will differ unit-to-unit.
-
-    Args:
-        illuminant: 0 (A) or 1 (D65).
-        gains: White balance gains, as a list of 4 floats.
-        ccm: White balance transform matrix, as a list of 9 floats.
-        cal: Per-unit calibration matrix, as a list of 9 floats.
-
-    Returns:
-        CM: The 3x3 ColorMatrix for the specified illuminant, as a numpy array
-        FM: The 3x3 ForwardMatrix for the specified illuminant, as a numpy array
-    """
-
-    ###########################################################################
-    # Standard matrices.
-
-    # W is the matrix that maps sRGB to XYZ.
-    # See: http://www.brucelindbloom.com/
-    W = numpy.array([
-        [ 0.4124564,  0.3575761,  0.1804375],
-        [ 0.2126729,  0.7151522,  0.0721750],
-        [ 0.0193339,  0.1191920,  0.9503041]])
-
-    # HH is the chromatic adaptation matrix from D65 (since sRGB's ref white is
-    # D65) to D50 (since CIE XYZ's ref white is D50).
-    HH = numpy.array([
-        [ 1.0478112,  0.0228866, -0.0501270],
-        [ 0.0295424,  0.9904844, -0.0170491],
-        [-0.0092345,  0.0150436,  0.7521316]])
-
-    # H is a chromatic adaptation matrix from D65 (because sRGB's reference
-    # white is D65) to the calibration illuminant (which is a standard matrix
-    # depending on the illuminant). For a D65 illuminant, the matrix is the
-    # identity. For the A illuminant, the matrix uses the linear Bradford
-    # adaptation method to map from D65 to A.
-    # See: http://www.brucelindbloom.com/
-    H_D65 = numpy.array([
-        [ 1.0,        0.0,        0.0],
-        [ 0.0,        1.0,        0.0],
-        [ 0.0,        0.0,        1.0]])
-    H_A = numpy.array([
-        [ 1.2164557,  0.1109905, -0.1549325],
-        [ 0.1533326,  0.9152313, -0.0559953],
-        [-0.0239469,  0.0358984,  0.3147529]])
-    H = [H_A, H_D65][illuminant]
-
-    ###########################################################################
-    # Per-model matrices (that should be the same for all units of a particular
-    # phone/camera. These are statics in the HAL camera properties.
-
-    # G is formed by taking the r,g,b gains and putting them into a
-    # diagonal matrix.
-    G = numpy.array([[gains[0],0,0], [0,gains[1],0], [0,0,gains[3]]])
-
-    # S is just the CCM.
-    S = numpy.array([ccm[0:3], ccm[3:6], ccm[6:9]])
-
-    ###########################################################################
-    # Per-unit matrices.
-
-    # The per-unit calibration matrix for the given illuminant.
-    CC = numpy.array([cal[0:3],cal[3:6],cal[6:9]])
-
-    ###########################################################################
-    # Derived matrices. These should match up with DNG-related matrices
-    # provided by the HAL.
-
-    # The color matrix and forward matrix are computed as follows:
-    #   CM = inv(H * W * S * G * CC)
-    #   FM = HH * W * S
-    CM = numpy.linalg.inv(
-            numpy.dot(numpy.dot(numpy.dot(numpy.dot(H, W), S), G), CC))
-    FM = numpy.dot(numpy.dot(HH, W), S)
-
-    # The color matrix is normalized so that it maps the D50 (PCS) white
-    # point to a maximum component value of 1.
-    CM = CM / max(numpy.dot(CM, (0.9642957, 1.0, 0.8251046)))
-
-    return CM, FM
-
-def compute_asn(illuminant, cal, CM):
-    """Compute the AsShotNeutral DNG value.
-
-    This value is the only dynamic DNG value; the ForwardMatrix, ColorMatrix,
-    and CalibrationMatrix values should be the same for every DNG saved by
-    a given unit. The AsShotNeutral depends on the scene white balance
-    estimate.
-
-    This function computes what the DNG AsShotNeutral values should be, for
-    a given ColorMatrix (which is computed from the WB gains and CCM for a
-    shot taken of a grey chart under either A or D65 illuminants) and the
-    per-unit calibration matrix.
-
-    Args:
-        illuminant: 0 (A) or 1 (D65).
-        cal: Per-unit calibration matrix, as a list of 9 floats.
-        CM: The computed 3x3 ColorMatrix for the illuminant, as a numpy array.
-
-    Returns:
-        ASN: The AsShotNeutral value, as a length-3 numpy array.
-    """
-
-    ###########################################################################
-    # Standard matrices.
-
-    # XYZCAL is the  XYZ coordinate of calibration illuminant (so A or D65).
-    # See: Wyszecki & Stiles, "Color Science", second edition.
-    XYZCAL_A = numpy.array([1.098675, 1.0, 0.355916])
-    XYZCAL_D65 = numpy.array([0.950456, 1.0, 1.089058])
-    XYZCAL = [XYZCAL_A, XYZCAL_D65][illuminant]
-
-    ###########################################################################
-    # Per-unit matrices.
-
-    # The per-unit calibration matrix for the given illuminant.
-    CC = numpy.array([cal[0:3],cal[3:6],cal[6:9]])
-
-    ###########################################################################
-    # Derived matrices.
-
-    # The AsShotNeutral value is then the product of this final color matrix
-    # with the XYZ coordinate of calibration illuminant.
-    #   ASN = CC * CM * XYZCAL
-    ASN = numpy.dot(numpy.dot(CC, CM), XYZCAL)
-
-    # Normalize so the max vector element is 1.0.
-    ASN = ASN / max(ASN)
-
-    return ASN
-
-class __UnitTest(unittest.TestCase):
-    """Run a suite of unit tests on this module.
-    """
-    # TODO: Add more unit tests.
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/apps/CameraITS/pymodules/its/error.py b/apps/CameraITS/pymodules/its/error.py
deleted file mode 100644
index 884389b..0000000
--- a/apps/CameraITS/pymodules/its/error.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2013 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.
-
-import unittest
-
-class Error(Exception):
-    pass
-
-class __UnitTest(unittest.TestCase):
-    """Run a suite of unit tests on this module.
-    """
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/apps/CameraITS/pymodules/its/image.py b/apps/CameraITS/pymodules/its/image.py
deleted file mode 100644
index a05c4e6..0000000
--- a/apps/CameraITS/pymodules/its/image.py
+++ /dev/null
@@ -1,745 +0,0 @@
-# Copyright 2013 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.
-
-import matplotlib
-matplotlib.use('Agg')
-
-import its.error
-import pylab
-import sys
-import Image
-import numpy
-import math
-import unittest
-import cStringIO
-import scipy.stats
-import copy
-
-DEFAULT_YUV_TO_RGB_CCM = numpy.matrix([
-                                [1.000,  0.000,  1.402],
-                                [1.000, -0.344, -0.714],
-                                [1.000,  1.772,  0.000]])
-
-DEFAULT_YUV_OFFSETS = numpy.array([0, 128, 128])
-
-DEFAULT_GAMMA_LUT = numpy.array(
-        [math.floor(65535 * math.pow(i/65535.0, 1/2.2) + 0.5)
-         for i in xrange(65536)])
-
-DEFAULT_INVGAMMA_LUT = numpy.array(
-        [math.floor(65535 * math.pow(i/65535.0, 2.2) + 0.5)
-         for i in xrange(65536)])
-
-MAX_LUT_SIZE = 65536
-
-def convert_capture_to_rgb_image(cap,
-                                 ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
-                                 yuv_off=DEFAULT_YUV_OFFSETS,
-                                 props=None):
-    """Convert a captured image object to a RGB image.
-
-    Args:
-        cap: A capture object as returned by its.device.do_capture.
-        ccm_yuv_to_rgb: (Optional) the 3x3 CCM to convert from YUV to RGB.
-        yuv_off: (Optional) offsets to subtract from each of Y,U,V values.
-        props: (Optional) camera properties object (of static values);
-            required for processing raw images.
-
-    Returns:
-        RGB float-3 image array, with pixel values in [0.0, 1.0].
-    """
-    w = cap["width"]
-    h = cap["height"]
-    if cap["format"] == "raw10":
-        assert(props is not None)
-        cap = unpack_raw10_capture(cap, props)
-    if cap["format"] == "yuv":
-        y = cap["data"][0:w*h]
-        u = cap["data"][w*h:w*h*5/4]
-        v = cap["data"][w*h*5/4:w*h*6/4]
-        return convert_yuv420_to_rgb_image(y, u, v, w, h)
-    elif cap["format"] == "jpeg":
-        return decompress_jpeg_to_rgb_image(cap["data"])
-    elif cap["format"] == "raw":
-        assert(props is not None)
-        r,gr,gb,b = convert_capture_to_planes(cap, props)
-        return convert_raw_to_rgb_image(r,gr,gb,b, props, cap["metadata"])
-    else:
-        raise its.error.Error('Invalid format %s' % (cap["format"]))
-
-def unpack_raw10_capture(cap, props):
-    """Unpack a raw-10 capture to a raw-16 capture.
-
-    Args:
-        cap: A raw-10 capture object.
-        props: Camera propertis object.
-
-    Returns:
-        New capture object with raw-16 data.
-    """
-    # Data is packed as 4x10b pixels in 5 bytes, with the first 4 bytes holding
-    # the MSPs of the pixels, and the 5th byte holding 4x2b LSBs.
-    w,h = cap["width"], cap["height"]
-    if w % 4 != 0:
-        raise its.error.Error('Invalid raw-10 buffer width')
-    cap = copy.deepcopy(cap)
-    cap["data"] = unpack_raw10_image(cap["data"].reshape(h,w*5/4))
-    cap["format"] = "raw"
-    return cap
-
-def unpack_raw10_image(img):
-    """Unpack a raw-10 image to a raw-16 image.
-
-    Output image will have the 10 LSBs filled in each 16b word, and the 6 MSBs
-    will be set to zero.
-
-    Args:
-        img: A raw-10 image, as a uint8 numpy array.
-
-    Returns:
-        Image as a uint16 numpy array, with all row padding stripped.
-    """
-    if img.shape[1] % 5 != 0:
-        raise its.error.Error('Invalid raw-10 buffer width')
-    w = img.shape[1]*4/5
-    h = img.shape[0]
-    # Cut out the 4x8b MSBs and shift to bits [10:2] in 16b words.
-    msbs = numpy.delete(img, numpy.s_[4::5], 1)
-    msbs = msbs.astype(numpy.uint16)
-    msbs = numpy.left_shift(msbs, 2)
-    msbs = msbs.reshape(h,w)
-    # Cut out the 4x2b LSBs and put each in bits [2:0] of their own 8b words.
-    lsbs = img[::, 4::5].reshape(h,w/4)
-    lsbs = numpy.right_shift(
-            numpy.packbits(numpy.unpackbits(lsbs).reshape(h,w/4,4,2),3), 6)
-    lsbs = lsbs.reshape(h,w)
-    # Fuse the MSBs and LSBs back together
-    img16 = numpy.bitwise_or(msbs, lsbs).reshape(h,w)
-    return img16
-
-def convert_capture_to_planes(cap, props=None):
-    """Convert a captured image object to separate image planes.
-
-    Decompose an image into multiple images, corresponding to different planes.
-
-    For YUV420 captures ("yuv"):
-        Returns Y,U,V planes, where the Y plane is full-res and the U,V planes
-        are each 1/2 x 1/2 of the full res.
-
-    For Bayer captures ("raw" or "raw10"):
-        Returns planes in the order R,Gr,Gb,B, regardless of the Bayer pattern
-        layout. Each plane is 1/2 x 1/2 of the full res.
-
-    For JPEG captures ("jpeg"):
-        Returns R,G,B full-res planes.
-
-    Args:
-        cap: A capture object as returned by its.device.do_capture.
-        props: (Optional) camera properties object (of static values);
-            required for processing raw images.
-
-    Returns:
-        A tuple of float numpy arrays (one per plane), consisting of pixel
-            values in the range [0.0, 1.0].
-    """
-    w = cap["width"]
-    h = cap["height"]
-    if cap["format"] == "raw10":
-        assert(props is not None)
-        cap = unpack_raw10_capture(cap, props)
-    if cap["format"] == "yuv":
-        y = cap["data"][0:w*h]
-        u = cap["data"][w*h:w*h*5/4]
-        v = cap["data"][w*h*5/4:w*h*6/4]
-        return ((y.astype(numpy.float32) / 255.0).reshape(h, w, 1),
-                (u.astype(numpy.float32) / 255.0).reshape(h/2, w/2, 1),
-                (v.astype(numpy.float32) / 255.0).reshape(h/2, w/2, 1))
-    elif cap["format"] == "jpeg":
-        rgb = decompress_jpeg_to_rgb_image(cap["data"]).reshape(w*h*3)
-        return (rgb[::3].reshape(h,w,1),
-                rgb[1::3].reshape(h,w,1),
-                rgb[2::3].reshape(h,w,1))
-    elif cap["format"] == "raw":
-        assert(props is not None)
-        white_level = float(props['android.sensor.info.whiteLevel'])
-        img = numpy.ndarray(shape=(h*w,), dtype='<u2',
-                            buffer=cap["data"][0:w*h*2])
-        img = img.astype(numpy.float32).reshape(h,w) / white_level
-        imgs = [img[::2].reshape(w*h/2)[::2].reshape(h/2,w/2,1),
-                img[::2].reshape(w*h/2)[1::2].reshape(h/2,w/2,1),
-                img[1::2].reshape(w*h/2)[::2].reshape(h/2,w/2,1),
-                img[1::2].reshape(w*h/2)[1::2].reshape(h/2,w/2,1)]
-        idxs = get_canonical_cfa_order(props)
-        return [imgs[i] for i in idxs]
-    else:
-        raise its.error.Error('Invalid format %s' % (cap["format"]))
-
-def get_canonical_cfa_order(props):
-    """Returns a mapping from the Bayer 2x2 top-left grid in the CFA to
-    the standard order R,Gr,Gb,B.
-
-    Args:
-        props: Camera properties object.
-
-    Returns:
-        List of 4 integers, corresponding to the positions in the 2x2 top-
-            left Bayer grid of R,Gr,Gb,B, where the 2x2 grid is labeled as
-            0,1,2,3 in row major order.
-    """
-    # Note that raw streams aren't croppable, so the cropRegion doesn't need
-    # to be considered when determining the top-left pixel color.
-    cfa_pat = props['android.sensor.info.colorFilterArrangement']
-    if cfa_pat == 0:
-        # RGGB
-        return [0,1,2,3]
-    elif cfa_pat == 1:
-        # GRBG
-        return [1,0,3,2]
-    elif cfa_pat == 2:
-        # GBRG
-        return [2,3,0,1]
-    elif cfa_pat == 3:
-        # BGGR
-        return [3,2,1,0]
-    else:
-        raise its.error.Error("Not supported")
-
-def get_gains_in_canonical_order(props, gains):
-    """Reorders the gains tuple to the canonical R,Gr,Gb,B order.
-
-    Args:
-        props: Camera properties object.
-        gains: List of 4 values, in R,G_even,G_odd,B order.
-
-    Returns:
-        List of gains values, in R,Gr,Gb,B order.
-    """
-    cfa_pat = props['android.sensor.info.colorFilterArrangement']
-    if cfa_pat in [0,1]:
-        # RGGB or GRBG, so G_even is Gr
-        return gains
-    elif cfa_pat in [2,3]:
-        # GBRG or BGGR, so G_even is Gb
-        return [gains[0], gains[2], gains[1], gains[3]]
-    else:
-        raise its.error.Error("Not supported")
-
-def convert_raw_to_rgb_image(r_plane, gr_plane, gb_plane, b_plane,
-                             props, cap_res):
-    """Convert a Bayer raw-16 image to an RGB image.
-
-    Includes some extremely rudimentary demosaicking and color processing
-    operations; the output of this function shouldn't be used for any image
-    quality analysis.
-
-    Args:
-        r_plane,gr_plane,gb_plane,b_plane: Numpy arrays for each color plane
-            in the Bayer image, with pixels in the [0.0, 1.0] range.
-        props: Camera properties object.
-        cap_res: Capture result (metadata) object.
-
-    Returns:
-        RGB float-3 image array, with pixel values in [0.0, 1.0]
-    """
-    # Values required for the RAW to RGB conversion.
-    assert(props is not None)
-    white_level = float(props['android.sensor.info.whiteLevel'])
-    black_levels = props['android.sensor.blackLevelPattern']
-    gains = cap_res['android.colorCorrection.gains']
-    ccm = cap_res['android.colorCorrection.transform']
-
-    # Reorder black levels and gains to R,Gr,Gb,B, to match the order
-    # of the planes.
-    idxs = get_canonical_cfa_order(props)
-    black_levels = [black_levels[i] for i in idxs]
-    gains = get_gains_in_canonical_order(props, gains)
-
-    # Convert CCM from rational to float, as numpy arrays.
-    ccm = numpy.array(its.objects.rational_to_float(ccm)).reshape(3,3)
-
-    # Need to scale the image back to the full [0,1] range after subtracting
-    # the black level from each pixel.
-    scale = white_level / (white_level - max(black_levels))
-
-    # Three-channel black levels, normalized to [0,1] by white_level.
-    black_levels = numpy.array([b/white_level for b in [
-            black_levels[i] for i in [0,1,3]]])
-
-    # Three-channel gains.
-    gains = numpy.array([gains[i] for i in [0,1,3]])
-
-    h,w = r_plane.shape[:2]
-    img = numpy.dstack([r_plane,(gr_plane+gb_plane)/2.0,b_plane])
-    img = (((img.reshape(h,w,3) - black_levels) * scale) * gains).clip(0.0,1.0)
-    img = numpy.dot(img.reshape(w*h,3), ccm.T).reshape(h,w,3).clip(0.0,1.0)
-    return img
-
-def convert_yuv420_to_rgb_image(y_plane, u_plane, v_plane,
-                                w, h,
-                                ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
-                                yuv_off=DEFAULT_YUV_OFFSETS):
-    """Convert a YUV420 8-bit planar image to an RGB image.
-
-    Args:
-        y_plane: The packed 8-bit Y plane.
-        u_plane: The packed 8-bit U plane.
-        v_plane: The packed 8-bit V plane.
-        w: The width of the image.
-        h: The height of the image.
-        ccm_yuv_to_rgb: (Optional) the 3x3 CCM to convert from YUV to RGB.
-        yuv_off: (Optional) offsets to subtract from each of Y,U,V values.
-
-    Returns:
-        RGB float-3 image array, with pixel values in [0.0, 1.0].
-    """
-    y = numpy.subtract(y_plane, yuv_off[0])
-    u = numpy.subtract(u_plane, yuv_off[1]).view(numpy.int8)
-    v = numpy.subtract(v_plane, yuv_off[2]).view(numpy.int8)
-    u = u.reshape(h/2, w/2).repeat(2, axis=1).repeat(2, axis=0)
-    v = v.reshape(h/2, w/2).repeat(2, axis=1).repeat(2, axis=0)
-    yuv = numpy.dstack([y, u.reshape(w*h), v.reshape(w*h)])
-    flt = numpy.empty([h, w, 3], dtype=numpy.float32)
-    flt.reshape(w*h*3)[:] = yuv.reshape(h*w*3)[:]
-    flt = numpy.dot(flt.reshape(w*h,3), ccm_yuv_to_rgb.T).clip(0, 255)
-    rgb = numpy.empty([h, w, 3], dtype=numpy.uint8)
-    rgb.reshape(w*h*3)[:] = flt.reshape(w*h*3)[:]
-    return rgb.astype(numpy.float32) / 255.0
-
-def load_yuv420_to_rgb_image(yuv_fname,
-                             w, h,
-                             ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
-                             yuv_off=DEFAULT_YUV_OFFSETS):
-    """Load a YUV420 image file, and return as an RGB image.
-
-    Args:
-        yuv_fname: The path of the YUV420 file.
-        w: The width of the image.
-        h: The height of the image.
-        ccm_yuv_to_rgb: (Optional) the 3x3 CCM to convert from YUV to RGB.
-        yuv_off: (Optional) offsets to subtract from each of Y,U,V values.
-
-    Returns:
-        RGB float-3 image array, with pixel values in [0.0, 1.0].
-    """
-    with open(yuv_fname, "rb") as f:
-        y = numpy.fromfile(f, numpy.uint8, w*h, "")
-        v = numpy.fromfile(f, numpy.uint8, w*h/4, "")
-        u = numpy.fromfile(f, numpy.uint8, w*h/4, "")
-        return convert_yuv420_to_rgb_image(y,u,v,w,h,ccm_yuv_to_rgb,yuv_off)
-
-def load_yuv420_to_yuv_planes(yuv_fname, w, h):
-    """Load a YUV420 image file, and return separate Y, U, and V plane images.
-
-    Args:
-        yuv_fname: The path of the YUV420 file.
-        w: The width of the image.
-        h: The height of the image.
-
-    Returns:
-        Separate Y, U, and V images as float-1 Numpy arrays, pixels in [0,1].
-        Note that pixel (0,0,0) is not black, since U,V pixels are centered at
-        0.5, and also that the Y and U,V plane images returned are different
-        sizes (due to chroma subsampling in the YUV420 format).
-    """
-    with open(yuv_fname, "rb") as f:
-        y = numpy.fromfile(f, numpy.uint8, w*h, "")
-        v = numpy.fromfile(f, numpy.uint8, w*h/4, "")
-        u = numpy.fromfile(f, numpy.uint8, w*h/4, "")
-        return ((y.astype(numpy.float32) / 255.0).reshape(h, w, 1),
-                (u.astype(numpy.float32) / 255.0).reshape(h/2, w/2, 1),
-                (v.astype(numpy.float32) / 255.0).reshape(h/2, w/2, 1))
-
-def decompress_jpeg_to_rgb_image(jpeg_buffer):
-    """Decompress a JPEG-compressed image, returning as an RGB image.
-
-    Args:
-        jpeg_buffer: The JPEG stream.
-
-    Returns:
-        A numpy array for the RGB image, with pixels in [0,1].
-    """
-    img = Image.open(cStringIO.StringIO(jpeg_buffer))
-    w = img.size[0]
-    h = img.size[1]
-    return numpy.array(img).reshape(h,w,3) / 255.0
-
-def apply_lut_to_image(img, lut):
-    """Applies a LUT to every pixel in a float image array.
-
-    Internally converts to a 16b integer image, since the LUT can work with up
-    to 16b->16b mappings (i.e. values in the range [0,65535]). The lut can also
-    have fewer than 65536 entries, however it must be sized as a power of 2
-    (and for smaller luts, the scale must match the bitdepth).
-
-    For a 16b lut of 65536 entries, the operation performed is:
-
-        lut[r * 65535] / 65535 -> r'
-        lut[g * 65535] / 65535 -> g'
-        lut[b * 65535] / 65535 -> b'
-
-    For a 10b lut of 1024 entries, the operation becomes:
-
-        lut[r * 1023] / 1023 -> r'
-        lut[g * 1023] / 1023 -> g'
-        lut[b * 1023] / 1023 -> b'
-
-    Args:
-        img: Numpy float image array, with pixel values in [0,1].
-        lut: Numpy table encoding a LUT, mapping 16b integer values.
-
-    Returns:
-        Float image array after applying LUT to each pixel.
-    """
-    n = len(lut)
-    if n <= 0 or n > MAX_LUT_SIZE or (n & (n - 1)) != 0:
-        raise its.error.Error('Invalid arg LUT size: %d' % (n))
-    m = float(n-1)
-    return (lut[(img * m).astype(numpy.uint16)] / m).astype(numpy.float32)
-
-def apply_matrix_to_image(img, mat):
-    """Multiplies a 3x3 matrix with each float-3 image pixel.
-
-    Each pixel is considered a column vector, and is left-multiplied by
-    the given matrix:
-
-        [     ]   r    r'
-        [ mat ] * g -> g'
-        [     ]   b    b'
-
-    Args:
-        img: Numpy float image array, with pixel values in [0,1].
-        mat: Numpy 3x3 matrix.
-
-    Returns:
-        The numpy float-3 image array resulting from the matrix mult.
-    """
-    h = img.shape[0]
-    w = img.shape[1]
-    img2 = numpy.empty([h, w, 3], dtype=numpy.float32)
-    img2.reshape(w*h*3)[:] = (numpy.dot(img.reshape(h*w, 3), mat.T)
-                             ).reshape(w*h*3)[:]
-    return img2
-
-def get_image_patch(img, xnorm, ynorm, wnorm, hnorm):
-    """Get a patch (tile) of an image.
-
-    Args:
-        img: Numpy float image array, with pixel values in [0,1].
-        xnorm,ynorm,wnorm,hnorm: Normalized (in [0,1]) coords for the tile.
-
-    Returns:
-        Float image array of the patch.
-    """
-    hfull = img.shape[0]
-    wfull = img.shape[1]
-    xtile = math.ceil(xnorm * wfull)
-    ytile = math.ceil(ynorm * hfull)
-    wtile = math.floor(wnorm * wfull)
-    htile = math.floor(hnorm * hfull)
-    return img[ytile:ytile+htile,xtile:xtile+wtile,:].copy()
-
-def compute_image_means(img):
-    """Calculate the mean of each color channel in the image.
-
-    Args:
-        img: Numpy float image array, with pixel values in [0,1].
-
-    Returns:
-        A list of mean values, one per color channel in the image.
-    """
-    means = []
-    chans = img.shape[2]
-    for i in xrange(chans):
-        means.append(numpy.mean(img[:,:,i], dtype=numpy.float64))
-    return means
-
-def compute_image_variances(img):
-    """Calculate the variance of each color channel in the image.
-
-    Args:
-        img: Numpy float image array, with pixel values in [0,1].
-
-    Returns:
-        A list of mean values, one per color channel in the image.
-    """
-    variances = []
-    chans = img.shape[2]
-    for i in xrange(chans):
-        variances.append(numpy.var(img[:,:,i], dtype=numpy.float64))
-    return variances
-
-def write_image(img, fname, apply_gamma=False):
-    """Save a float-3 numpy array image to a file.
-
-    Supported formats: PNG, JPEG, and others; see PIL docs for more.
-
-    Image can be 3-channel, which is interpreted as RGB, or can be 1-channel,
-    which is greyscale.
-
-    Can optionally specify that the image should be gamma-encoded prior to
-    writing it out; this should be done if the image contains linear pixel
-    values, to make the image look "normal".
-
-    Args:
-        img: Numpy image array data.
-        fname: Path of file to save to; the extension specifies the format.
-        apply_gamma: (Optional) apply gamma to the image prior to writing it.
-    """
-    if apply_gamma:
-        img = apply_lut_to_image(img, DEFAULT_GAMMA_LUT)
-    (h, w, chans) = img.shape
-    if chans == 3:
-        Image.fromarray((img * 255.0).astype(numpy.uint8), "RGB").save(fname)
-    elif chans == 1:
-        img3 = (img * 255.0).astype(numpy.uint8).repeat(3).reshape(h,w,3)
-        Image.fromarray(img3, "RGB").save(fname)
-    else:
-        raise its.error.Error('Unsupported image type')
-
-def downscale_image(img, f):
-    """Shrink an image by a given integer factor.
-
-    This function computes output pixel values by averaging over rectangular
-    regions of the input image; it doesn't skip or sample pixels, and all input
-    image pixels are evenly weighted.
-
-    If the downscaling factor doesn't cleanly divide the width and/or height,
-    then the remaining pixels on the right or bottom edge are discarded prior
-    to the downscaling.
-
-    Args:
-        img: The input image as an ndarray.
-        f: The downscaling factor, which should be an integer.
-
-    Returns:
-        The new (downscaled) image, as an ndarray.
-    """
-    h,w,chans = img.shape
-    f = int(f)
-    assert(f >= 1)
-    h = (h/f)*f
-    w = (w/f)*f
-    img = img[0:h:,0:w:,::]
-    chs = []
-    for i in xrange(chans):
-        ch = img.reshape(h*w*chans)[i::chans].reshape(h,w)
-        ch = ch.reshape(h,w/f,f).mean(2).reshape(h,w/f)
-        ch = ch.T.reshape(w/f,h/f,f).mean(2).T.reshape(h/f,w/f)
-        chs.append(ch.reshape(h*w/(f*f)))
-    img = numpy.vstack(chs).T.reshape(h/f,w/f,chans)
-    return img
-
-def __measure_color_checker_patch(img, xc,yc, patch_size):
-    r = patch_size/2
-    tile = img[yc-r:yc+r+1:, xc-r:xc+r+1:, ::]
-    means = tile.mean(1).mean(0)
-    return means
-
-def get_color_checker_chart_patches(img, debug_fname_prefix=None):
-    """Return the center coords of each patch in a color checker chart.
-
-    Assumptions:
-    * Chart is vertical or horizontal w.r.t. camera, but not diagonal.
-    * Chart is (roughly) planar-parallel to the camera.
-    * Chart is centered in frame (roughly).
-    * Around/behind chart is white/grey background.
-    * The only black pixels in the image are from the chart.
-    * Chart is 100% visible and contained within image.
-    * No other objects within image.
-    * Image is well-exposed.
-    * Standard color checker chart with standard-sized black borders.
-
-    The values returned are in the coordinate system of the chart; that is,
-    the "origin" patch is the brown patch that is in the chart's top-left
-    corner when it is in the normal upright/horizontal orientation. (The chart
-    may be any of the four main orientations in the image.)
-
-    The chart is 6x4 patches in the normal upright orientation. The return
-    values of this function are the center coordinate of the top-left patch,
-    and the displacement vectors to the next patches to the right and below
-    the top-left patch. From these pieces of data, the center coordinates of
-    any of the patches can be computed.
-
-    Args:
-        img: Input image, as a numpy array with pixels in [0,1].
-        debug_fname_prefix: If not None, the (string) name of a file prefix to
-            use to save a number of debug images for visulaizing the output of
-            this function; can be used to see if the patches are being found
-            successfully.
-
-    Returns:
-        6x4 list of lists of integer (x,y) coords of the center of each patch,
-        ordered in the "chart order" (6x4 row major).
-    """
-
-    # Shrink the original image.
-    DOWNSCALE_FACTOR = 4
-    img_small = downscale_image(img, DOWNSCALE_FACTOR)
-
-    # Make a threshold image, which is 1.0 where the image is black,
-    # and 0.0 elsewhere.
-    BLACK_PIXEL_THRESH = 0.2
-    mask_img = scipy.stats.threshold(
-                img_small.max(2), BLACK_PIXEL_THRESH, 1.1, 0.0)
-    mask_img = 1.0 - scipy.stats.threshold(mask_img, -0.1, 0.1, 1.0)
-
-    if debug_fname_prefix is not None:
-        h,w = mask_img.shape
-        write_image(img, debug_fname_prefix+"_0.jpg")
-        write_image(mask_img.repeat(3).reshape(h,w,3),
-                debug_fname_prefix+"_1.jpg")
-
-    # Mask image flattened to a single row or column (by averaging).
-    # Also apply a threshold to these arrays.
-    FLAT_PIXEL_THRESH = 0.05
-    flat_row = mask_img.mean(0)
-    flat_col = mask_img.mean(1)
-    flat_row = [0 if v < FLAT_PIXEL_THRESH else 1 for v in flat_row]
-    flat_col = [0 if v < FLAT_PIXEL_THRESH else 1 for v in flat_col]
-
-    # Start and end of the non-zero region of the flattened row/column.
-    flat_row_nonzero = [i for i in range(len(flat_row)) if flat_row[i]>0]
-    flat_col_nonzero = [i for i in range(len(flat_col)) if flat_col[i]>0]
-    flat_row_min, flat_row_max = min(flat_row_nonzero), max(flat_row_nonzero)
-    flat_col_min, flat_col_max = min(flat_col_nonzero), max(flat_col_nonzero)
-
-    # Orientation of chart, and number of grid cells horz. and vertically.
-    orient = "h" if flat_row_max-flat_row_min>flat_col_max-flat_col_min else "v"
-    xgrids = 6 if orient=="h" else 4
-    ygrids = 6 if orient=="v" else 4
-
-    # Get better bounds on the patches region, lopping off some of the excess
-    # black border.
-    HRZ_BORDER_PAD_FRAC = 0.0138
-    VERT_BORDER_PAD_FRAC = 0.0395
-    xpad = HRZ_BORDER_PAD_FRAC if orient=="h" else VERT_BORDER_PAD_FRAC
-    ypad = HRZ_BORDER_PAD_FRAC if orient=="v" else VERT_BORDER_PAD_FRAC
-    xchart = flat_row_min + (flat_row_max - flat_row_min) * xpad
-    ychart = flat_col_min + (flat_col_max - flat_col_min) * ypad
-    wchart = (flat_row_max - flat_row_min) * (1 - 2*xpad)
-    hchart = (flat_col_max - flat_col_min) * (1 - 2*ypad)
-
-    # Get the colors of the 4 corner patches, in clockwise order, by measuring
-    # the average value of a small patch at each of the 4 patch centers.
-    colors = []
-    centers = []
-    for (x,y) in [(0,0), (xgrids-1,0), (xgrids-1,ygrids-1), (0,ygrids-1)]:
-        xc = xchart + (x + 0.5)*wchart/xgrids
-        yc = ychart + (y + 0.5)*hchart/ygrids
-        xc = int(xc * DOWNSCALE_FACTOR + 0.5)
-        yc = int(yc * DOWNSCALE_FACTOR + 0.5)
-        centers.append((xc,yc))
-        chan_means = __measure_color_checker_patch(img, xc,yc, 32)
-        colors.append(sum(chan_means) / len(chan_means))
-
-    # The brightest corner is the white patch, the darkest is the black patch.
-    # The black patch should be counter-clockwise from the white patch.
-    white_patch_index = None
-    for i in range(4):
-        if colors[i] == max(colors) and \
-                colors[(i-1+4)%4] == min(colors):
-            white_patch_index = i%4
-    assert(white_patch_index is not None)
-
-    # Return the coords of the origin (top-left when the chart is in the normal
-    # upright orientation) patch's center, and the vector displacement to the
-    # center of the second patch on the first row of the chart (when in the
-    # normal upright orienation).
-    origin_index = (white_patch_index+1)%4
-    prev_index = (origin_index-1+4)%4
-    next_index = (origin_index+1)%4
-    origin_center = centers[origin_index]
-    prev_center = centers[prev_index]
-    next_center = centers[next_index]
-    vec_across = tuple([(next_center[i]-origin_center[i])/5.0 for i in [0,1]])
-    vec_down = tuple([(prev_center[i]-origin_center[i])/3.0 for i in [0,1]])
-
-    # Compute the center of each patch.
-    patches = [[],[],[],[]]
-    for yi in range(4):
-        for xi in range(6):
-            x0,y0 = origin_center
-            dxh,dyh = vec_across
-            dxv,dyv = vec_down
-            xc = int(x0 + dxh*xi + dxv*yi)
-            yc = int(y0 + dyh*xi + dyv*yi)
-            patches[yi].append((xc,yc))
-
-    # Sanity check: test that the R,G,B,black,white patches are correct.
-    patch_info = [(2,2,[0]), # Red
-                  (2,1,[1]), # Green
-                  (2,0,[2]), # Blue
-                  (3,0,[0,1,2]), # White
-                  (3,5,[])] # Black
-    for i in range(len(patch_info)):
-        yi,xi,high_chans = patch_info[i]
-        low_chans = [i for i in [0,1,2] if i not in high_chans]
-        xc,yc = patches[yi][xi]
-        means = __measure_color_checker_patch(img, xc,yc, 64)
-        if (min([means[i] for i in high_chans]+[1]) < \
-                max([means[i] for i in low_chans]+[0])):
-            print "Color patch sanity check failed: patch", i
-            # If the debug info is requested, then don't assert that the patches
-            # are matched, to allow the caller to see the output.
-            if debug_fname_prefix is None:
-                assert(0)
-
-    if debug_fname_prefix is not None:
-        for (xc,yc) in sum(patches,[]):
-            img[yc,xc] = 1.0
-        write_image(img, debug_fname_prefix+"_2.jpg")
-
-    return patches
-
-class __UnitTest(unittest.TestCase):
-    """Run a suite of unit tests on this module.
-    """
-
-    # TODO: Add more unit tests.
-
-    def test_apply_matrix_to_image(self):
-        """Unit test for apply_matrix_to_image.
-
-        Test by using a canned set of values on a 1x1 pixel image.
-
-            [ 1 2 3 ]   [ 0.1 ]   [ 1.4 ]
-            [ 4 5 6 ] * [ 0.2 ] = [ 3.2 ]
-            [ 7 8 9 ]   [ 0.3 ]   [ 5.0 ]
-               mat         x         y
-        """
-        mat = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
-        x = numpy.array([0.1,0.2,0.3]).reshape(1,1,3)
-        y = apply_matrix_to_image(x, mat).reshape(3).tolist()
-        y_ref = [1.4,3.2,5.0]
-        passed = all([math.fabs(y[i] - y_ref[i]) < 0.001 for i in xrange(3)])
-        self.assertTrue(passed)
-
-    def test_apply_lut_to_image(self):
-        """ Unit test for apply_lut_to_image.
-
-        Test by using a canned set of values on a 1x1 pixel image. The LUT will
-        simply double the value of the index:
-
-            lut[x] = 2*x
-        """
-        lut = numpy.array([2*i for i in xrange(65536)])
-        x = numpy.array([0.1,0.2,0.3]).reshape(1,1,3)
-        y = apply_lut_to_image(x, lut).reshape(3).tolist()
-        y_ref = [0.2,0.4,0.6]
-        passed = all([math.fabs(y[i] - y_ref[i]) < 0.001 for i in xrange(3)])
-        self.assertTrue(passed)
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
deleted file mode 100644
index d11ef84..0000000
--- a/apps/CameraITS/pymodules/its/objects.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright 2013 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.
-
-import os
-import os.path
-import sys
-import re
-import json
-import tempfile
-import time
-import unittest
-import subprocess
-import math
-
-def int_to_rational(i):
-    """Function to convert Python integers to Camera2 rationals.
-
-    Args:
-        i: Python integer or list of integers.
-
-    Returns:
-        Python dictionary or list of dictionaries representing the given int(s)
-        as rationals with denominator=1.
-    """
-    if isinstance(i, list):
-        return [{"numerator":val, "denominator":1} for val in i]
-    else:
-        return {"numerator":i, "denominator":1}
-
-def float_to_rational(f, denom=128):
-    """Function to convert Python floats to Camera2 rationals.
-
-    Args:
-        f: Python float or list of floats.
-        denom: (Optonal) the denominator to use in the output rationals.
-
-    Returns:
-        Python dictionary or list of dictionaries representing the given
-        float(s) as rationals.
-    """
-    if isinstance(f, list):
-        return [{"numerator":math.floor(val*denom+0.5), "denominator":denom}
-                for val in f]
-    else:
-        return {"numerator":math.floor(f*denom+0.5), "denominator":denom}
-
-def rational_to_float(r):
-    """Function to convert Camera2 rational objects to Python floats.
-
-    Args:
-        r: Rational or list of rationals, as Python dictionaries.
-
-    Returns:
-        Float or list of floats.
-    """
-    if isinstance(r, list):
-        return [float(val["numerator"]) / float(val["denominator"])
-                for val in r]
-    else:
-        return float(r["numerator"]) / float(r["denominator"])
-
-def manual_capture_request(sensitivity, exp_time, linear_tonemap=False):
-    """Return a capture request with everything set to manual.
-
-    Uses identity/unit color correction, and the default tonemap curve.
-    Optionally, the tonemap can be specified as being linear.
-
-    Args:
-        sensitivity: The sensitivity value to populate the request with.
-        exp_time: The exposure time, in nanoseconds, to populate the request
-            with.
-        linear_tonemap: [Optional] whether a linear tonemap should be used
-            in this request.
-
-    Returns:
-        The default manual capture request, ready to be passed to the
-        its.device.do_capture function.
-    """
-    req = {
-        "android.control.mode": 0,
-        "android.control.aeMode": 0,
-        "android.control.awbMode": 0,
-        "android.control.afMode": 0,
-        "android.control.effectMode": 0,
-        "android.sensor.frameDuration": 0,
-        "android.sensor.sensitivity": sensitivity,
-        "android.sensor.exposureTime": exp_time,
-        "android.colorCorrection.mode": 0,
-        "android.colorCorrection.transform":
-                int_to_rational([1,0,0, 0,1,0, 0,0,1]),
-        "android.colorCorrection.gains": [1,1,1,1],
-        "android.tonemap.mode": 1,
-        }
-    if linear_tonemap:
-        req["android.tonemap.mode"] = 0
-        req["android.tonemap.curveRed"] = [0.0,0.0, 1.0,1.0]
-        req["android.tonemap.curveGreen"] = [0.0,0.0, 1.0,1.0]
-        req["android.tonemap.curveBlue"] = [0.0,0.0, 1.0,1.0]
-    return req
-
-def auto_capture_request():
-    """Return a capture request with everything set to auto.
-    """
-    return {
-        "android.control.mode": 1,
-        "android.control.aeMode": 1,
-        "android.control.awbMode": 1,
-        "android.control.afMode": 1,
-        "android.colorCorrection.mode": 1,
-        "android.tonemap.mode": 1,
-        }
-
-def get_available_output_sizes(fmt, props):
-    """Return a sorted list of available output sizes for a given format.
-
-    Args:
-        fmt: the output format, as a string in ["jpg", "yuv", "raw"].
-        props: the object returned from its.device.get_camera_properties().
-
-    Returns:
-        A sorted list of (w,h) tuples (sorted large-to-small).
-    """
-    fmt_codes = {"raw":0x20, "raw10":0x25, "yuv":0x23, "jpg":0x100, "jpeg":0x100}
-    configs = props['android.scaler.streamConfigurationMap']\
-                   ['availableStreamConfigurations']
-    fmt_configs = [cfg for cfg in configs if cfg['format'] == fmt_codes[fmt]]
-    out_configs = [cfg for cfg in fmt_configs if cfg['input'] == False]
-    out_sizes = [(cfg['width'],cfg['height']) for cfg in out_configs]
-    out_sizes.sort(reverse=True)
-    return out_sizes
-
-def get_fastest_manual_capture_settings(props):
-    """Return a capture request and format spec for the fastest capture.
-
-    Args:
-        props: the object returned from its.device.get_camera_properties().
-
-    Returns:
-        Two values, the first is a capture request, and the second is an output
-        format specification, for the fastest possible (legal) capture that
-        can be performed on this device (with the smallest output size).
-    """
-    fmt = "yuv"
-    size = get_available_output_sizes(fmt, props)[-1]
-    out_spec = {"format":fmt, "width":size[0], "height":size[1]}
-    s = min(props['android.sensor.info.sensitivityRange'])
-    e = min(props['android.sensor.info.exposureTimeRange'])
-    req = manual_capture_request(s,e)
-    return req, out_spec
-
-class __UnitTest(unittest.TestCase):
-    """Run a suite of unit tests on this module.
-    """
-
-    def test_int_to_rational(self):
-        """Unit test for int_to_rational.
-        """
-        self.assertEqual(int_to_rational(10),
-                         {"numerator":10,"denominator":1})
-        self.assertEqual(int_to_rational([1,2]),
-                         [{"numerator":1,"denominator":1},
-                          {"numerator":2,"denominator":1}])
-
-    def test_float_to_rational(self):
-        """Unit test for float_to_rational.
-        """
-        self.assertEqual(float_to_rational(0.5001, 64),
-                        {"numerator":32, "denominator":64})
-
-    def test_rational_to_float(self):
-        """Unit test for rational_to_float.
-        """
-        self.assertTrue(
-                abs(rational_to_float({"numerator":32,"denominator":64})-0.5)
-                < 0.0001)
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/apps/CameraITS/pymodules/its/target.py b/apps/CameraITS/pymodules/its/target.py
deleted file mode 100644
index 3715f34..0000000
--- a/apps/CameraITS/pymodules/its/target.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# Copyright 2013 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.
-
-import its.device
-import its.image
-import its.objects
-import os
-import os.path
-import sys
-import json
-import unittest
-import json
-
-CACHE_FILENAME = "its.target.cfg"
-
-def __do_target_exposure_measurement(its_session):
-    """Use device 3A and captured shots to determine scene exposure.
-
-    Creates a new ITS device session (so this function should not be called
-    while another session to the device is open).
-
-    Assumes that the camera is pointed at a scene that is reasonably uniform
-    and reasonably lit -- that is, an appropriate target for running the ITS
-    tests that assume such uniformity.
-
-    Measures the scene using device 3A and then by taking a shot to hone in on
-    the exact exposure level that will result in a center 10% by 10% patch of
-    the scene having a intensity level of 0.5 (in the pixel range of [0,1])
-    when a linear tonemap is used. That is, the pixels coming off the sensor
-    should be at approximately 50% intensity (however note that it's actually
-    the luma value in the YUV image that is being targeted to 50%).
-
-    The computed exposure value is the product of the sensitivity (ISO) and
-    exposure time (ns) to achieve that sensor exposure level.
-
-    Args:
-        its_session: Holds an open device session.
-
-    Returns:
-        The measured product of sensitivity and exposure time that results in
-            the luma channel of captured shots having an intensity of 0.5.
-    """
-    print "Measuring target exposure"
-
-    # Get AE+AWB lock first, so the auto values in the capture result are
-    # populated properly.
-    r = [[0.45, 0.45, 0.1, 0.1, 1]]
-    sens, exp_time, gains, xform, _ \
-            = its_session.do_3a(r,r,r,do_af=False,get_results=True)
-
-    # Convert the transform to rational.
-    xform_rat = [{"numerator":int(100*x),"denominator":100} for x in xform]
-
-    # Linear tonemap
-    tmap = sum([[i/63.0,i/63.0] for i in range(64)], [])
-
-    # Capture a manual shot with this exposure, using a linear tonemap.
-    # Use the gains+transform returned by the AWB pass.
-    req = its.objects.manual_capture_request(sens, exp_time)
-    req["android.tonemap.mode"] = 0
-    req["android.tonemap.curveRed"] = tmap
-    req["android.tonemap.curveGreen"] = tmap
-    req["android.tonemap.curveBlue"] = tmap
-    req["android.colorCorrection.transform"] = xform_rat
-    req["android.colorCorrection.gains"] = gains
-    cap = its_session.do_capture(req)
-
-    # Compute the mean luma of a center patch.
-    yimg,uimg,vimg = its.image.convert_capture_to_planes(cap)
-    tile = its.image.get_image_patch(yimg, 0.45, 0.45, 0.1, 0.1)
-    luma_mean = its.image.compute_image_means(tile)
-
-    # Compute the exposure value that would result in a luma of 0.5.
-    return sens * exp_time * 0.5 / luma_mean[0]
-
-def __set_cached_target_exposure(exposure):
-    """Saves the given exposure value to a cached location.
-
-    Once a value is cached, a call to __get_cached_target_exposure will return
-    the value, even from a subsequent test/script run. That is, the value is
-    persisted.
-
-    The value is persisted in a JSON file in the current directory (from which
-    the script calling this function is run).
-
-    Args:
-        exposure: The value to cache.
-    """
-    print "Setting cached target exposure"
-    with open(CACHE_FILENAME, "w") as f:
-        f.write(json.dumps({"exposure":exposure}))
-
-def __get_cached_target_exposure():
-    """Get the cached exposure value.
-
-    Returns:
-        The cached exposure value, or None if there is no valid cached value.
-    """
-    try:
-        with open(CACHE_FILENAME, "r") as f:
-            o = json.load(f)
-            return o["exposure"]
-    except:
-        return None
-
-def clear_cached_target_exposure():
-    """If there is a cached exposure value, clear it.
-    """
-    if os.path.isfile(CACHE_FILENAME):
-        os.remove(CACHE_FILENAME)
-
-def set_hardcoded_exposure(exposure):
-    """Set a hard-coded exposure value, rather than relying on measurements.
-
-    The exposure value is the product of sensitivity (ISO) and eposure time
-    (ns) that will result in a center-patch luma value of 0.5 (using a linear
-    tonemap) for the scene that the camera is pointing at.
-
-    If bringing up a new HAL implementation and the ability use the device to
-    measure the scene isn't there yet (e.g. device 3A doesn't work), then a
-    cache file of the appropriate name can be manually created and populated
-    with a hard-coded value using this function.
-
-    Args:
-        exposure: The hard-coded exposure value to set.
-    """
-    __set_cached_target_exposure(exposure)
-
-def get_target_exposure(its_session=None):
-    """Get the target exposure to use.
-
-    If there is a cached value and if the "target" command line parameter is
-    present, then return the cached value. Otherwise, measure a new value from
-    the scene, cache it, then return it.
-
-    Args:
-        its_session: Optional, holding an open device session.
-
-    Returns:
-        The target exposure value.
-    """
-    cached_exposure = None
-    for s in sys.argv[1:]:
-        if s == "target":
-            cached_exposure = __get_cached_target_exposure()
-    if cached_exposure is not None:
-        print "Using cached target exposure"
-        return cached_exposure
-    if its_session is None:
-        with its.device.ItsSession() as cam:
-            measured_exposure = __do_target_exposure_measurement(cam)
-    else:
-        measured_exposure = __do_target_exposure_measurement(its_session)
-    __set_cached_target_exposure(measured_exposure)
-    return measured_exposure
-
-def get_target_exposure_combos(its_session=None):
-    """Get a set of legal combinations of target (exposure time, sensitivity).
-
-    Gets the target exposure value, which is a product of sensitivity (ISO) and
-    exposure time, and returns equivalent tuples of (exposure time,sensitivity)
-    that are all legal and that correspond to the four extrema in this 2D param
-    space, as well as to two "middle" points.
-
-    Will open a device session if its_session is None.
-
-    Args:
-        its_session: Optional, holding an open device session.
-
-    Returns:
-        Object containing six legal (exposure time, sensitivity) tuples, keyed
-        by the following strings:
-            "minExposureTime"
-            "midExposureTime"
-            "maxExposureTime"
-            "minSensitivity"
-            "midSensitivity"
-            "maxSensitivity
-    """
-    if its_session is None:
-        with its.device.ItsSession() as cam:
-            exposure = get_target_exposure(cam)
-            props = cam.get_camera_properties()
-    else:
-        exposure = get_target_exposure(its_session)
-        props = its_session.get_camera_properties()
-
-    sens_range = props['android.sensor.info.sensitivityRange']
-    exp_time_range = props['android.sensor.info.exposureTimeRange']
-
-    # Combo 1: smallest legal exposure time.
-    e1_expt = exp_time_range[0]
-    e1_sens = exposure / e1_expt
-    if e1_sens > sens_range[1]:
-        e1_sens = sens_range[1]
-        e1_expt = exposure / e1_sens
-
-    # Combo 2: largest legal exposure time.
-    e2_expt = exp_time_range[1]
-    e2_sens = exposure / e2_expt
-    if e2_sens < sens_range[0]:
-        e2_sens = sens_range[0]
-        e2_expt = exposure / e2_sens
-
-    # Combo 3: smallest legal sensitivity.
-    e3_sens = sens_range[0]
-    e3_expt = exposure / e3_sens
-    if e3_expt > exp_time_range[1]:
-        e3_expt = exp_time_range[1]
-        e3_sens = exposure / e3_expt
-
-    # Combo 4: largest legal sensitivity.
-    e4_sens = sens_range[1]
-    e4_expt = exposure / e4_sens
-    if e4_expt < exp_time_range[0]:
-        e4_expt = exp_time_range[0]
-        e4_sens = exposure / e4_expt
-
-    # Combo 5: middle exposure time.
-    e5_expt = (exp_time_range[0] + exp_time_range[1]) / 2.0
-    e5_sens = exposure / e5_expt
-    if e5_sens > sens_range[1]:
-        e5_sens = sens_range[1]
-        e5_expt = exposure / e5_sens
-    if e5_sens < sens_range[0]:
-        e5_sens = sens_range[0]
-        e5_expt = exposure / e5_sens
-
-    # Combo 6: middle sensitivity.
-    e6_sens = (sens_range[0] + sens_range[1]) / 2.0
-    e6_expt = exposure / e6_sens
-    if e6_expt > exp_time_range[1]:
-        e6_expt = exp_time_range[1]
-        e6_sens = exposure / e6_expt
-    if e6_expt < exp_time_range[0]:
-        e6_expt = exp_time_range[0]
-        e6_sens = exposure / e6_expt
-
-    return {
-        "minExposureTime" : (int(e1_expt), int(e1_sens)),
-        "maxExposureTime" : (int(e2_expt), int(e2_sens)),
-        "minSensitivity" : (int(e3_expt), int(e3_sens)),
-        "maxSensitivity" : (int(e4_expt), int(e4_sens)),
-        "midExposureTime" : (int(e5_expt), int(e5_sens)),
-        "midSensitivity" : (int(e6_expt), int(e6_sens))
-        }
-
-class __UnitTest(unittest.TestCase):
-    """Run a suite of unit tests on this module.
-    """
-    # TODO: Add some unit tests.
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/apps/CameraITS/service/Android.mk b/apps/CameraITS/service/Android.mk
deleted file mode 100644
index 5bb67a1..0000000
--- a/apps/CameraITS/service/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2013 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.
-
-ifeq ($(TARGET_BUILD_JAVA_SUPPORT_LEVEL),platform)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_STATIC_JAVA_LIBRARIES := android-ex-camera2
-
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := ItsService
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/apps/CameraITS/service/AndroidManifest.xml b/apps/CameraITS/service/AndroidManifest.xml
deleted file mode 100644
index 1dcadd5..0000000
--- a/apps/CameraITS/service/AndroidManifest.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright (C) 2013 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.
--->
-
-<manifest
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.camera2.its">
-  <uses-feature android:name="android.hardware.camera" android:required="true"/>
-  <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
-  <uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
-  <uses-feature android:name="android.hardware.camera.front" android:required="false"/>
-  <uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
-  <uses-feature android:name="android.hardware.sensor.compass" android:required="true" />
-  <uses-feature android:name="android.hardware.sensor.gyroscope" android:required="true" />
-  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-  <uses-permission android:name="android.permission.CAMERA" />
-  <uses-permission android:name="android.permission.INTERNET" />
-  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
-  <uses-permission android:name="android.permission.WAKE_LOCK" />
-  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-  <uses-permission android:name="android.permission.VIBRATE" />
-  <application
-      android:label="@string/app_name"
-      android:largeHeap="true"
-      android:theme="@android:style/Theme.Holo"
-      >
-    <service
-        android:name=".ItsService"
-        android:label="@string/app_name"
-        >
-      <intent-filter>
-        <action android:name="com.android.camera2.its.START"/>
-        <category android:name="android.intent.category.DEFAULT" />
-        <data android:mimeType="text/plain" />
-      </intent-filter>
-    </service>
-  </application>
-</manifest>
-
diff --git a/apps/CameraITS/service/res/values/strings.xml b/apps/CameraITS/service/res/values/strings.xml
deleted file mode 100644
index bd70229..0000000
--- a/apps/CameraITS/service/res/values/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright (C) 2013 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.
--->
-
-<resources>
-    <string name="app_name">ItsService</string>
-</resources>
diff --git a/apps/CameraITS/service/src/com/android/camera2/its/ItsException.java b/apps/CameraITS/service/src/com/android/camera2/its/ItsException.java
deleted file mode 100644
index 87af0b5..0000000
--- a/apps/CameraITS/service/src/com/android/camera2/its/ItsException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package com.android.camera2.its;
-
-/**
- * All exceptions are converted to ItsExceptions.
- */
-class ItsException extends Exception {
-    public ItsException(Throwable cause) {
-        super(cause);
-    }
-
-    public ItsException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    public ItsException(String message) {
-        super(message);
-    }
-}
diff --git a/apps/CameraITS/service/src/com/android/camera2/its/ItsSerializer.java b/apps/CameraITS/service/src/com/android/camera2/its/ItsSerializer.java
deleted file mode 100644
index 943a73f..0000000
--- a/apps/CameraITS/service/src/com/android/camera2/its/ItsSerializer.java
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package com.android.camera2.its;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.BlackLevelPattern;
-import android.hardware.camera2.params.ColorSpaceTransform;
-import android.hardware.camera2.params.Face;
-import android.hardware.camera2.params.LensShadingMap;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.camera2.params.RggbChannelVector;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.hardware.camera2.params.TonemapCurve;
-import android.location.Location;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Rational;
-import android.util.Size;
-import android.util.SizeF;
-import android.util.Range;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Class to deal with serializing and deserializing between JSON and Camera2 objects.
- */
-public class ItsSerializer {
-    public static final String TAG = ItsSerializer.class.getSimpleName();
-
-    private static class MetadataEntry {
-        public MetadataEntry(String k, Object v) {
-            key = k;
-            value = v;
-        }
-        public String key;
-        public Object value;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeRational(Rational rat) throws org.json.JSONException {
-        JSONObject ratObj = new JSONObject();
-        ratObj.put("numerator", rat.getNumerator());
-        ratObj.put("denominator", rat.getDenominator());
-        return ratObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeSize(Size size) throws org.json.JSONException {
-        JSONObject sizeObj = new JSONObject();
-        sizeObj.put("width", size.getWidth());
-        sizeObj.put("height", size.getHeight());
-        return sizeObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeSizeF(SizeF size) throws org.json.JSONException {
-        JSONObject sizeObj = new JSONObject();
-        sizeObj.put("width", size.getWidth());
-        sizeObj.put("height", size.getHeight());
-        return sizeObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeRect(Rect rect) throws org.json.JSONException {
-        JSONObject rectObj = new JSONObject();
-        rectObj.put("left", rect.left);
-        rectObj.put("right", rect.right);
-        rectObj.put("top", rect.top);
-        rectObj.put("bottom", rect.bottom);
-        return rectObj;
-    }
-
-    private static Object serializePoint(Point point) throws org.json.JSONException {
-        JSONObject pointObj = new JSONObject();
-        pointObj.put("x", point.x);
-        pointObj.put("y", point.y);
-        return pointObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeFace(Face face)
-            throws org.json.JSONException {
-        JSONObject faceObj = new JSONObject();
-        faceObj.put("bounds", serializeRect(face.getBounds()));
-        faceObj.put("score", face.getScore());
-        faceObj.put("id", face.getId());
-        faceObj.put("leftEye", serializePoint(face.getLeftEyePosition()));
-        faceObj.put("rightEye", serializePoint(face.getRightEyePosition()));
-        faceObj.put("mouth", serializePoint(face.getMouthPosition()));
-        return faceObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeStreamConfigurationMap(
-            StreamConfigurationMap map)
-            throws org.json.JSONException {
-        // TODO: Serialize the rest of the StreamConfigurationMap fields.
-        JSONObject mapObj = new JSONObject();
-        JSONArray cfgArray = new JSONArray();
-        int fmts[] = map.getOutputFormats();
-        if (fmts != null) {
-            for (int fi = 0; fi < Array.getLength(fmts); fi++) {
-                Size sizes[] = map.getOutputSizes(fmts[fi]);
-                if (sizes != null) {
-                    for (int si = 0; si < Array.getLength(sizes); si++) {
-                        JSONObject obj = new JSONObject();
-                        obj.put("format", fmts[fi]);
-                        obj.put("width",sizes[si].getWidth());
-                        obj.put("height", sizes[si].getHeight());
-                        obj.put("input", false);
-                        obj.put("minFrameDuration",
-                                map.getOutputMinFrameDuration(fmts[fi],sizes[si]));
-                        cfgArray.put(obj);
-                    }
-                }
-            }
-        }
-        mapObj.put("availableStreamConfigurations", cfgArray);
-        return mapObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeMeteringRectangle(MeteringRectangle rect)
-            throws org.json.JSONException {
-        JSONObject rectObj = new JSONObject();
-        rectObj.put("x", rect.getX());
-        rectObj.put("y", rect.getY());
-        rectObj.put("width", rect.getWidth());
-        rectObj.put("height", rect.getHeight());
-        rectObj.put("weight", rect.getMeteringWeight());
-        return rectObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializePair(Pair pair)
-            throws org.json.JSONException {
-        JSONArray pairObj = new JSONArray();
-        pairObj.put(pair.first);
-        pairObj.put(pair.second);
-        return pairObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeRange(Range range)
-            throws org.json.JSONException {
-        JSONArray rangeObj = new JSONArray();
-        rangeObj.put(range.getLower());
-        rangeObj.put(range.getUpper());
-        return rangeObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeColorSpaceTransform(ColorSpaceTransform xform)
-            throws org.json.JSONException {
-        JSONArray xformObj = new JSONArray();
-        for (int row = 0; row < 3; row++) {
-            for (int col = 0; col < 3; col++) {
-                xformObj.put(serializeRational(xform.getElement(col,row)));
-            }
-        }
-        return xformObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeTonemapCurve(TonemapCurve curve)
-            throws org.json.JSONException {
-        JSONObject curveObj = new JSONObject();
-        String names[] = {"red", "green", "blue"};
-        for (int ch = 0; ch < 3; ch++) {
-            JSONArray curveArr = new JSONArray();
-            int len = curve.getPointCount(ch);
-            for (int i = 0; i < len; i++) {
-                curveArr.put(curve.getPoint(ch,i).x);
-                curveArr.put(curve.getPoint(ch,i).y);
-            }
-            curveObj.put(names[ch], curveArr);
-        }
-        return curveObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeRggbChannelVector(RggbChannelVector vec)
-            throws org.json.JSONException {
-        JSONArray vecObj = new JSONArray();
-        vecObj.put(vec.getRed());
-        vecObj.put(vec.getGreenEven());
-        vecObj.put(vec.getGreenOdd());
-        vecObj.put(vec.getBlue());
-        return vecObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeBlackLevelPattern(BlackLevelPattern pat)
-            throws org.json.JSONException {
-        int patVals[] = new int[4];
-        pat.copyTo(patVals, 0);
-        JSONArray patObj = new JSONArray();
-        patObj.put(patVals[0]);
-        patObj.put(patVals[1]);
-        patObj.put(patVals[2]);
-        patObj.put(patVals[3]);
-        return patObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeLocation(Location loc)
-            throws org.json.JSONException {
-        return loc.toString();
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Object serializeLensShadingMap(LensShadingMap map)
-            throws org.json.JSONException {
-        JSONArray mapObj = new JSONArray();
-        for (int row = 0; row < map.getRowCount(); row++) {
-            for (int col = 0; col < map.getColumnCount(); col++) {
-                for (int ch = 0; ch < 4; ch++) {
-                    mapObj.put(map.getGainFactor(ch, col, row));
-                }
-            }
-        }
-        return mapObj;
-    }
-
-    private static String getKeyName(Object keyObj) throws ItsException {
-        if (keyObj.getClass() == CaptureResult.Key.class
-                || keyObj.getClass() == TotalCaptureResult.class) {
-            return ((CaptureResult.Key)keyObj).getName();
-        } else if (keyObj.getClass() == CaptureRequest.Key.class) {
-            return ((CaptureRequest.Key)keyObj).getName();
-        } else if (keyObj.getClass() == CameraCharacteristics.Key.class) {
-            return ((CameraCharacteristics.Key)keyObj).getName();
-        }
-        throw new ItsException("Invalid key object");
-    }
-
-    private static Object getKeyValue(CameraMetadata md, Object keyObj) throws ItsException {
-        if (md.getClass() == CaptureResult.class || md.getClass() == TotalCaptureResult.class) {
-            return ((CaptureResult)md).get((CaptureResult.Key)keyObj);
-        } else if (md.getClass() == CaptureRequest.class) {
-            return ((CaptureRequest)md).get((CaptureRequest.Key)keyObj);
-        } else if (md.getClass() == CameraCharacteristics.class) {
-            return ((CameraCharacteristics)md).get((CameraCharacteristics.Key)keyObj);
-        }
-        throw new ItsException("Invalid key object");
-    }
-
-    @SuppressWarnings("unchecked")
-    private static MetadataEntry serializeEntry(Type keyType, Object keyObj, CameraMetadata md)
-            throws ItsException {
-        String keyName = getKeyName(keyObj);
-
-        try {
-            Object keyValue = getKeyValue(md, keyObj);
-            if (keyValue == null) {
-                return new MetadataEntry(keyName, JSONObject.NULL);
-            } else if (keyType == Float.class) {
-                // The JSON serializer doesn't handle floating point NaN or Inf.
-                if (((Float)keyValue).isInfinite() || ((Float)keyValue).isNaN()) {
-                    Logt.w(TAG, "Inf/NaN floating point value serialized: " + keyName);
-                    return null;
-                }
-                return new MetadataEntry(keyName, keyValue);
-            } else if (keyType == Integer.class || keyType == Long.class || keyType == Byte.class ||
-                       keyType == Boolean.class || keyType == String.class) {
-                return new MetadataEntry(keyName, keyValue);
-            } else if (keyType == Rational.class) {
-                return new MetadataEntry(keyName, serializeRational((Rational)keyValue));
-            } else if (keyType == Size.class) {
-                return new MetadataEntry(keyName, serializeSize((Size)keyValue));
-            } else if (keyType == SizeF.class) {
-                return new MetadataEntry(keyName, serializeSizeF((SizeF)keyValue));
-            } else if (keyType == Rect.class) {
-                return new MetadataEntry(keyName, serializeRect((Rect)keyValue));
-            } else if (keyType == Face.class) {
-                return new MetadataEntry(keyName, serializeFace((Face)keyValue));
-            } else if (keyType == StreamConfigurationMap.class) {
-                return new MetadataEntry(keyName,
-                        serializeStreamConfigurationMap((StreamConfigurationMap)keyValue));
-            } else if (keyType instanceof ParameterizedType &&
-                    ((ParameterizedType)keyType).getRawType() == Range.class) {
-                return new MetadataEntry(keyName, serializeRange((Range)keyValue));
-            } else if (keyType == ColorSpaceTransform.class) {
-                return new MetadataEntry(keyName,
-                        serializeColorSpaceTransform((ColorSpaceTransform)keyValue));
-            } else if (keyType == MeteringRectangle.class) {
-                return new MetadataEntry(keyName,
-                        serializeMeteringRectangle((MeteringRectangle)keyValue));
-            } else if (keyType == Location.class) {
-                return new MetadataEntry(keyName,
-                        serializeLocation((Location)keyValue));
-            } else if (keyType == RggbChannelVector.class) {
-                return new MetadataEntry(keyName,
-                        serializeRggbChannelVector((RggbChannelVector)keyValue));
-            } else if (keyType == BlackLevelPattern.class) {
-                return new MetadataEntry(keyName,
-                        serializeBlackLevelPattern((BlackLevelPattern)keyValue));
-            } else if (keyType == TonemapCurve.class) {
-                return new MetadataEntry(keyName,
-                        serializeTonemapCurve((TonemapCurve)keyValue));
-            } else if (keyType == Point.class) {
-                return new MetadataEntry(keyName,
-                        serializePoint((Point)keyValue));
-            } else if (keyType == LensShadingMap.class) {
-                return new MetadataEntry(keyName,
-                        serializeLensShadingMap((LensShadingMap)keyValue));
-            } else {
-                Logt.w(TAG, String.format("Serializing unsupported key type: " + keyType));
-                return null;
-            }
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error for key: " + keyName + ": ", e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private static MetadataEntry serializeArrayEntry(Type keyType, Object keyObj, CameraMetadata md)
-            throws ItsException {
-        String keyName = getKeyName(keyObj);
-        try {
-            Object keyValue = getKeyValue(md, keyObj);
-            if (keyValue == null) {
-                return new MetadataEntry(keyName, JSONObject.NULL);
-            }
-            int arrayLen = Array.getLength(keyValue);
-            Type elmtType = ((GenericArrayType)keyType).getGenericComponentType();
-            if (elmtType == int.class  || elmtType == float.class || elmtType == byte.class ||
-                elmtType == long.class || elmtType == double.class || elmtType == boolean.class) {
-                return new MetadataEntry(keyName, new JSONArray(keyValue));
-            } else if (elmtType == Rational.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeRational((Rational)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == Size.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeSize((Size)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == Rect.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeRect((Rect)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == Face.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeFace((Face)Array.get(keyValue, i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == StreamConfigurationMap.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeStreamConfigurationMap(
-                            (StreamConfigurationMap)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType instanceof ParameterizedType &&
-                    ((ParameterizedType)elmtType).getRawType() == Range.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeRange((Range)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType instanceof ParameterizedType &&
-                    ((ParameterizedType)elmtType).getRawType() == Pair.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializePair((Pair)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == MeteringRectangle.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeMeteringRectangle(
-                            (MeteringRectangle)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == Location.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeLocation((Location)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == RggbChannelVector.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeRggbChannelVector(
-                            (RggbChannelVector)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == BlackLevelPattern.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializeBlackLevelPattern(
-                            (BlackLevelPattern)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else if (elmtType == Point.class) {
-                JSONArray jsonArray = new JSONArray();
-                for (int i = 0; i < arrayLen; i++) {
-                    jsonArray.put(serializePoint((Point)Array.get(keyValue,i)));
-                }
-                return new MetadataEntry(keyName, jsonArray);
-            } else {
-                Logt.w(TAG, String.format("Serializing unsupported array type: " + elmtType));
-                return null;
-            }
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error for key: " + keyName + ": ", e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public static JSONObject serialize(CameraMetadata md)
-            throws ItsException {
-        JSONObject jsonObj = new JSONObject();
-        Field[] allFields = md.getClass().getDeclaredFields();
-        if (md.getClass() == TotalCaptureResult.class) {
-            allFields = CaptureResult.class.getDeclaredFields();
-        }
-        for (Field field : allFields) {
-            if (Modifier.isPublic(field.getModifiers()) &&
-                    Modifier.isStatic(field.getModifiers()) &&
-                    (field.getType() == CaptureRequest.Key.class
-                      || field.getType() == CaptureResult.Key.class
-                      || field.getType() == TotalCaptureResult.Key.class
-                      || field.getType() == CameraCharacteristics.Key.class) &&
-                    field.getGenericType() instanceof ParameterizedType) {
-                ParameterizedType paramType = (ParameterizedType)field.getGenericType();
-                Type[] argTypes = paramType.getActualTypeArguments();
-                if (argTypes.length > 0) {
-                    try {
-                        Type keyType = argTypes[0];
-                        Object keyObj = field.get(md);
-                        MetadataEntry entry;
-                        if (keyType instanceof GenericArrayType) {
-                            entry = serializeArrayEntry(keyType, keyObj, md);
-                        } else {
-                            entry = serializeEntry(keyType, keyObj, md);
-                        }
-
-                        // TODO: Figure this weird case out.
-                        // There is a weird case where the entry is non-null but the toString
-                        // of the entry is null, and if this happens, the null-ness spreads like
-                        // a virus and makes the whole JSON object null from the top level down.
-                        // Not sure if it's a bug in the library or I'm just not using it right.
-                        // Workaround by checking for this case explicitly and not adding the
-                        // value to the jsonObj when it is detected.
-                        if (entry != null && entry.key != null && entry.value != null
-                                          && entry.value.toString() == null) {
-                            Logt.w(TAG, "Error encountered serializing value for key: " + entry.key);
-                        } else if (entry != null) {
-                            jsonObj.put(entry.key, entry.value);
-                        } else {
-                            // Ignore.
-                        }
-                    } catch (IllegalAccessException e) {
-                        throw new ItsException(
-                                "Access error for field: " + field + ": ", e);
-                    } catch (org.json.JSONException e) {
-                        throw new ItsException(
-                                "JSON error for field: " + field + ": ", e);
-                    }
-                }
-            }
-        }
-        return jsonObj;
-    }
-
-    @SuppressWarnings("unchecked")
-    public static CaptureRequest.Builder deserialize(CaptureRequest.Builder mdDefault,
-            JSONObject jsonReq) throws ItsException {
-        try {
-            Logt.i(TAG, "Parsing JSON capture request ...");
-
-            // Iterate over the CaptureRequest reflected fields.
-            CaptureRequest.Builder md = mdDefault;
-            Field[] allFields = CaptureRequest.class.getDeclaredFields();
-            for (Field field : allFields) {
-                if (Modifier.isPublic(field.getModifiers()) &&
-                        Modifier.isStatic(field.getModifiers()) &&
-                        field.getType() == CaptureRequest.Key.class &&
-                        field.getGenericType() instanceof ParameterizedType) {
-                    ParameterizedType paramType = (ParameterizedType)field.getGenericType();
-                    Type[] argTypes = paramType.getActualTypeArguments();
-                    if (argTypes.length > 0) {
-                        CaptureRequest.Key key = (CaptureRequest.Key)field.get(md);
-                        String keyName = key.getName();
-                        Type keyType = argTypes[0];
-
-                        // For each reflected CaptureRequest entry, look inside the JSON object
-                        // to see if it is being set. If it is found, remove the key from the
-                        // JSON object. After this process, there should be no keys left in the
-                        // JSON (otherwise an invalid key was specified).
-
-                        if (jsonReq.has(keyName) && !jsonReq.isNull(keyName)) {
-                            if (keyType instanceof GenericArrayType) {
-                                Type elmtType =
-                                        ((GenericArrayType)keyType).getGenericComponentType();
-                                JSONArray ja = jsonReq.getJSONArray(keyName);
-                                Object val[] = new Object[ja.length()];
-                                for (int i = 0; i < ja.length(); i++) {
-                                    if (elmtType == int.class) {
-                                        Array.set(val, i, ja.getInt(i));
-                                    } else if (elmtType == byte.class) {
-                                        Array.set(val, i, (byte)ja.getInt(i));
-                                    } else if (elmtType == float.class) {
-                                        Array.set(val, i, (float)ja.getDouble(i));
-                                    } else if (elmtType == long.class) {
-                                        Array.set(val, i, ja.getLong(i));
-                                    } else if (elmtType == double.class) {
-                                        Array.set(val, i, ja.getDouble(i));
-                                    } else if (elmtType == boolean.class) {
-                                        Array.set(val, i, ja.getBoolean(i));
-                                    } else if (elmtType == String.class) {
-                                        Array.set(val, i, ja.getString(i));
-                                    } else if (elmtType == Size.class){
-                                        JSONObject obj = ja.getJSONObject(i);
-                                        Array.set(val, i, new Size(
-                                                obj.getInt("width"), obj.getInt("height")));
-                                    } else if (elmtType == Rect.class) {
-                                        JSONObject obj = ja.getJSONObject(i);
-                                        Array.set(val, i, new Rect(
-                                                obj.getInt("left"), obj.getInt("top"),
-                                                obj.getInt("bottom"), obj.getInt("right")));
-                                    } else if (elmtType == Rational.class) {
-                                        JSONObject obj = ja.getJSONObject(i);
-                                        Array.set(val, i, new Rational(
-                                                obj.getInt("numerator"),
-                                                obj.getInt("denominator")));
-                                    } else if (elmtType == RggbChannelVector.class) {
-                                        JSONArray arr = ja.getJSONArray(i);
-                                        Array.set(val, i, new RggbChannelVector(
-                                                (float)arr.getDouble(0),
-                                                (float)arr.getDouble(1),
-                                                (float)arr.getDouble(2),
-                                                (float)arr.getDouble(3)));
-                                    } else if (elmtType == ColorSpaceTransform.class) {
-                                        JSONArray arr = ja.getJSONArray(i);
-                                        Rational xform[] = new Rational[9];
-                                        for (int j = 0; j < 9; j++) {
-                                            xform[j] = new Rational(
-                                                    arr.getJSONObject(j).getInt("numerator"),
-                                                    arr.getJSONObject(j).getInt("denominator"));
-                                        }
-                                        Array.set(val, i, new ColorSpaceTransform(xform));
-                                    } else if (elmtType == MeteringRectangle.class) {
-                                        JSONObject obj = ja.getJSONObject(i);
-                                        Array.set(val, i, new MeteringRectangle(
-                                                obj.getInt("x"),
-                                                obj.getInt("y"),
-                                                obj.getInt("width"),
-                                                obj.getInt("height"),
-                                                obj.getInt("weight")));
-                                    } else {
-                                        throw new ItsException(
-                                                "Failed to parse key from JSON: " + keyName);
-                                    }
-                                }
-                                if (val != null) {
-                                    Logt.i(TAG, "Set: "+keyName+" -> "+Arrays.toString(val));
-                                    md.set(key, val);
-                                    jsonReq.remove(keyName);
-                                }
-                            } else {
-                                Object val = null;
-                                if (keyType == Integer.class) {
-                                    val = jsonReq.getInt(keyName);
-                                } else if (keyType == Byte.class) {
-                                    val = (byte)jsonReq.getInt(keyName);
-                                } else if (keyType == Double.class) {
-                                    val = jsonReq.getDouble(keyName);
-                                } else if (keyType == Long.class) {
-                                    val = jsonReq.getLong(keyName);
-                                } else if (keyType == Float.class) {
-                                    val = (float)jsonReq.getDouble(keyName);
-                                } else if (keyType == Boolean.class) {
-                                    val = jsonReq.getBoolean(keyName);
-                                } else if (keyType == String.class) {
-                                    val = jsonReq.getString(keyName);
-                                } else if (keyType == Size.class) {
-                                    JSONObject obj = jsonReq.getJSONObject(keyName);
-                                    val = new Size(
-                                            obj.getInt("width"), obj.getInt("height"));
-                                } else if (keyType == Rect.class) {
-                                    JSONObject obj = jsonReq.getJSONObject(keyName);
-                                    val = new Rect(
-                                            obj.getInt("left"), obj.getInt("top"),
-                                            obj.getInt("right"), obj.getInt("bottom"));
-                                } else if (keyType == Rational.class) {
-                                    JSONObject obj = jsonReq.getJSONObject(keyName);
-                                    val = new Rational(obj.getInt("numerator"),
-                                                       obj.getInt("denominator"));
-                                } else if (keyType == RggbChannelVector.class) {
-                                    JSONObject obj = jsonReq.optJSONObject(keyName);
-                                    JSONArray arr = jsonReq.optJSONArray(keyName);
-                                    if (arr != null) {
-                                        val = new RggbChannelVector(
-                                                (float)arr.getDouble(0),
-                                                (float)arr.getDouble(1),
-                                                (float)arr.getDouble(2),
-                                                (float)arr.getDouble(3));
-                                    } else if (obj != null) {
-                                        val = new RggbChannelVector(
-                                                (float)obj.getDouble("red"),
-                                                (float)obj.getDouble("greenEven"),
-                                                (float)obj.getDouble("greenOdd"),
-                                                (float)obj.getDouble("blue"));
-                                    } else {
-                                        throw new ItsException("Invalid RggbChannelVector object");
-                                    }
-                                } else if (keyType == ColorSpaceTransform.class) {
-                                    JSONArray arr = jsonReq.getJSONArray(keyName);
-                                    Rational a[] = new Rational[9];
-                                    for (int i = 0; i < 9; i++) {
-                                        a[i] = new Rational(
-                                                arr.getJSONObject(i).getInt("numerator"),
-                                                arr.getJSONObject(i).getInt("denominator"));
-                                    }
-                                    val = new ColorSpaceTransform(a);
-                                } else if (keyType instanceof ParameterizedType &&
-                                        ((ParameterizedType)keyType).getRawType() == Range.class &&
-                                        ((ParameterizedType)keyType).getActualTypeArguments().length == 1 &&
-                                        ((ParameterizedType)keyType).getActualTypeArguments()[0] == Integer.class) {
-                                    JSONArray arr = jsonReq.getJSONArray(keyName);
-                                    val = new Range<Integer>(arr.getInt(0), arr.getInt(1));
-                                } else {
-                                    throw new ItsException(
-                                            "Failed to parse key from JSON: " +
-                                            keyName + ", " + keyType);
-                                }
-                                if (val != null) {
-                                    Logt.i(TAG, "Set: " + keyName + " -> " + val);
-                                    md.set(key ,val);
-                                    jsonReq.remove(keyName);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            // Ensure that there were no invalid keys in the JSON request object.
-            if (jsonReq.length() != 0) {
-                throw new ItsException("Invalid JSON key(s): " + jsonReq.toString());
-            }
-
-            Logt.i(TAG, "Parsing JSON capture request completed");
-            return md;
-        } catch (java.lang.IllegalAccessException e) {
-            throw new ItsException("Access error: ", e);
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error: ", e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public static List<CaptureRequest.Builder> deserializeRequestList(
-            CameraDevice device, JSONObject jsonObjTop)
-            throws ItsException {
-        try {
-            List<CaptureRequest.Builder> requests = null;
-            JSONArray jsonReqs = jsonObjTop.getJSONArray("captureRequests");
-            requests = new LinkedList<CaptureRequest.Builder>();
-            for (int i = 0; i < jsonReqs.length(); i++) {
-                CaptureRequest.Builder templateReq = device.createCaptureRequest(
-                        CameraDevice.TEMPLATE_STILL_CAPTURE);
-                requests.add(
-                    deserialize(templateReq, jsonReqs.getJSONObject(i)));
-            }
-            return requests;
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error: ", e);
-        } catch (android.hardware.camera2.CameraAccessException e) {
-            throw new ItsException("Access error: ", e);
-        }
-    }
-}
diff --git a/apps/CameraITS/service/src/com/android/camera2/its/ItsService.java b/apps/CameraITS/service/src/com/android/camera2/its/ItsService.java
deleted file mode 100644
index 1c497ea..0000000
--- a/apps/CameraITS/service/src/com/android/camera2/its/ItsService.java
+++ /dev/null
@@ -1,1319 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package com.android.camera2.its;
-
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CaptureFailure;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.DngCreator;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.media.Image;
-import android.media.ImageReader;
-import android.net.Uri;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Vibrator;
-import android.util.Log;
-import android.util.Rational;
-import android.util.Size;
-import android.view.Surface;
-
-import com.android.ex.camera2.blocking.BlockingCameraManager;
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.math.BigInteger;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketTimeoutException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class ItsService extends Service implements SensorEventListener {
-    public static final String TAG = ItsService.class.getSimpleName();
-
-    // Timeouts, in seconds.
-    public static final int TIMEOUT_CALLBACK = 3;
-    public static final int TIMEOUT_3A = 10;
-
-    // State transition timeouts, in ms.
-    private static final long TIMEOUT_IDLE_MS = 2000;
-    private static final long TIMEOUT_STATE_MS = 500;
-
-    // Timeout to wait for a capture result after the capture buffer has arrived, in ms.
-    private static final long TIMEOUT_CAP_RES = 2000;
-
-    private static final int MAX_CONCURRENT_READER_BUFFERS = 8;
-
-    // Supports at most RAW+YUV+JPEG, one surface each.
-    private static final int MAX_NUM_OUTPUT_SURFACES = 3;
-
-    public static final int SERVERPORT = 6000;
-
-    public static final String REGION_KEY = "regions";
-    public static final String REGION_AE_KEY = "ae";
-    public static final String REGION_AWB_KEY = "awb";
-    public static final String REGION_AF_KEY = "af";
-    public static final String LOCK_AE_KEY = "aeLock";
-    public static final String LOCK_AWB_KEY = "awbLock";
-    public static final String TRIGGER_KEY = "triggers";
-    public static final String TRIGGER_AE_KEY = "ae";
-    public static final String TRIGGER_AF_KEY = "af";
-    public static final String VIB_PATTERN_KEY = "pattern";
-
-    private CameraManager mCameraManager = null;
-    private HandlerThread mCameraThread = null;
-    private Handler mCameraHandler = null;
-    private BlockingCameraManager mBlockingCameraManager = null;
-    private BlockingStateCallback mCameraListener = null;
-    private CameraDevice mCamera = null;
-    private CameraCaptureSession mSession = null;
-    private ImageReader[] mCaptureReaders = null;
-    private CameraCharacteristics mCameraCharacteristics = null;
-
-    private Vibrator mVibrator = null;
-
-    private HandlerThread mSaveThreads[] = new HandlerThread[MAX_NUM_OUTPUT_SURFACES];
-    private Handler mSaveHandlers[] = new Handler[MAX_NUM_OUTPUT_SURFACES];
-    private HandlerThread mResultThread = null;
-    private Handler mResultHandler = null;
-
-    private volatile boolean mThreadExitFlag = false;
-
-    private volatile ServerSocket mSocket = null;
-    private volatile SocketRunnable mSocketRunnableObj = null;
-    private volatile BlockingQueue<ByteBuffer> mSocketWriteQueue =
-            new LinkedBlockingDeque<ByteBuffer>();
-    private final Object mSocketWriteEnqueueLock = new Object();
-    private final Object mSocketWriteDrainLock = new Object();
-
-    private volatile BlockingQueue<Object[]> mSerializerQueue =
-            new LinkedBlockingDeque<Object[]>();
-
-    private AtomicInteger mCountCallbacksRemaining = new AtomicInteger();
-    private AtomicInteger mCountRawOrDng = new AtomicInteger();
-    private AtomicInteger mCountRaw10 = new AtomicInteger();
-    private AtomicInteger mCountJpg = new AtomicInteger();
-    private AtomicInteger mCountYuv = new AtomicInteger();
-    private AtomicInteger mCountCapRes = new AtomicInteger();
-    private boolean mCaptureRawIsDng;
-    private CaptureResult mCaptureResults[] = null;
-
-    private volatile ConditionVariable mInterlock3A = new ConditionVariable(true);
-    private volatile boolean mIssuedRequest3A = false;
-    private volatile boolean mConvergedAE = false;
-    private volatile boolean mConvergedAF = false;
-    private volatile boolean mConvergedAWB = false;
-    private volatile boolean mLockedAE = false;
-    private volatile boolean mLockedAWB = false;
-    private volatile boolean mNeedsLockedAE = false;
-    private volatile boolean mNeedsLockedAWB = false;
-
-    class MySensorEvent {
-        public Sensor sensor;
-        public int accuracy;
-        public long timestamp;
-        public float values[];
-    }
-
-    // For capturing motion sensor traces.
-    private SensorManager mSensorManager = null;
-    private Sensor mAccelSensor = null;
-    private Sensor mMagSensor = null;
-    private Sensor mGyroSensor = null;
-    private volatile LinkedList<MySensorEvent> mEvents = null;
-    private volatile Object mEventLock = new Object();
-    private volatile boolean mEventsEnabled = false;
-
-    public interface CaptureCallback {
-        void onCaptureAvailable(Image capture);
-    }
-
-    public abstract class CaptureResultListener extends CameraCaptureSession.CaptureCallback {}
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public void onCreate() {
-        try {
-            mThreadExitFlag = false;
-
-            // Get handle to camera manager.
-            mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
-            if (mCameraManager == null) {
-                throw new ItsException("Failed to connect to camera manager");
-            }
-            mBlockingCameraManager = new BlockingCameraManager(mCameraManager);
-            mCameraListener = new BlockingStateCallback();
-
-            // Register for motion events.
-            mEvents = new LinkedList<MySensorEvent>();
-            mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
-            mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
-            mMagSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
-            mGyroSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
-            mSensorManager.registerListener(this, mAccelSensor, SensorManager.SENSOR_DELAY_FASTEST);
-            mSensorManager.registerListener(this, mMagSensor, SensorManager.SENSOR_DELAY_FASTEST);
-            mSensorManager.registerListener(this, mGyroSensor, SensorManager.SENSOR_DELAY_FASTEST);
-
-            // Get a handle to the system vibrator.
-            mVibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
-
-            // Create threads to receive images and save them.
-            for (int i = 0; i < MAX_NUM_OUTPUT_SURFACES; i++) {
-                mSaveThreads[i] = new HandlerThread("SaveThread" + i);
-                mSaveThreads[i].start();
-                mSaveHandlers[i] = new Handler(mSaveThreads[i].getLooper());
-            }
-
-            // Create a thread to handle object serialization.
-            (new Thread(new SerializerRunnable())).start();;
-
-            // Create a thread to receive capture results and process them.
-            mResultThread = new HandlerThread("ResultThread");
-            mResultThread.start();
-            mResultHandler = new Handler(mResultThread.getLooper());
-
-            // Create a thread for the camera device.
-            mCameraThread = new HandlerThread("ItsCameraThread");
-            mCameraThread.start();
-            mCameraHandler = new Handler(mCameraThread.getLooper());
-
-            // Create a thread to process commands, listening on a TCP socket.
-            mSocketRunnableObj = new SocketRunnable();
-            (new Thread(mSocketRunnableObj)).start();
-        } catch (ItsException e) {
-            Logt.e(TAG, "Service failed to start: ", e);
-        }
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        try {
-            // Just log a message indicating that the service is running and is able to accept
-            // socket connections.
-            while (!mThreadExitFlag && mSocket==null) {
-                Thread.sleep(1);
-            }
-            if (!mThreadExitFlag){
-                Logt.i(TAG, "ItsService ready");
-            } else {
-                Logt.e(TAG, "Starting ItsService in bad state");
-            }
-        } catch (java.lang.InterruptedException e) {
-            Logt.e(TAG, "Error starting ItsService (interrupted)", e);
-        }
-        return START_STICKY;
-    }
-
-    @Override
-    public void onDestroy() {
-        mThreadExitFlag = true;
-        for (int i = 0; i < MAX_NUM_OUTPUT_SURFACES; i++) {
-            if (mSaveThreads[i] != null) {
-                mSaveThreads[i].quit();
-                mSaveThreads[i] = null;
-            }
-        }
-        if (mResultThread != null) {
-            mResultThread.quitSafely();
-            mResultThread = null;
-        }
-        if (mCameraThread != null) {
-            mCameraThread.quitSafely();
-            mCameraThread = null;
-        }
-    }
-
-    public void openCameraDevice(int cameraId) throws ItsException {
-        Logt.i(TAG, String.format("Opening camera %d", cameraId));
-
-        String[] devices;
-        try {
-            devices = mCameraManager.getCameraIdList();
-            if (devices == null || devices.length == 0) {
-                throw new ItsException("No camera devices");
-            }
-        } catch (CameraAccessException e) {
-            throw new ItsException("Failed to get device ID list", e);
-        }
-
-        try {
-            mCamera = mBlockingCameraManager.openCamera(devices[cameraId],
-                    mCameraListener, mCameraHandler);
-            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(
-                    devices[cameraId]);
-        } catch (CameraAccessException e) {
-            throw new ItsException("Failed to open camera", e);
-        } catch (BlockingOpenException e) {
-            throw new ItsException("Failed to open camera (after blocking)", e);
-        }
-        mSocketRunnableObj.sendResponse("cameraOpened", "");
-    }
-
-    public void closeCameraDevice() throws ItsException {
-        try {
-            if (mCamera != null) {
-                Logt.i(TAG, "Closing camera");
-                mCamera.close();
-                mCamera = null;
-            }
-        } catch (Exception e) {
-            throw new ItsException("Failed to close device");
-        }
-        mSocketRunnableObj.sendResponse("cameraClosed", "");
-    }
-
-    class SerializerRunnable implements Runnable {
-        // Use a separate thread to perform JSON serialization (since this can be slow due to
-        // the reflection).
-        @Override
-        public void run() {
-            Logt.i(TAG, "Serializer thread starting");
-            while (! mThreadExitFlag) {
-                try {
-                    Object objs[] = mSerializerQueue.take();
-                    JSONObject jsonObj = new JSONObject();
-                    String tag = null;
-                    for (int i = 0; i < objs.length; i++) {
-                        Object obj = objs[i];
-                        if (obj instanceof String) {
-                            if (tag != null) {
-                                throw new ItsException("Multiple tags for socket response");
-                            }
-                            tag = (String)obj;
-                        } else if (obj instanceof CameraCharacteristics) {
-                            jsonObj.put("cameraProperties", ItsSerializer.serialize(
-                                    (CameraCharacteristics)obj));
-                        } else if (obj instanceof CaptureRequest) {
-                            jsonObj.put("captureRequest", ItsSerializer.serialize(
-                                    (CaptureRequest)obj));
-                        } else if (obj instanceof CaptureResult) {
-                            jsonObj.put("captureResult", ItsSerializer.serialize(
-                                    (CaptureResult)obj));
-                        } else if (obj instanceof JSONArray) {
-                            jsonObj.put("outputs", (JSONArray)obj);
-                        } else {
-                            throw new ItsException("Invalid object received for serialiation");
-                        }
-                    }
-                    if (tag == null) {
-                        throw new ItsException("No tag provided for socket response");
-                    }
-                    mSocketRunnableObj.sendResponse(tag, null, jsonObj, null);
-                    Logt.i(TAG, String.format("Serialized %s", tag));
-                } catch (org.json.JSONException e) {
-                    Logt.e(TAG, "Error serializing object", e);
-                    break;
-                } catch (ItsException e) {
-                    Logt.e(TAG, "Error serializing object", e);
-                    break;
-                } catch (java.lang.InterruptedException e) {
-                    Logt.e(TAG, "Error serializing object (interrupted)", e);
-                    break;
-                }
-            }
-            Logt.i(TAG, "Serializer thread terminated");
-        }
-    }
-
-    class SocketWriteRunnable implements Runnable {
-
-        // Use a separate thread to service a queue of objects to be written to the socket,
-        // writing each sequentially in order. This is needed since different handler functions
-        // (called on different threads) will need to send data back to the host script.
-
-        public Socket mOpenSocket = null;
-
-        public SocketWriteRunnable(Socket openSocket) {
-            mOpenSocket = openSocket;
-        }
-
-        public void setOpenSocket(Socket openSocket) {
-            mOpenSocket = openSocket;
-        }
-
-        @Override
-        public void run() {
-            Logt.i(TAG, "Socket writer thread starting");
-            while (true) {
-                try {
-                    ByteBuffer b = mSocketWriteQueue.take();
-                    synchronized(mSocketWriteDrainLock) {
-                        if (mOpenSocket == null) {
-                            continue;
-                        }
-                        if (b.hasArray()) {
-                            mOpenSocket.getOutputStream().write(b.array());
-                        } else {
-                            byte[] barray = new byte[b.capacity()];
-                            b.get(barray);
-                            mOpenSocket.getOutputStream().write(barray);
-                        }
-                        mOpenSocket.getOutputStream().flush();
-                        Logt.i(TAG, String.format("Wrote to socket: %d bytes", b.capacity()));
-                    }
-                } catch (IOException e) {
-                    Logt.e(TAG, "Error writing to socket", e);
-                    break;
-                } catch (java.lang.InterruptedException e) {
-                    Logt.e(TAG, "Error writing to socket (interrupted)", e);
-                    break;
-                }
-            }
-            Logt.i(TAG, "Socket writer thread terminated");
-        }
-    }
-
-    class SocketRunnable implements Runnable {
-
-        // Format of sent messages (over the socket):
-        // * Serialized JSON object on a single line (newline-terminated)
-        // * For byte buffers, the binary data then follows
-        //
-        // Format of received messages (from the socket):
-        // * Serialized JSON object on a single line (newline-terminated)
-
-        private Socket mOpenSocket = null;
-        private SocketWriteRunnable mSocketWriteRunnable = null;
-
-        @Override
-        public void run() {
-            Logt.i(TAG, "Socket thread starting");
-            try {
-                mSocket = new ServerSocket(SERVERPORT);
-            } catch (IOException e) {
-                Logt.e(TAG, "Failed to create socket", e);
-            }
-
-            // Create a new thread to handle writes to this socket.
-            mSocketWriteRunnable = new SocketWriteRunnable(null);
-            (new Thread(mSocketWriteRunnable)).start();
-
-            while (!mThreadExitFlag) {
-                // Receive the socket-open request from the host.
-                try {
-                    Logt.i(TAG, "Waiting for client to connect to socket");
-                    mOpenSocket = mSocket.accept();
-                    if (mOpenSocket == null) {
-                        Logt.e(TAG, "Socket connection error");
-                        break;
-                    }
-                    mSocketWriteQueue.clear();
-                    mSocketWriteRunnable.setOpenSocket(mOpenSocket);
-                    Logt.i(TAG, "Socket connected");
-                } catch (IOException e) {
-                    Logt.e(TAG, "Socket open error: ", e);
-                    break;
-                }
-
-                // Process commands over the open socket.
-                while (!mThreadExitFlag) {
-                    try {
-                        BufferedReader input = new BufferedReader(
-                                new InputStreamReader(mOpenSocket.getInputStream()));
-                        if (input == null) {
-                            Logt.e(TAG, "Failed to get socket input stream");
-                            break;
-                        }
-                        String line = input.readLine();
-                        if (line == null) {
-                            Logt.i(TAG, "Socket readline retuned null (host disconnected)");
-                            break;
-                        }
-                        processSocketCommand(line);
-                    } catch (IOException e) {
-                        Logt.e(TAG, "Socket read error: ", e);
-                        break;
-                    } catch (ItsException e) {
-                        Logt.e(TAG, "Script error: ", e);
-                        break;
-                    }
-                }
-
-                // Close socket and go back to waiting for a new connection.
-                try {
-                    synchronized(mSocketWriteDrainLock) {
-                        mSocketWriteQueue.clear();
-                        mOpenSocket.close();
-                        mOpenSocket = null;
-                        Logt.i(TAG, "Socket disconnected");
-                    }
-                } catch (java.io.IOException e) {
-                    Logt.e(TAG, "Exception closing socket");
-                }
-            }
-
-            // It's an overall error state if the code gets here; no recevery.
-            // Try to do some cleanup, but the service probably needs to be restarted.
-            Logt.i(TAG, "Socket server loop exited");
-            mThreadExitFlag = true;
-            try {
-                if (mOpenSocket != null) {
-                    mOpenSocket.close();
-                    mOpenSocket = null;
-                }
-            } catch (java.io.IOException e) {
-                Logt.w(TAG, "Exception closing socket");
-            }
-            try {
-                if (mSocket != null) {
-                    mSocket.close();
-                    mSocket = null;
-                }
-            } catch (java.io.IOException e) {
-                Logt.w(TAG, "Exception closing socket");
-            }
-        }
-
-        public void processSocketCommand(String cmd)
-                throws ItsException {
-            // Each command is a serialized JSON object.
-            try {
-                JSONObject cmdObj = new JSONObject(cmd);
-                if ("open".equals(cmdObj.getString("cmdName"))) {
-                    int cameraId = cmdObj.getInt("cameraId");
-                    openCameraDevice(cameraId);
-                } else if ("close".equals(cmdObj.getString("cmdName"))) {
-                    closeCameraDevice();
-                } else if ("getCameraProperties".equals(cmdObj.getString("cmdName"))) {
-                    doGetProps();
-                } else if ("startSensorEvents".equals(cmdObj.getString("cmdName"))) {
-                    doStartSensorEvents();
-                } else if ("getSensorEvents".equals(cmdObj.getString("cmdName"))) {
-                    doGetSensorEvents();
-                } else if ("do3A".equals(cmdObj.getString("cmdName"))) {
-                    do3A(cmdObj);
-                } else if ("doCapture".equals(cmdObj.getString("cmdName"))) {
-                    doCapture(cmdObj);
-                } else if ("doVibrate".equals(cmdObj.getString("cmdName"))) {
-                    doVibrate(cmdObj);
-                } else {
-                    throw new ItsException("Unknown command: " + cmd);
-                }
-            } catch (org.json.JSONException e) {
-                Logt.e(TAG, "Invalid command: ", e);
-            }
-        }
-
-        public void sendResponse(String tag, String str, JSONObject obj, ByteBuffer bbuf)
-                throws ItsException {
-            try {
-                JSONObject jsonObj = new JSONObject();
-                jsonObj.put("tag", tag);
-                if (str != null) {
-                    jsonObj.put("strValue", str);
-                }
-                if (obj != null) {
-                    jsonObj.put("objValue", obj);
-                }
-                if (bbuf != null) {
-                    jsonObj.put("bufValueSize", bbuf.capacity());
-                }
-                ByteBuffer bstr = ByteBuffer.wrap(
-                        (jsonObj.toString()+"\n").getBytes(Charset.defaultCharset()));
-                synchronized(mSocketWriteEnqueueLock) {
-                    if (bstr != null) {
-                        mSocketWriteQueue.put(bstr);
-                    }
-                    if (bbuf != null) {
-                        mSocketWriteQueue.put(bbuf);
-                    }
-                }
-            } catch (org.json.JSONException e) {
-                throw new ItsException("JSON error: ", e);
-            } catch (java.lang.InterruptedException e) {
-                throw new ItsException("Socket error: ", e);
-            }
-        }
-
-        public void sendResponse(String tag, String str)
-                throws ItsException {
-            sendResponse(tag, str, null, null);
-        }
-
-        public void sendResponse(String tag, JSONObject obj)
-                throws ItsException {
-            sendResponse(tag, null, obj, null);
-        }
-
-        public void sendResponseCaptureBuffer(String tag, ByteBuffer bbuf)
-                throws ItsException {
-            sendResponse(tag, null, null, bbuf);
-        }
-
-        public void sendResponse(LinkedList<MySensorEvent> events)
-                throws ItsException {
-            try {
-                JSONArray accels = new JSONArray();
-                JSONArray mags = new JSONArray();
-                JSONArray gyros = new JSONArray();
-                for (MySensorEvent event : events) {
-                    JSONObject obj = new JSONObject();
-                    obj.put("time", event.timestamp);
-                    obj.put("x", event.values[0]);
-                    obj.put("y", event.values[1]);
-                    obj.put("z", event.values[2]);
-                    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
-                        accels.put(obj);
-                    } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
-                        mags.put(obj);
-                    } else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
-                        gyros.put(obj);
-                    }
-                }
-                JSONObject obj = new JSONObject();
-                obj.put("accel", accels);
-                obj.put("mag", mags);
-                obj.put("gyro", gyros);
-                sendResponse("sensorEvents", null, obj, null);
-            } catch (org.json.JSONException e) {
-                throw new ItsException("JSON error: ", e);
-            }
-        }
-
-        public void sendResponse(CameraCharacteristics props)
-                throws ItsException {
-            try {
-                Object objs[] = new Object[2];
-                objs[0] = "cameraProperties";
-                objs[1] = props;
-                mSerializerQueue.put(objs);
-            } catch (InterruptedException e) {
-                throw new ItsException("Interrupted: ", e);
-            }
-        }
-
-        public void sendResponseCaptureResult(CameraCharacteristics props,
-                                              CaptureRequest request,
-                                              CaptureResult result,
-                                              ImageReader[] readers)
-                throws ItsException {
-            try {
-                JSONArray jsonSurfaces = new JSONArray();
-                for (int i = 0; i < readers.length; i++) {
-                    JSONObject jsonSurface = new JSONObject();
-                    jsonSurface.put("width", readers[i].getWidth());
-                    jsonSurface.put("height", readers[i].getHeight());
-                    int format = readers[i].getImageFormat();
-                    if (format == ImageFormat.RAW_SENSOR) {
-                        jsonSurface.put("format", "raw");
-                    } else if (format == ImageFormat.RAW10) {
-                        jsonSurface.put("format", "raw10");
-                    } else if (format == ImageFormat.JPEG) {
-                        jsonSurface.put("format", "jpeg");
-                    } else if (format == ImageFormat.YUV_420_888) {
-                        jsonSurface.put("format", "yuv");
-                    } else {
-                        throw new ItsException("Invalid format");
-                    }
-                    jsonSurfaces.put(jsonSurface);
-                }
-
-                Object objs[] = new Object[5];
-                objs[0] = "captureResults";
-                objs[1] = props;
-                objs[2] = request;
-                objs[3] = result;
-                objs[4] = jsonSurfaces;
-                mSerializerQueue.put(objs);
-            } catch (org.json.JSONException e) {
-                throw new ItsException("JSON error: ", e);
-            } catch (InterruptedException e) {
-                throw new ItsException("Interrupted: ", e);
-            }
-        }
-    }
-
-    public ImageReader.OnImageAvailableListener
-            createAvailableListener(final CaptureCallback listener) {
-        return new ImageReader.OnImageAvailableListener() {
-            @Override
-            public void onImageAvailable(ImageReader reader) {
-                Image i = null;
-                try {
-                    i = reader.acquireNextImage();
-                    listener.onCaptureAvailable(i);
-                } finally {
-                    if (i != null) {
-                        i.close();
-                    }
-                }
-            }
-        };
-    }
-
-    private ImageReader.OnImageAvailableListener
-            createAvailableListenerDropper(final CaptureCallback listener) {
-        return new ImageReader.OnImageAvailableListener() {
-            @Override
-            public void onImageAvailable(ImageReader reader) {
-                Image i = reader.acquireNextImage();
-                i.close();
-            }
-        };
-    }
-
-    private void doStartSensorEvents() throws ItsException {
-        synchronized(mEventLock) {
-            mEventsEnabled = true;
-        }
-        mSocketRunnableObj.sendResponse("sensorEventsStarted", "");
-    }
-
-    private void doGetSensorEvents() throws ItsException {
-        synchronized(mEventLock) {
-            mSocketRunnableObj.sendResponse(mEvents);
-            mEvents.clear();
-            mEventsEnabled = false;
-        }
-    }
-
-    private void doGetProps() throws ItsException {
-        mSocketRunnableObj.sendResponse(mCameraCharacteristics);
-    }
-
-    private void prepareCaptureReader(int[] widths, int[] heights, int formats[], int numSurfaces) {
-        if (mCaptureReaders != null) {
-            for (int i = 0; i < mCaptureReaders.length; i++) {
-                if (mCaptureReaders[i] != null) {
-                    mCaptureReaders[i].close();
-                }
-            }
-        }
-        mCaptureReaders = new ImageReader[numSurfaces];
-        for (int i = 0; i < numSurfaces; i++) {
-            mCaptureReaders[i] = ImageReader.newInstance(widths[i], heights[i], formats[i],
-                    MAX_CONCURRENT_READER_BUFFERS);
-        }
-    }
-
-    private void do3A(JSONObject params) throws ItsException {
-        try {
-            // Start a 3A action, and wait for it to converge.
-            // Get the converged values for each "A", and package into JSON result for caller.
-
-            // 3A happens on full-res frames.
-            Size sizes[] = ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
-            int widths[] = new int[1];
-            int heights[] = new int[1];
-            int formats[] = new int[1];
-            widths[0] = sizes[0].getWidth();
-            heights[0] = sizes[0].getHeight();
-            formats[0] = ImageFormat.YUV_420_888;
-            int width = widths[0];
-            int height = heights[0];
-
-            prepareCaptureReader(widths, heights, formats, 1);
-            List<Surface> outputSurfaces = new ArrayList<Surface>(1);
-            outputSurfaces.add(mCaptureReaders[0].getSurface());
-            BlockingSessionCallback sessionListener = new BlockingSessionCallback();
-            mCamera.createCaptureSession(outputSurfaces, sessionListener, mCameraHandler);
-            mSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS);
-
-            // Add a listener that just recycles buffers; they aren't saved anywhere.
-            ImageReader.OnImageAvailableListener readerListener =
-                    createAvailableListenerDropper(mCaptureCallback);
-            mCaptureReaders[0].setOnImageAvailableListener(readerListener, mSaveHandlers[0]);
-
-            // Get the user-specified regions for AE, AWB, AF.
-            // Note that the user specifies normalized [x,y,w,h], which is converted below
-            // to an [x0,y0,x1,y1] region in sensor coords. The capture request region
-            // also has a fifth "weight" element: [x0,y0,x1,y1,w].
-            MeteringRectangle[] regionAE = new MeteringRectangle[]{
-                    new MeteringRectangle(0,0,width,height,1)};
-            MeteringRectangle[] regionAF = new MeteringRectangle[]{
-                    new MeteringRectangle(0,0,width,height,1)};
-            MeteringRectangle[] regionAWB = new MeteringRectangle[]{
-                    new MeteringRectangle(0,0,width,height,1)};
-            if (params.has(REGION_KEY)) {
-                JSONObject regions = params.getJSONObject(REGION_KEY);
-                if (regions.has(REGION_AE_KEY)) {
-                    regionAE = ItsUtils.getJsonWeightedRectsFromArray(
-                            regions.getJSONArray(REGION_AE_KEY), true, width, height);
-                }
-                if (regions.has(REGION_AF_KEY)) {
-                    regionAF = ItsUtils.getJsonWeightedRectsFromArray(
-                            regions.getJSONArray(REGION_AF_KEY), true, width, height);
-                }
-                if (regions.has(REGION_AWB_KEY)) {
-                    regionAWB = ItsUtils.getJsonWeightedRectsFromArray(
-                            regions.getJSONArray(REGION_AWB_KEY), true, width, height);
-                }
-            }
-
-            // If AE or AWB lock is specified, then the 3A will converge first and then lock these
-            // values, waiting until the HAL has reported that the lock was successful.
-            mNeedsLockedAE = params.optBoolean(LOCK_AE_KEY, false);
-            mNeedsLockedAWB = params.optBoolean(LOCK_AWB_KEY, false);
-
-            // By default, AE and AF both get triggered, but the user can optionally override this.
-            // Also, AF won't get triggered if the lens is fixed-focus.
-            boolean doAE = true;
-            boolean doAF = true;
-            if (params.has(TRIGGER_KEY)) {
-                JSONObject triggers = params.getJSONObject(TRIGGER_KEY);
-                if (triggers.has(TRIGGER_AE_KEY)) {
-                    doAE = triggers.getBoolean(TRIGGER_AE_KEY);
-                }
-                if (triggers.has(TRIGGER_AF_KEY)) {
-                    doAF = triggers.getBoolean(TRIGGER_AF_KEY);
-                }
-            }
-            if (doAF && mCameraCharacteristics.get(
-                            CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE) == 0) {
-                // Send a dummy result back for the code that is waiting for this message to see
-                // that AF has converged.
-                Logt.i(TAG, "Ignoring request for AF on fixed-focus camera");
-                mSocketRunnableObj.sendResponse("afResult", "0.0");
-                doAF = false;
-            }
-
-            mInterlock3A.open();
-            mIssuedRequest3A = false;
-            mConvergedAE = false;
-            mConvergedAWB = false;
-            mConvergedAF = false;
-            mLockedAE = false;
-            mLockedAWB = false;
-            long tstart = System.currentTimeMillis();
-            boolean triggeredAE = false;
-            boolean triggeredAF = false;
-
-            Logt.i(TAG, String.format("Initiating 3A: AE:%d, AF:%d, AWB:1, AELOCK:%d, AWBLOCK:%d",
-                    doAE?1:0, doAF?1:0, mNeedsLockedAE?1:0, mNeedsLockedAWB?1:0));
-
-            // Keep issuing capture requests until 3A has converged.
-            while (true) {
-
-                // Block until can take the next 3A frame. Only want one outstanding frame
-                // at a time, to simplify the logic here.
-                if (!mInterlock3A.block(TIMEOUT_3A * 1000) ||
-                        System.currentTimeMillis() - tstart > TIMEOUT_3A * 1000) {
-                    throw new ItsException("3A failed to converge (timeout)");
-                }
-                mInterlock3A.close();
-
-                // If not converged yet, issue another capture request.
-                if (       (doAE && (!triggeredAE || !mConvergedAE))
-                        || !mConvergedAWB
-                        || (doAF && (!triggeredAF || !mConvergedAF))
-                        || (doAE && mNeedsLockedAE && !mLockedAE)
-                        || (mNeedsLockedAWB && !mLockedAWB)) {
-
-                    // Baseline capture request for 3A.
-                    CaptureRequest.Builder req = mCamera.createCaptureRequest(
-                            CameraDevice.TEMPLATE_PREVIEW);
-                    req.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
-                    req.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
-                    req.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
-                            CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
-                    req.set(CaptureRequest.CONTROL_AE_MODE,
-                            CaptureRequest.CONTROL_AE_MODE_ON);
-                    req.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
-                    req.set(CaptureRequest.CONTROL_AE_LOCK, false);
-                    req.set(CaptureRequest.CONTROL_AE_REGIONS, regionAE);
-                    req.set(CaptureRequest.CONTROL_AF_MODE,
-                            CaptureRequest.CONTROL_AF_MODE_AUTO);
-                    req.set(CaptureRequest.CONTROL_AF_REGIONS, regionAF);
-                    req.set(CaptureRequest.CONTROL_AWB_MODE,
-                            CaptureRequest.CONTROL_AWB_MODE_AUTO);
-                    req.set(CaptureRequest.CONTROL_AWB_LOCK, false);
-                    req.set(CaptureRequest.CONTROL_AWB_REGIONS, regionAWB);
-
-                    if (mConvergedAE && mNeedsLockedAE) {
-                        req.set(CaptureRequest.CONTROL_AE_LOCK, true);
-                    }
-                    if (mConvergedAWB && mNeedsLockedAWB) {
-                        req.set(CaptureRequest.CONTROL_AWB_LOCK, true);
-                    }
-
-                    // Trigger AE first.
-                    if (doAE && !triggeredAE) {
-                        Logt.i(TAG, "Triggering AE");
-                        req.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
-                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
-                        triggeredAE = true;
-                    }
-
-                    // After AE has converged, trigger AF.
-                    if (doAF && !triggeredAF && (!doAE || (triggeredAE && mConvergedAE))) {
-                        Logt.i(TAG, "Triggering AF");
-                        req.set(CaptureRequest.CONTROL_AF_TRIGGER,
-                                CaptureRequest.CONTROL_AF_TRIGGER_START);
-                        triggeredAF = true;
-                    }
-
-                    req.addTarget(mCaptureReaders[0].getSurface());
-
-                    mIssuedRequest3A = true;
-                    mSession.capture(req.build(), mCaptureResultListener, mResultHandler);
-                } else {
-                    mSocketRunnableObj.sendResponse("3aConverged", "");
-                    Logt.i(TAG, "3A converged");
-                    break;
-                }
-            }
-        } catch (android.hardware.camera2.CameraAccessException e) {
-            throw new ItsException("Access error: ", e);
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error: ", e);
-        } finally {
-            mSocketRunnableObj.sendResponse("3aDone", "");
-        }
-    }
-
-    private void doVibrate(JSONObject params) throws ItsException {
-        try {
-            if (mVibrator == null) {
-                throw new ItsException("Unable to start vibrator");
-            }
-            JSONArray patternArray = params.getJSONArray(VIB_PATTERN_KEY);
-            int len = patternArray.length();
-            long pattern[] = new long[len];
-            for (int i = 0; i < len; i++) {
-                pattern[i] = patternArray.getLong(i);
-            }
-            Logt.i(TAG, String.format("Starting vibrator, pattern length %d",len));
-            mVibrator.vibrate(pattern, -1);
-            mSocketRunnableObj.sendResponse("vibrationStarted", "");
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error: ", e);
-        }
-    }
-
-    private void doCapture(JSONObject params) throws ItsException {
-        try {
-            // Parse the JSON to get the list of capture requests.
-            List<CaptureRequest.Builder> requests = ItsSerializer.deserializeRequestList(
-                    mCamera, params);
-
-            // Set the output surface(s) and listeners.
-            int widths[] = new int[MAX_NUM_OUTPUT_SURFACES];
-            int heights[] = new int[MAX_NUM_OUTPUT_SURFACES];
-            int formats[] = new int[MAX_NUM_OUTPUT_SURFACES];
-            int numSurfaces = 0;
-            try {
-                mCountRawOrDng.set(0);
-                mCountJpg.set(0);
-                mCountYuv.set(0);
-                mCountRaw10.set(0);
-                mCountCapRes.set(0);
-                mCaptureRawIsDng = false;
-                mCaptureResults = new CaptureResult[requests.size()];
-
-                JSONArray jsonOutputSpecs = ItsUtils.getOutputSpecs(params);
-                if (jsonOutputSpecs != null) {
-                    numSurfaces = jsonOutputSpecs.length();
-                    if (numSurfaces > MAX_NUM_OUTPUT_SURFACES) {
-                        throw new ItsException("Too many output surfaces");
-                    }
-                    for (int i = 0; i < numSurfaces; i++) {
-                        // Get the specified surface.
-                        JSONObject surfaceObj = jsonOutputSpecs.getJSONObject(i);
-                        String sformat = surfaceObj.optString("format");
-                        Size sizes[];
-                        if ("yuv".equals(sformat) || "".equals(sformat)) {
-                            // Default to YUV if no format is specified.
-                            formats[i] = ImageFormat.YUV_420_888;
-                            sizes = ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
-                        } else if ("jpg".equals(sformat) || "jpeg".equals(sformat)) {
-                            formats[i] = ImageFormat.JPEG;
-                            sizes = ItsUtils.getJpegOutputSizes(mCameraCharacteristics);
-                        } else if ("raw".equals(sformat)) {
-                            formats[i] = ImageFormat.RAW_SENSOR;
-                            sizes = ItsUtils.getRawOutputSizes(mCameraCharacteristics);
-                        } else if ("raw10".equals(sformat)) {
-                            formats[i] = ImageFormat.RAW10;
-                            sizes = ItsUtils.getRawOutputSizes(mCameraCharacteristics);
-                        } else if ("dng".equals(sformat)) {
-                            formats[i] = ImageFormat.RAW_SENSOR;
-                            sizes = ItsUtils.getRawOutputSizes(mCameraCharacteristics);
-                            mCaptureRawIsDng = true;
-                        } else {
-                            throw new ItsException("Unsupported format: " + sformat);
-                        }
-                        // If the size is omitted, then default to the largest allowed size for the
-                        // format.
-                        widths[i] = surfaceObj.optInt("width");
-                        heights[i] = surfaceObj.optInt("height");
-                        if (widths[i] <= 0) {
-                            if (sizes == null || sizes.length == 0) {
-                                throw new ItsException(String.format(
-                                        "Zero stream configs available for requested format: %s",
-                                        sformat));
-                            }
-                            widths[i] = sizes[0].getWidth();
-                        }
-                        if (heights[i] <= 0) {
-                            heights[i] = sizes[0].getHeight();
-                        }
-                    }
-                } else {
-                    // No surface(s) specified at all.
-                    // Default: a single output surface which is full-res YUV.
-                    Size sizes[] =
-                            ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
-                    numSurfaces = 1;
-                    widths[0] = sizes[0].getWidth();
-                    heights[0] = sizes[0].getHeight();
-                    formats[0] = ImageFormat.YUV_420_888;
-                }
-
-                prepareCaptureReader(widths, heights, formats, numSurfaces);
-                List<Surface> outputSurfaces = new ArrayList<Surface>(numSurfaces);
-                for (int i = 0; i < numSurfaces; i++) {
-                    outputSurfaces.add(mCaptureReaders[i].getSurface());
-                }
-                BlockingSessionCallback sessionListener = new BlockingSessionCallback();
-                mCamera.createCaptureSession(outputSurfaces, sessionListener, mCameraHandler);
-                mSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS);
-
-                for (int i = 0; i < numSurfaces; i++) {
-                    ImageReader.OnImageAvailableListener readerListener =
-                            createAvailableListener(mCaptureCallback);
-                    mCaptureReaders[i].setOnImageAvailableListener(readerListener,mSaveHandlers[i]);
-                }
-
-                // Plan for how many callbacks need to be received throughout the duration of this
-                // sequence of capture requests. There is one callback per image surface, and one
-                // callback for the CaptureResult, for each capture.
-                int numCaptures = requests.size();
-                mCountCallbacksRemaining.set(numCaptures * (numSurfaces + 1));
-
-            } catch (CameraAccessException e) {
-                throw new ItsException("Error configuring outputs", e);
-            } catch (org.json.JSONException e) {
-                throw new ItsException("JSON error", e);
-            }
-
-            // Initiate the captures.
-            for (int i = 0; i < requests.size(); i++) {
-                // For DNG captures, need the LSC map to be available.
-                if (mCaptureRawIsDng) {
-                    requests.get(i).set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE, 1);
-                }
-
-                CaptureRequest.Builder req = requests.get(i);
-                for (int j = 0; j < numSurfaces; j++) {
-                    req.addTarget(mCaptureReaders[j].getSurface());
-                }
-                mSession.capture(req.build(), mCaptureResultListener, mResultHandler);
-            }
-
-            // Make sure all callbacks have been hit (wait until captures are done).
-            // If no timeouts are received after a timeout, then fail.
-            int currentCount = mCountCallbacksRemaining.get();
-            while (currentCount > 0) {
-                try {
-                    Thread.sleep(TIMEOUT_CALLBACK*1000);
-                } catch (InterruptedException e) {
-                    throw new ItsException("Timeout failure", e);
-                }
-                int newCount = mCountCallbacksRemaining.get();
-                if (newCount == currentCount) {
-                    throw new ItsException(
-                            "No callback received within timeout");
-                }
-                currentCount = newCount;
-            }
-        } catch (android.hardware.camera2.CameraAccessException e) {
-            throw new ItsException("Access error: ", e);
-        }
-    }
-
-    @Override
-    public final void onSensorChanged(SensorEvent event) {
-        synchronized(mEventLock) {
-            if (mEventsEnabled) {
-                MySensorEvent ev2 = new MySensorEvent();
-                ev2.sensor = event.sensor;
-                ev2.accuracy = event.accuracy;
-                ev2.timestamp = event.timestamp;
-                ev2.values = new float[event.values.length];
-                System.arraycopy(event.values, 0, ev2.values, 0, event.values.length);
-                mEvents.add(ev2);
-            }
-        }
-    }
-
-    @Override
-    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
-    }
-
-    private final CaptureCallback mCaptureCallback = new CaptureCallback() {
-        @Override
-        public void onCaptureAvailable(Image capture) {
-            try {
-                int format = capture.getFormat();
-                if (format == ImageFormat.JPEG) {
-                    Logt.i(TAG, "Received JPEG capture");
-                    byte[] img = ItsUtils.getDataFromImage(capture);
-                    ByteBuffer buf = ByteBuffer.wrap(img);
-                    int count = mCountJpg.getAndIncrement();
-                    mSocketRunnableObj.sendResponseCaptureBuffer("jpegImage", buf);
-                } else if (format == ImageFormat.YUV_420_888) {
-                    Logt.i(TAG, "Received YUV capture");
-                    byte[] img = ItsUtils.getDataFromImage(capture);
-                    ByteBuffer buf = ByteBuffer.wrap(img);
-                    int count = mCountYuv.getAndIncrement();
-                    mSocketRunnableObj.sendResponseCaptureBuffer("yuvImage", buf);
-                } else if (format == ImageFormat.RAW10) {
-                    Logt.i(TAG, "Received RAW10 capture");
-                    byte[] img = ItsUtils.getDataFromImage(capture);
-                    ByteBuffer buf = ByteBuffer.wrap(img);
-                    int count = mCountRaw10.getAndIncrement();
-                    mSocketRunnableObj.sendResponseCaptureBuffer("raw10Image", buf);
-                } else if (format == ImageFormat.RAW_SENSOR) {
-                    Logt.i(TAG, "Received RAW16 capture");
-                    int count = mCountRawOrDng.getAndIncrement();
-                    if (! mCaptureRawIsDng) {
-                        byte[] img = ItsUtils.getDataFromImage(capture);
-                        ByteBuffer buf = ByteBuffer.wrap(img);
-                        mSocketRunnableObj.sendResponseCaptureBuffer("rawImage", buf);
-                    } else {
-                        // Wait until the corresponding capture result is ready, up to a timeout.
-                        long t0 = android.os.SystemClock.elapsedRealtime();
-                        while (! mThreadExitFlag
-                                && android.os.SystemClock.elapsedRealtime()-t0 < TIMEOUT_CAP_RES) {
-                            if (mCaptureResults[count] != null) {
-                                Logt.i(TAG, "Writing capture as DNG");
-                                DngCreator dngCreator = new DngCreator(
-                                        mCameraCharacteristics, mCaptureResults[count]);
-                                ByteArrayOutputStream dngStream = new ByteArrayOutputStream();
-                                dngCreator.writeImage(dngStream, capture);
-                                byte[] dngArray = dngStream.toByteArray();
-                                ByteBuffer dngBuf = ByteBuffer.wrap(dngArray);
-                                mSocketRunnableObj.sendResponseCaptureBuffer("dngImage", dngBuf);
-                                break;
-                            } else {
-                                Thread.sleep(1);
-                            }
-                        }
-                    }
-                } else {
-                    throw new ItsException("Unsupported image format: " + format);
-                }
-                mCountCallbacksRemaining.decrementAndGet();
-            } catch (IOException e) {
-                Logt.e(TAG, "Script error: ", e);
-            } catch (InterruptedException e) {
-                Logt.e(TAG, "Script error: ", e);
-            } catch (ItsException e) {
-                Logt.e(TAG, "Script error: ", e);
-            }
-        }
-    };
-
-    private static float r2f(Rational r) {
-        return (float)r.getNumerator() / (float)r.getDenominator();
-    }
-
-    private final CaptureResultListener mCaptureResultListener = new CaptureResultListener() {
-        @Override
-        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
-                long timestamp, long frameNumber) {
-        }
-
-        @Override
-        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
-                TotalCaptureResult result) {
-            try {
-                // Currently result has all 0 values.
-                if (request == null || result == null) {
-                    throw new ItsException("Request/result is invalid");
-                }
-
-                StringBuilder logMsg = new StringBuilder();
-                logMsg.append(String.format(
-                        "Capt result: AE=%d, AF=%d, AWB=%d, sens=%d, exp=%.1fms, dur=%.1fms, ",
-                        result.get(CaptureResult.CONTROL_AE_STATE),
-                        result.get(CaptureResult.CONTROL_AF_STATE),
-                        result.get(CaptureResult.CONTROL_AWB_STATE),
-                        result.get(CaptureResult.SENSOR_SENSITIVITY),
-                        result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue() / 1000000.0f,
-                        result.get(CaptureResult.SENSOR_FRAME_DURATION).intValue() / 1000000.0f));
-                if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null) {
-                    logMsg.append(String.format(
-                            "gains=[%.1f, %.1f, %.1f, %.1f], ",
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getRed(),
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenEven(),
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenOdd(),
-                            result.get(CaptureResult.COLOR_CORRECTION_GAINS).getBlue()));
-                } else {
-                    logMsg.append("gains=[], ");
-                }
-                if (result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
-                    logMsg.append(String.format(
-                            "xform=[%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f], ",
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,0)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,0)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,0)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,1)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,1)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,1)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,2)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,2)),
-                            r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,2))));
-                } else {
-                    logMsg.append("xform=[], ");
-                }
-                logMsg.append(String.format(
-                        "foc=%.1f",
-                        result.get(CaptureResult.LENS_FOCUS_DISTANCE)));
-                Logt.i(TAG, logMsg.toString());
-
-                if (result.get(CaptureResult.CONTROL_AE_STATE) != null) {
-                    mConvergedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                              CaptureResult.CONTROL_AE_STATE_CONVERGED ||
-                                   result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                              CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED ||
-                                   result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                              CaptureResult.CONTROL_AE_STATE_LOCKED;
-                    mLockedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
-                                           CaptureResult.CONTROL_AE_STATE_LOCKED;
-                }
-                if (result.get(CaptureResult.CONTROL_AF_STATE) != null) {
-                    mConvergedAF = result.get(CaptureResult.CONTROL_AF_STATE) ==
-                                              CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED;
-                }
-                if (result.get(CaptureResult.CONTROL_AWB_STATE) != null) {
-                    mConvergedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
-                                               CaptureResult.CONTROL_AWB_STATE_CONVERGED ||
-                                    result.get(CaptureResult.CONTROL_AWB_STATE) ==
-                                               CaptureResult.CONTROL_AWB_STATE_LOCKED;
-                    mLockedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
-                                            CaptureResult.CONTROL_AWB_STATE_LOCKED;
-                }
-
-                if (mConvergedAE && (!mNeedsLockedAE || mLockedAE)) {
-                    if (result.get(CaptureResult.SENSOR_SENSITIVITY) != null
-                            && result.get(CaptureResult.SENSOR_EXPOSURE_TIME) != null) {
-                        mSocketRunnableObj.sendResponse("aeResult", String.format("%d %d",
-                                result.get(CaptureResult.SENSOR_SENSITIVITY).intValue(),
-                                result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue()
-                                ));
-                    } else {
-                        Logt.i(TAG, String.format(
-                                "AE converged but NULL exposure values, sensitivity:%b, expTime:%b",
-                                result.get(CaptureResult.SENSOR_SENSITIVITY) == null,
-                                result.get(CaptureResult.SENSOR_EXPOSURE_TIME) == null));
-                    }
-                }
-
-                if (mConvergedAF) {
-                    if (result.get(CaptureResult.LENS_FOCUS_DISTANCE) != null) {
-                        mSocketRunnableObj.sendResponse("afResult", String.format("%f",
-                                result.get(CaptureResult.LENS_FOCUS_DISTANCE)
-                                ));
-                    } else {
-                        Logt.i(TAG, "AF converged but NULL focus distance values");
-                    }
-                }
-
-                if (mConvergedAWB && (!mNeedsLockedAWB || mLockedAWB)) {
-                    if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null
-                            && result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
-                        mSocketRunnableObj.sendResponse("awbResult", String.format(
-                                "%f %f %f %f %f %f %f %f %f %f %f %f %f",
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getRed(),
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenEven(),
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenOdd(),
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS).getBlue(),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,0)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,0)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,0)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,1)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,1)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,1)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(0,2)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(1,2)),
-                                r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).getElement(2,2))
-                                ));
-                    } else {
-                        Logt.i(TAG, String.format(
-                                "AWB converged but NULL color correction values, gains:%b, ccm:%b",
-                                result.get(CaptureResult.COLOR_CORRECTION_GAINS) == null,
-                                result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) == null));
-                    }
-                }
-
-                if (mIssuedRequest3A) {
-                    mIssuedRequest3A = false;
-                    mInterlock3A.open();
-                } else {
-                    int count = mCountCapRes.getAndIncrement();
-                    mCaptureResults[count] = result;
-                    mSocketRunnableObj.sendResponseCaptureResult(mCameraCharacteristics,
-                            request, result, mCaptureReaders);
-                    mCountCallbacksRemaining.decrementAndGet();
-                }
-            } catch (ItsException e) {
-                Logt.e(TAG, "Script error: ", e);
-            } catch (Exception e) {
-                Logt.e(TAG, "Script error: ", e);
-            }
-        }
-
-        @Override
-        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
-                CaptureFailure failure) {
-            Logt.e(TAG, "Script error: capture failed");
-        }
-    };
-}
diff --git a/apps/CameraITS/service/src/com/android/camera2/its/ItsUtils.java b/apps/CameraITS/service/src/com/android/camera2/its/ItsUtils.java
deleted file mode 100644
index 8d330cf..0000000
--- a/apps/CameraITS/service/src/com/android/camera2/its/ItsUtils.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package com.android.camera2.its;
-
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.media.Image;
-import android.media.Image.Plane;
-import android.net.Uri;
-import android.os.Environment;
-import android.util.Log;
-import android.util.Size;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-
-public class ItsUtils {
-    public static final String TAG = ItsUtils.class.getSimpleName();
-
-    public static ByteBuffer jsonToByteBuffer(JSONObject jsonObj) {
-        return ByteBuffer.wrap(jsonObj.toString().getBytes(Charset.defaultCharset()));
-    }
-
-    public static MeteringRectangle[] getJsonWeightedRectsFromArray(
-            JSONArray a, boolean normalized, int width, int height)
-            throws ItsException {
-        try {
-            // Returns [x0,y0,x1,y1,wgt,  x0,y0,x1,y1,wgt,  x0,y0,x1,y1,wgt,  ...]
-            assert(a.length() % 5 == 0);
-            MeteringRectangle[] ma = new MeteringRectangle[a.length() / 5];
-            for (int i = 0; i < a.length(); i += 5) {
-                int x,y,w,h;
-                if (normalized) {
-                    x = (int)Math.floor(a.getDouble(i+0) * width + 0.5f);
-                    y = (int)Math.floor(a.getDouble(i+1) * height + 0.5f);
-                    w = (int)Math.floor(a.getDouble(i+2) * width + 0.5f);
-                    h = (int)Math.floor(a.getDouble(i+3) * height + 0.5f);
-                } else {
-                    x = a.getInt(i+0);
-                    y = a.getInt(i+1);
-                    w = a.getInt(i+2);
-                    h = a.getInt(i+3);
-                }
-                x = Math.max(x, 0);
-                y = Math.max(y, 0);
-                w = Math.min(w, width-x);
-                h = Math.min(h, height-y);
-                int wgt = a.getInt(i+4);
-                ma[i/5] = new MeteringRectangle(x,y,w,h,wgt);
-            }
-            return ma;
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error: ", e);
-        }
-    }
-
-    public static JSONArray getOutputSpecs(JSONObject jsonObjTop)
-            throws ItsException {
-        try {
-            if (jsonObjTop.has("outputSurfaces")) {
-                return jsonObjTop.getJSONArray("outputSurfaces");
-            }
-            return null;
-        } catch (org.json.JSONException e) {
-            throw new ItsException("JSON error: ", e);
-        }
-    }
-
-    public static Size[] getRawOutputSizes(CameraCharacteristics ccs)
-            throws ItsException {
-        return getOutputSizes(ccs, ImageFormat.RAW_SENSOR);
-    }
-
-    public static Size[] getJpegOutputSizes(CameraCharacteristics ccs)
-            throws ItsException {
-        return getOutputSizes(ccs, ImageFormat.JPEG);
-    }
-
-    public static Size[] getYuvOutputSizes(CameraCharacteristics ccs)
-            throws ItsException {
-        return getOutputSizes(ccs, ImageFormat.YUV_420_888);
-    }
-
-    private static Size[] getOutputSizes(CameraCharacteristics ccs, int format)
-            throws ItsException {
-        StreamConfigurationMap configMap = ccs.get(
-                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-        if (configMap == null) {
-            throw new ItsException("Failed to get stream config");
-        }
-        return configMap.getOutputSizes(format);
-    }
-
-    public static byte[] getDataFromImage(Image image)
-            throws ItsException {
-        int format = image.getFormat();
-        int width = image.getWidth();
-        int height = image.getHeight();
-        byte[] data = null;
-
-        // Read image data
-        Plane[] planes = image.getPlanes();
-
-        // Check image validity
-        if (!checkAndroidImageFormat(image)) {
-            throw new ItsException(
-                    "Invalid image format passed to getDataFromImage: " + image.getFormat());
-        }
-
-        if (format == ImageFormat.JPEG) {
-            // JPEG doesn't have pixelstride and rowstride, treat it as 1D buffer.
-            ByteBuffer buffer = planes[0].getBuffer();
-            data = new byte[buffer.capacity()];
-            buffer.get(data);
-            return data;
-        } else if (format == ImageFormat.YUV_420_888 || format == ImageFormat.RAW_SENSOR
-                || format == ImageFormat.RAW10) {
-            int offset = 0;
-            data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
-            byte[] rowData = new byte[planes[0].getRowStride()];
-            for (int i = 0; i < planes.length; i++) {
-                ByteBuffer buffer = planes[i].getBuffer();
-                int rowStride = planes[i].getRowStride();
-                int pixelStride = planes[i].getPixelStride();
-                int bytesPerPixel = ImageFormat.getBitsPerPixel(format) / 8;
-                Logt.i(TAG, String.format(
-                        "Reading image: fmt %d, plane %d, w %d, h %d, rowStride %d, pixStride %d",
-                        format, i, width, height, rowStride, pixelStride));
-                // For multi-planar yuv images, assuming yuv420 with 2x2 chroma subsampling.
-                int w = (i == 0) ? width : width / 2;
-                int h = (i == 0) ? height : height / 2;
-                for (int row = 0; row < h; row++) {
-                    if (pixelStride == bytesPerPixel) {
-                        // Special case: optimized read of the entire row
-                        int length = w * bytesPerPixel;
-                        buffer.get(data, offset, length);
-                        // Advance buffer the remainder of the row stride
-                        buffer.position(buffer.position() + rowStride - length);
-                        offset += length;
-                    } else {
-                        // Generic case: should work for any pixelStride but slower.
-                        // Use intermediate buffer to avoid read byte-by-byte from
-                        // DirectByteBuffer, which is very bad for performance.
-                        // Also need avoid access out of bound by only reading the available
-                        // bytes in the bytebuffer.
-                        int readSize = rowStride;
-                        if (buffer.remaining() < readSize) {
-                            readSize = buffer.remaining();
-                        }
-                        buffer.get(rowData, 0, readSize);
-                        if (pixelStride >= 1) {
-                            for (int col = 0; col < w; col++) {
-                                data[offset++] = rowData[col * pixelStride];
-                            }
-                        } else {
-                            // PixelStride of 0 can mean pixel isn't a multiple of 8 bits, for
-                            // example with RAW10. Just copy the buffer, dropping any padding at
-                            // the end of the row.
-                            int length = (w * ImageFormat.getBitsPerPixel(format)) / 8;
-                            System.arraycopy(rowData,0,data,offset,length);
-                            offset += length;
-                        }
-                    }
-                }
-            }
-            Logt.i(TAG, String.format("Done reading image, format %d", format));
-            return data;
-        } else {
-            throw new ItsException("Unsupported image format: " + format);
-        }
-    }
-
-    private static boolean checkAndroidImageFormat(Image image) {
-        int format = image.getFormat();
-        Plane[] planes = image.getPlanes();
-        switch (format) {
-            case ImageFormat.YUV_420_888:
-            case ImageFormat.NV21:
-            case ImageFormat.YV12:
-                return 3 == planes.length;
-            case ImageFormat.RAW_SENSOR:
-            case ImageFormat.RAW10:
-            case ImageFormat.JPEG:
-                return 1 == planes.length;
-            default:
-                return false;
-        }
-    }
-}
-
diff --git a/apps/CameraITS/service/src/com/android/camera2/its/Logt.java b/apps/CameraITS/service/src/com/android/camera2/its/Logt.java
deleted file mode 100644
index 2fc5399..0000000
--- a/apps/CameraITS/service/src/com/android/camera2/its/Logt.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-package com.android.camera2.its;
-
-import android.util.Log;
-
-public class Logt {
-    public static void i(String tag, String msg) {
-        long t = android.os.SystemClock.elapsedRealtime();
-        Log.i(tag, String.format("[%d] %s", t, msg));
-    }
-    public static void e(String tag, String msg) {
-        long t = android.os.SystemClock.elapsedRealtime();
-        Log.e(tag, String.format("[%d] %s", t, msg));
-    }
-    public static void w(String tag, String msg) {
-        long t = android.os.SystemClock.elapsedRealtime();
-        Log.w(tag, String.format("[%d] %s", t, msg));
-    }
-    public static void e(String tag, String msg, Throwable tr) {
-        long t = android.os.SystemClock.elapsedRealtime();
-        Log.e(tag, String.format("[%d] %s", t, msg), tr);
-    }
-}
-
diff --git a/apps/CameraITS/tests/inprog/scene2/README b/apps/CameraITS/tests/inprog/scene2/README
deleted file mode 100644
index 3a0953f..0000000
--- a/apps/CameraITS/tests/inprog/scene2/README
+++ /dev/null
@@ -1,8 +0,0 @@
-Scene 2 requires a camera lab with controlled illuminants, for example
-light sources capable of producing D65, D50, A, TL84, etc. illumination.
-Specific charts may also be required, for example grey cards, color
-checker charts, and resolution charts. The individual tests will specify
-the setup that they require.
-
-If a test requires that the camera be in any particular orientaion, it will
-specify this too. Otherwise, the camara can be in either portrait or lanscape.
diff --git a/apps/CameraITS/tests/inprog/scene2/test_dng_tags.py b/apps/CameraITS/tests/inprog/scene2/test_dng_tags.py
deleted file mode 100644
index 0c96ca7..0000000
--- a/apps/CameraITS/tests/inprog/scene2/test_dng_tags.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.device
-import its.dng
-import its.objects
-import numpy
-import os.path
-
-def main():
-    """Test that the DNG tags are internally self-consistent.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-
-        # Assumes that illuminant 1 is D65, and illuminant 2 is standard A.
-        # TODO: Generalize DNG tags check for any provided illuminants.
-        illum_code = [21, 17] # D65, A
-        illum_str = ['D65', 'A']
-        ref_str = ['android.sensor.referenceIlluminant%d'%(i) for i in [1,2]]
-        cm_str = ['android.sensor.colorTransform%d'%(i) for i in [1,2]]
-        fm_str = ['android.sensor.forwardMatrix%d'%(i) for i in [1,2]]
-        cal_str = ['android.sensor.calibrationTransform%d'%(i) for i in [1,2]]
-        dng_illum = [its.dng.D65, its.dng.A]
-
-        for i in [0,1]:
-            assert(props[ref_str[i]] == illum_code[i])
-            raw_input("\n[Point camera at grey card under %s and press ENTER]"%(
-                    illum_str[i]))
-
-            cam.do_3a(do_af=False)
-            cap = cam.do_capture(its.objects.auto_capture_request())
-            gains = cap["metadata"]["android.colorCorrection.gains"]
-            ccm = its.objects.rational_to_float(
-                    cap["metadata"]["android.colorCorrection.transform"])
-            cal = its.objects.rational_to_float(props[cal_str[i]])
-            print "HAL reported gains:\n", numpy.array(gains)
-            print "HAL reported ccm:\n", numpy.array(ccm).reshape(3,3)
-            print "HAL reported cal:\n", numpy.array(cal).reshape(3,3)
-
-            # Dump the image.
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_%s.jpg" % (NAME, illum_str[i]))
-
-            # Compute the matrices that are expected under this illuminant from
-            # the HAL-reported WB gains, CCM, and calibration matrix.
-            cm, fm = its.dng.compute_cm_fm(dng_illum[i], gains, ccm, cal)
-            asn = its.dng.compute_asn(dng_illum[i], cal, cm)
-            print "Expected ColorMatrix:\n", cm
-            print "Expected ForwardMatrix:\n", fm
-            print "Expected AsShotNeutral:\n", asn
-
-            # Get the matrices that are reported by the HAL for this
-            # illuminant.
-            cm_ref = numpy.array(its.objects.rational_to_float(
-                    props[cm_str[i]])).reshape(3,3)
-            fm_ref = numpy.array(its.objects.rational_to_float(
-                    props[fm_str[i]])).reshape(3,3)
-            asn_ref = numpy.array(its.objects.rational_to_float(
-                    cap['metadata']['android.sensor.neutralColorPoint']))
-            print "Reported ColorMatrix:\n", cm_ref
-            print "Reported ForwardMatrix:\n", fm_ref
-            print "Reported AsShotNeutral:\n", asn_ref
-
-            # The color matrix may be scaled (between the reported and
-            # expected values).
-            cm_scale = cm.mean(1).mean(0) / cm_ref.mean(1).mean(0)
-            print "ColorMatrix scale factor:", cm_scale
-
-            # Compute the deltas between reported and expected.
-            print "Ratios in ColorMatrix:\n", cm / cm_ref
-            print "Deltas in ColorMatrix (after normalizing):\n", cm/cm_scale - cm_ref
-            print "Deltas in ForwardMatrix:\n", fm - fm_ref
-            print "Deltas in AsShotNeutral:\n", asn - asn_ref
-
-            # TODO: Add pass/fail test on DNG matrices.
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_3a_remote.py b/apps/CameraITS/tests/inprog/test_3a_remote.py
deleted file mode 100644
index c76ff6d..0000000
--- a/apps/CameraITS/tests/inprog/test_3a_remote.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.device
-import its.objects
-import os.path
-import pprint
-import math
-import numpy
-import matplotlib.pyplot
-import mpl_toolkits.mplot3d
-
-def main():
-    """Run 3A remotely (from this script).
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        w_map = props["android.lens.info.shadingMapSize"]["width"]
-        h_map = props["android.lens.info.shadingMapSize"]["height"]
-
-        # TODO: Test for 3A convergence, and exit this test once converged.
-
-        triggered = False
-        while True:
-            req = its.objects.auto_capture_request()
-            req["android.statistics.lensShadingMapMode"] = 1
-            req['android.control.aePrecaptureTrigger'] = (0 if triggered else 1)
-            req['android.control.afTrigger'] = (0 if triggered else 1)
-            triggered = True
-
-            cap = cam.do_capture(req)
-
-            ae_state = cap["metadata"]["android.control.aeState"]
-            awb_state = cap["metadata"]["android.control.awbState"]
-            af_state = cap["metadata"]["android.control.afState"]
-            gains = cap["metadata"]["android.colorCorrection.gains"]
-            transform = cap["metadata"]["android.colorCorrection.transform"]
-            exp_time = cap["metadata"]['android.sensor.exposureTime']
-            lsc_map = cap["metadata"]["android.statistics.lensShadingMap"]
-            foc_dist = cap["metadata"]['android.lens.focusDistance']
-            foc_range = cap["metadata"]['android.lens.focusRange']
-
-            print "States (AE,AWB,AF):", ae_state, awb_state, af_state
-            print "Gains:", gains
-            print "Transform:", [its.objects.rational_to_float(t)
-                                 for t in transform]
-            print "AE region:", cap["metadata"]['android.control.aeRegions']
-            print "AF region:", cap["metadata"]['android.control.afRegions']
-            print "AWB region:", cap["metadata"]['android.control.awbRegions']
-            print "LSC map:", w_map, h_map, lsc_map[:8]
-            print "Focus (dist,range):", foc_dist, foc_range
-            print ""
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_black_level.py b/apps/CameraITS/tests/inprog/test_black_level.py
deleted file mode 100644
index 37dab94..0000000
--- a/apps/CameraITS/tests/inprog/test_black_level.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.device
-import its.objects
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-import numpy
-
-def main():
-    """Black level consistence test.
-
-    Test: capture dark frames and check if black level correction is done
-    correctly.
-    1. Black level should be roughly consistent for repeating shots.
-    2. Noise distribution should be roughly centered at black level.
-
-    Shoot with the camera covered (i.e.) dark/black. The test varies the
-    sensitivity parameter.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    NUM_REPEAT = 3
-    NUM_STEPS = 3
-
-    # Only check the center part where LSC has little effects.
-    R = 200
-
-    # The most frequent pixel value in each image; assume this is the black
-    # level, since the images are all dark (shot with the lens covered).
-    ymodes = []
-    umodes = []
-    vmodes = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        sens_range = props['android.sensor.info.sensitivityRange']
-        sens_step = (sens_range[1] - sens_range[0]) / float(NUM_STEPS-1)
-        sensitivities = [sens_range[0] + i*sens_step for i in range(NUM_STEPS)]
-        print "Sensitivities:", sensitivities
-
-        for si, s in enumerate(sensitivities):
-            for rep in xrange(NUM_REPEAT):
-                req = its.objects.manual_capture_request(100, 1*1000*1000)
-                req["android.blackLevel.lock"] = True
-                req["android.sensor.sensitivity"] = s
-                cap = cam.do_capture(req)
-                yimg,uimg,vimg = its.image.convert_capture_to_planes(cap)
-                w = cap["width"]
-                h = cap["height"]
-
-                # Magnify the noise in saved images to help visualize.
-                its.image.write_image(yimg * 2,
-                                      "%s_s=%05d_y.jpg" % (NAME, s), True)
-                its.image.write_image(numpy.absolute(uimg - 0.5) * 2,
-                                      "%s_s=%05d_u.jpg" % (NAME, s), True)
-
-                yimg = yimg[w/2-R:w/2+R, h/2-R:h/2+R]
-                uimg = uimg[w/4-R/2:w/4+R/2, w/4-R/2:w/4+R/2]
-                vimg = vimg[w/4-R/2:w/4+R/2, w/4-R/2:w/4+R/2]
-                yhist,_ = numpy.histogram(yimg*255, 256, (0,256))
-                ymodes.append(numpy.argmax(yhist))
-                uhist,_ = numpy.histogram(uimg*255, 256, (0,256))
-                umodes.append(numpy.argmax(uhist))
-                vhist,_ = numpy.histogram(vimg*255, 256, (0,256))
-                vmodes.append(numpy.argmax(vhist))
-
-                # Take 32 bins from Y, U, and V.
-                # Histograms of U and V are cropped at the center of 128.
-                pylab.plot(range(32), yhist.tolist()[0:32], 'rgb'[si])
-                pylab.plot(range(32), uhist.tolist()[112:144], 'rgb'[si]+'--')
-                pylab.plot(range(32), vhist.tolist()[112:144], 'rgb'[si]+'--')
-
-    pylab.xlabel("DN: Y[0:32], U[112:144], V[112:144]")
-    pylab.ylabel("Pixel count")
-    pylab.title("Histograms for different sensitivities")
-    matplotlib.pyplot.savefig("%s_plot_histograms.png" % (NAME))
-
-    print "Y black levels:", ymodes
-    print "U black levels:", umodes
-    print "V black levels:", vmodes
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_blc_lsc.py b/apps/CameraITS/tests/inprog/test_blc_lsc.py
deleted file mode 100644
index ce120a2..0000000
--- a/apps/CameraITS/tests/inprog/test_blc_lsc.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.device
-import its.objects
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that BLC and LSC look reasonable.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    r_means_center = []
-    g_means_center = []
-    b_means_center = []
-    r_means_corner = []
-    g_means_corner = []
-    b_means_corner = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        expt_range = props['android.sensor.info.exposureTimeRange']
-
-        # Get AE+AWB lock first, so the auto values in the capture result are
-        # populated properly.
-        r = [[0,0,1,1,1]]
-        ae_sen,ae_exp,awb_gains,awb_transform,_ \
-                = cam.do_3a(r,r,r,do_af=False,get_results=True)
-        print "AE:", ae_sen, ae_exp / 1000000.0
-        print "AWB:", awb_gains, awb_transform
-
-        # Set analog gain (sensitivity) to 800
-        ae_exp = ae_exp * ae_sen / 800
-        ae_sen = 800
-
-        # Capture range of exposures from 1/100x to 4x of AE estimate.
-        exposures = [ae_exp*x/100.0 for x in [1]+range(10,401,40)]
-        exposures = [e for e in exposures
-                     if e >= expt_range[0] and e <= expt_range[1]]
-
-        # Convert the transform back to rational.
-        awb_transform_rat = its.objects.float_to_rational(awb_transform)
-
-        # Linear tonemap
-        tmap = sum([[i/63.0,i/63.0] for i in range(64)], [])
-
-        reqs = []
-        for e in exposures:
-            req = its.objects.manual_capture_request(ae_sen,e)
-            req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = tmap
-            req["android.tonemap.curveGreen"] = tmap
-            req["android.tonemap.curveBlue"] = tmap
-            req["android.colorCorrection.transform"] = awb_transform_rat
-            req["android.colorCorrection.gains"] = awb_gains
-            reqs.append(req)
-
-        caps = cam.do_capture(reqs)
-        for i,cap in enumerate(caps):
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_i=%d.jpg"%(NAME, i))
-
-            tile_center = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile_center)
-            r_means_center.append(rgb_means[0])
-            g_means_center.append(rgb_means[1])
-            b_means_center.append(rgb_means[2])
-
-            tile_corner = its.image.get_image_patch(img, 0.0, 0.0, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile_corner)
-            r_means_corner.append(rgb_means[0])
-            g_means_corner.append(rgb_means[1])
-            b_means_corner.append(rgb_means[2])
-
-    fig = matplotlib.pyplot.figure()
-    pylab.plot(exposures, r_means_center, 'r')
-    pylab.plot(exposures, g_means_center, 'g')
-    pylab.plot(exposures, b_means_center, 'b')
-    pylab.ylim([0,1])
-    matplotlib.pyplot.savefig("%s_plot_means_center.png" % (NAME))
-
-    fig = matplotlib.pyplot.figure()
-    pylab.plot(exposures, r_means_corner, 'r')
-    pylab.plot(exposures, g_means_corner, 'g')
-    pylab.plot(exposures, b_means_corner, 'b')
-    pylab.ylim([0,1])
-    matplotlib.pyplot.savefig("%s_plot_means_corner.png" % (NAME))
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_burst_sameness_auto.py b/apps/CameraITS/tests/inprog/test_burst_sameness_auto.py
deleted file mode 100644
index f3d49be..0000000
--- a/apps/CameraITS/tests/inprog/test_burst_sameness_auto.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import os.path
-import numpy
-
-def main():
-    """Take long bursts of images and check that they're all identical.
-
-    Assumes a static scene. Can be used to idenfity if there are sporadic
-    frames that are processed differently or have artifacts, or if 3A isn't
-    stable, since this test converges 3A at the start but doesn't lock 3A
-    throughout capture.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    BURST_LEN = 50
-    BURSTS = 5
-    FRAMES = BURST_LEN * BURSTS
-
-    SPREAD_THRESH = 0.03
-
-    with its.device.ItsSession() as cam:
-
-        # Capture at the smallest resolution.
-        props = cam.get_camera_properties()
-        if not its.caps.manual_sensor(props):
-            print "Test skipped"
-            return
-
-        _, fmt = its.objects.get_fastest_manual_capture_settings(props)
-        w,h = fmt["width"], fmt["height"]
-
-        # Converge 3A prior to capture.
-        cam.do_3a(lock_ae=True, lock_awb=True)
-
-        # After 3A has converged, lock AE+AWB for the duration of the test.
-        req = its.objects.auto_capture_request()
-        req["android.blackLevel.lock"] = True
-        req["android.control.awbLock"] = True
-        req["android.control.aeLock"] = True
-
-        # Capture bursts of YUV shots.
-        # Get the mean values of a center patch for each.
-        # Also build a 4D array, which is an array of all RGB images.
-        r_means = []
-        g_means = []
-        b_means = []
-        imgs = numpy.empty([FRAMES,h,w,3])
-        for j in range(BURSTS):
-            caps = cam.do_capture([req]*BURST_LEN, [fmt])
-            for i,cap in enumerate(caps):
-                n = j*BURST_LEN + i
-                imgs[n] = its.image.convert_capture_to_rgb_image(cap)
-                tile = its.image.get_image_patch(imgs[n], 0.45, 0.45, 0.1, 0.1)
-                means = its.image.compute_image_means(tile)
-                r_means.append(means[0])
-                g_means.append(means[1])
-                b_means.append(means[2])
-
-        # Dump all images.
-        print "Dumping images"
-        for i in range(FRAMES):
-            its.image.write_image(imgs[i], "%s_frame%03d.jpg"%(NAME,i))
-
-        # The mean image.
-        img_mean = imgs.mean(0)
-        its.image.write_image(img_mean, "%s_mean.jpg"%(NAME))
-
-        # Pass/fail based on center patch similarity.
-        for means in [r_means, g_means, b_means]:
-            spread = max(means) - min(means)
-            print spread
-            assert(spread < SPREAD_THRESH)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_burst_sameness_fullres_auto.py b/apps/CameraITS/tests/inprog/test_burst_sameness_fullres_auto.py
deleted file mode 100644
index a8d1d45..0000000
--- a/apps/CameraITS/tests/inprog/test_burst_sameness_fullres_auto.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.device
-import its.objects
-import os.path
-import numpy
-import pylab
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Take long bursts of images and check that they're all identical.
-
-    Assumes a static scene. Can be used to idenfity if there are sporadic
-    frames that are processed differently or have artifacts, or if 3A isn't
-    stable, since this test converges 3A at the start but doesn't lock 3A
-    throughout capture.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    BURST_LEN = 6
-    BURSTS = 2
-    FRAMES = BURST_LEN * BURSTS
-
-    DELTA_THRESH = 0.1
-
-    with its.device.ItsSession() as cam:
-
-        # Capture at full resolution.
-        props = cam.get_camera_properties()
-        w,h = its.objects.get_available_output_sizes("yuv", props)[0]
-
-        # Converge 3A prior to capture.
-        cam.do_3a(lock_ae=True, lock_awb=True)
-
-        # After 3A has converged, lock AE+AWB for the duration of the test.
-        req = its.objects.auto_capture_request()
-        req["android.blackLevel.lock"] = True
-        req["android.control.awbLock"] = True
-        req["android.control.aeLock"] = True
-
-        # Capture bursts of YUV shots.
-        # Build a 4D array, which is an array of all RGB images after down-
-        # scaling them by a factor of 4x4.
-        imgs = numpy.empty([FRAMES,h/4,w/4,3])
-        for j in range(BURSTS):
-            caps = cam.do_capture([req]*BURST_LEN)
-            for i,cap in enumerate(caps):
-                n = j*BURST_LEN + i
-                imgs[n] = its.image.downscale_image(
-                        its.image.convert_capture_to_rgb_image(cap), 4)
-
-        # Dump all images.
-        print "Dumping images"
-        for i in range(FRAMES):
-            its.image.write_image(imgs[i], "%s_frame%03d.jpg"%(NAME,i))
-
-        # The mean image.
-        img_mean = imgs.mean(0)
-        its.image.write_image(img_mean, "%s_mean.jpg"%(NAME))
-
-        # Compute the deltas of each image from the mean image; this test
-        # passes if none of the deltas are large.
-        print "Computing frame differences"
-        delta_maxes = []
-        for i in range(FRAMES):
-            deltas = (imgs[i] - img_mean).reshape(h*w*3/16)
-            delta_max_pos = numpy.max(deltas)
-            delta_max_neg = numpy.min(deltas)
-            delta_maxes.append(max(abs(delta_max_pos), abs(delta_max_neg)))
-        max_delta_max = max(delta_maxes)
-        print "Frame %d has largest diff %f" % (
-                delta_maxes.index(max_delta_max), max_delta_max)
-        assert(max_delta_max < DELTA_THRESH)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_crop_region.py b/apps/CameraITS/tests/inprog/test_crop_region.py
deleted file mode 100644
index 396603f..0000000
--- a/apps/CameraITS/tests/inprog/test_crop_region.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2014 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.
-
-import os
-import its.image
-import its.device
-import its.objects
-
-
-def main():
-    """Takes shots with different sensor crop regions.
-    """
-    name = os.path.basename(__file__).split(".")[0]
-
-    # Regions specified here in x,y,w,h normalized form.
-    regions = [[0.0, 0.0, 0.5, 0.5], # top left
-               [0.0, 0.5, 0.5, 0.5], # bottom left
-               [0.1, 0.9, 0.5, 1.0]] # right side (top + bottom)
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        r = props['android.sensor.info.pixelArraySize']
-        w = r['width']
-        h = r['height']
-
-        # Capture a full frame first.
-        reqs = [its.objects.auto_capture_request()]
-        print "Capturing img0 with the full sensor region"
-
-        # Capture a frame for each of the regions.
-        for i,region in enumerate(regions):
-            req = its.objects.auto_capture_request()
-            req['android.scaler.cropRegion'] = {
-                    "left": int(region[0] * w),
-                    "top": int(region[1] * h),
-                    "right": int((region[0]+region[2])*w),
-                    "bottom": int((region[1]+region[3])*h)}
-            reqs.append(req)
-            crop = req['android.scaler.cropRegion']
-            print "Capturing img%d with crop: %d,%d %dx%d"%(i+1,
-                    crop["left"],crop["top"],
-                    crop["right"]-crop["left"],crop["bottom"]-crop["top"])
-
-        cam.do_3a()
-        caps = cam.do_capture(reqs)
-
-        for i,cap in enumerate(caps):
-            img = its.image.convert_capture_to_rgb_image(cap)
-            crop = cap["metadata"]['android.scaler.cropRegion']
-            its.image.write_image(img, "%s_img%d.jpg"%(name,i))
-            print "Captured img%d with crop: %d,%d %dx%d"%(i,
-                    crop["left"],crop["top"],
-                    crop["right"]-crop["left"],crop["bottom"]-crop["top"])
-
-if __name__ == '__main__':
-    main()
diff --git a/apps/CameraITS/tests/inprog/test_ev_compensation.py b/apps/CameraITS/tests/inprog/test_ev_compensation.py
deleted file mode 100644
index f9b0cd3..0000000
--- a/apps/CameraITS/tests/inprog/test_ev_compensation.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.device
-import its.objects
-import os.path
-import pylab
-import matplotlib
-import matplotlib.pyplot
-import numpy
-
-def main():
-    """Tests that EV compensation is applied.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    MAX_LUMA_DELTA_THRESH = 0.01
-    AVG_LUMA_DELTA_THRESH = 0.001
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        cam.do_3a()
-
-        # Capture auto shots, but with a linear tonemap.
-        req = its.objects.auto_capture_request()
-        req["android.tonemap.mode"] = 0
-        req["android.tonemap.curveRed"] = (0.0, 0.0, 1.0, 1.0)
-        req["android.tonemap.curveGreen"] = (0.0, 0.0, 1.0, 1.0)
-        req["android.tonemap.curveBlue"] = (0.0, 0.0, 1.0, 1.0)
-
-        evs = range(-4,5)
-        lumas = []
-        for ev in evs:
-            req['android.control.aeExposureCompensation'] = ev
-            cap = cam.do_capture(req)
-            y = its.image.convert_capture_to_planes(cap)[0]
-            tile = its.image.get_image_patch(y, 0.45,0.45,0.1,0.1)
-            lumas.append(its.image.compute_image_means(tile)[0])
-
-        ev_step_size_in_stops = its.objects.rational_to_float(
-                props['android.control.aeCompensationStep'])
-        luma_increase_per_step = pow(2, ev_step_size_in_stops)
-        expected_lumas = [lumas[0] * pow(luma_increase_per_step, i) \
-                for i in range(len(evs))]
-
-        pylab.plot(evs, lumas, 'r')
-        pylab.plot(evs, expected_lumas, 'b')
-        matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-        luma_diffs = [expected_lumas[i] - lumas[i] for i in range(len(evs))]
-        max_diff = max(luma_diffs)
-        avg_diff = sum(luma_diffs) / len(luma_diffs)
-        print "Max delta between modeled and measured lumas:", max_diff
-        print "Avg delta between modeled and measured lumas:", avg_diff
-        assert(max_diff < MAX_LUMA_DELTA_THRESH)
-        assert(avg_diff < AVG_LUMA_DELTA_THRESH)
-
-if __name__ == '__main__':
-    main()
diff --git a/apps/CameraITS/tests/inprog/test_faces.py b/apps/CameraITS/tests/inprog/test_faces.py
deleted file mode 100644
index 228dac8..0000000
--- a/apps/CameraITS/tests/inprog/test_faces.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.device
-import its.objects
-import os.path
-
-def main():
-    """Test face detection.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        cam.do_3a()
-        req = its.objects.auto_capture_request()
-        req['android.statistics.faceDetectMode'] = 2
-        caps = cam.do_capture([req]*5)
-        for i,cap in enumerate(caps):
-            md = cap['metadata']
-            print "Frame %d face metadata:" % i
-            print "  Ids:", md['android.statistics.faceIds']
-            print "  Landmarks:", md['android.statistics.faceLandmarks']
-            print "  Rectangles:", md['android.statistics.faceRectangles']
-            print "  Scores:", md['android.statistics.faceScores']
-            print ""
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_param_black_level_lock.py b/apps/CameraITS/tests/inprog/test_param_black_level_lock.py
deleted file mode 100644
index 7d0be92..0000000
--- a/apps/CameraITS/tests/inprog/test_param_black_level_lock.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.device
-import its.objects
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-import numpy
-
-def main():
-    """Test that when the black level is locked, it doesn't change.
-
-    Shoot with the camera covered (i.e.) dark/black. The test varies the
-    sensitivity parameter and checks if the black level changes.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    NUM_STEPS = 5
-
-    req = {
-        "android.blackLevel.lock": True,
-        "android.control.mode": 0,
-        "android.control.aeMode": 0,
-        "android.control.awbMode": 0,
-        "android.control.afMode": 0,
-        "android.sensor.frameDuration": 0,
-        "android.sensor.exposureTime": 10*1000*1000
-        }
-
-    # The most frequent pixel value in each image; assume this is the black
-    # level, since the images are all dark (shot with the lens covered).
-    modes = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        sens_range = props['android.sensor.info.sensitivityRange']
-        sensitivities = range(sens_range[0],
-                              sens_range[1]+1,
-                              int((sens_range[1] - sens_range[0]) / NUM_STEPS))
-        for si, s in enumerate(sensitivities):
-            req["android.sensor.sensitivity"] = s
-            cap = cam.do_capture(req)
-            yimg,_,_ = its.image.convert_capture_to_planes(cap)
-            hist,_ = numpy.histogram(yimg*255, 256, (0,256))
-            modes.append(numpy.argmax(hist))
-
-            # Add this histogram to a plot; solid for shots without BL
-            # lock, dashes for shots with BL lock
-            pylab.plot(range(16), hist.tolist()[:16])
-
-    pylab.xlabel("Luma DN, showing [0:16] out of full [0:256] range")
-    pylab.ylabel("Pixel count")
-    pylab.title("Histograms for different sensitivities")
-    matplotlib.pyplot.savefig("%s_plot_histograms.png" % (NAME))
-
-    # Check that the black levels are all the same.
-    print "Black levels:", modes
-    assert(all([modes[i] == modes[0] for i in range(len(modes))]))
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_param_edge_mode.py b/apps/CameraITS/tests/inprog/test_param_edge_mode.py
deleted file mode 100644
index e928f21..0000000
--- a/apps/CameraITS/tests/inprog/test_param_edge_mode.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.device
-import its.objects
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that the android.edge.mode parameter is applied.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    req = {
-        "android.control.mode": 0,
-        "android.control.aeMode": 0,
-        "android.control.awbMode": 0,
-        "android.control.afMode": 0,
-        "android.sensor.frameDuration": 0,
-        "android.sensor.exposureTime": 30*1000*1000,
-        "android.sensor.sensitivity": 100
-        }
-
-    with its.device.ItsSession() as cam:
-        sens, exp, gains, xform, focus = cam.do_3a(get_results=True)
-        for e in [0,1,2]:
-            req["android.edge.mode"] = e
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_mode=%d.jpg" % (NAME, e))
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_test_patterns.py b/apps/CameraITS/tests/inprog/test_test_patterns.py
deleted file mode 100644
index f75b141..0000000
--- a/apps/CameraITS/tests/inprog/test_test_patterns.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.device
-import its.objects
-import os.path
-
-def main():
-    """Test sensor test patterns.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        caps = []
-        for i in range(1,6):
-            req = its.objects.manual_capture_request(100, 10*1000*1000)
-            req['android.sensor.testPatternData'] = [40, 100, 160, 220]
-            req['android.sensor.testPatternMode'] = i
-
-            # Capture the shot twice, and use the second one, so the pattern
-            # will have stabilized.
-            caps = cam.do_capture([req]*2)
-
-            img = its.image.convert_capture_to_rgb_image(caps[1])
-            its.image.write_image(img, "%s_pattern=%d.jpg" % (NAME, i))
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/README b/apps/CameraITS/tests/scene0/README
deleted file mode 100644
index 50be04a..0000000
--- a/apps/CameraITS/tests/scene0/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This scene has no requirements; scene 0 tests don't actually
-look at the image content, and the camera can be pointed at
-any target (or even flat on the desk).
diff --git a/apps/CameraITS/tests/scene0/test_camera_properties.py b/apps/CameraITS/tests/scene0/test_camera_properties.py
deleted file mode 100644
index 05fc364..0000000
--- a/apps/CameraITS/tests/scene0/test_camera_properties.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013 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.
-
-import its.caps
-import its.device
-import its.objects
-import pprint
-
-def main():
-    """Basic test to query and print out camera properties.
-    """
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-
-        pprint.pprint(props)
-
-        # Test that a handful of required keys are present.
-        if its.caps.manual_sensor(props):
-            assert(props.has_key('android.sensor.info.sensitivityRange'))
-
-        assert(props.has_key('android.sensor.orientation'))
-        assert(props.has_key('android.scaler.streamConfigurationMap'))
-        assert(props.has_key('android.lens.facing'))
-
-        print "JPG sizes:", its.objects.get_available_output_sizes("jpg", props)
-        print "RAW sizes:", its.objects.get_available_output_sizes("raw", props)
-        print "YUV sizes:", its.objects.get_available_output_sizes("yuv", props)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/test_capture_result_dump.py b/apps/CameraITS/tests/scene0/test_capture_result_dump.py
deleted file mode 100644
index c8b1f8f..0000000
--- a/apps/CameraITS/tests/scene0/test_capture_result_dump.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2014 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.
-
-import its.caps
-import its.image
-import its.device
-import its.objects
-import its.target
-import pprint
-
-def main():
-    """Test that a capture result is returned from a manual capture; dump it.
-    """
-
-    with its.device.ItsSession() as cam:
-        # Arbitrary capture request exposure values; image content is not
-        # important for this test, only the metadata.
-        props = cam.get_camera_properties()
-        if not its.caps.manual_sensor(props):
-            print "Test skipped"
-            return
-
-        req,fmt = its.objects.get_fastest_manual_capture_settings(props)
-        cap = cam.do_capture(req, fmt)
-        pprint.pprint(cap["metadata"])
-
-        # No pass/fail check; test passes if it completes.
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/test_gyro_bias.py b/apps/CameraITS/tests/scene0/test_gyro_bias.py
deleted file mode 100644
index 64a5ff0..0000000
--- a/apps/CameraITS/tests/scene0/test_gyro_bias.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import time
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-import numpy
-
-def main():
-    """Test if the gyro has stable output when device is stationary.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # Number of samples averaged together, in the plot.
-    N = 20
-
-    # Pass/fail thresholds for gyro drift
-    MEAN_THRESH = 0.01
-    VAR_THRESH = 0.001
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        # Only run test if the appropriate caps are claimed.
-        if not its.caps.sensor_fusion(props):
-            print "Test skipped"
-            return
-
-        print "Collecting gyro events"
-        cam.start_sensor_events()
-        time.sleep(5)
-        gyro_events = cam.get_sensor_events()["gyro"]
-
-    nevents = (len(gyro_events) / N) * N
-    gyro_events = gyro_events[:nevents]
-    times = numpy.array([(e["time"] - gyro_events[0]["time"])/1000000000.0
-                         for e in gyro_events])
-    xs = numpy.array([e["x"] for e in gyro_events])
-    ys = numpy.array([e["y"] for e in gyro_events])
-    zs = numpy.array([e["z"] for e in gyro_events])
-
-    # Group samples into size-N groups and average each together, to get rid
-    # of individual rnadom spikes in the data.
-    times = times[N/2::N]
-    xs = xs.reshape(nevents/N, N).mean(1)
-    ys = ys.reshape(nevents/N, N).mean(1)
-    zs = zs.reshape(nevents/N, N).mean(1)
-
-    pylab.plot(times, xs, 'r', label="x")
-    pylab.plot(times, ys, 'g', label="y")
-    pylab.plot(times, zs, 'b', label="z")
-    pylab.xlabel("Time (seconds)")
-    pylab.ylabel("Gyro readings (mean of %d samples)"%(N))
-    pylab.legend()
-    matplotlib.pyplot.savefig("%s_plot.png" % (NAME))
-
-    for samples in [xs,ys,zs]:
-        assert(samples.mean() < MEAN_THRESH)
-        assert(numpy.var(samples) < VAR_THRESH)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/test_jitter.py b/apps/CameraITS/tests/scene0/test_jitter.py
deleted file mode 100644
index 29b3047..0000000
--- a/apps/CameraITS/tests/scene0/test_jitter.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import os.path
-import pylab
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Measure jitter in camera timestamps.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # Pass/fail thresholds
-    MIN_AVG_FRAME_DELTA = 30 # at least 30ms delta between frames
-    MAX_VAR_FRAME_DELTA = 0.01 # variance of frame deltas
-    MAX_FRAME_DELTA_JITTER = 0.3 # max ms gap from the average frame delta
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.manual_sensor(props):
-            print "Test skipped"
-            return
-
-        req, fmt = its.objects.get_fastest_manual_capture_settings(props)
-        caps = cam.do_capture([req]*50, [fmt])
-
-        # Print out the millisecond delta between the start of each exposure
-        tstamps = [c['metadata']['android.sensor.timestamp'] for c in caps]
-        deltas = [tstamps[i]-tstamps[i-1] for i in range(1,len(tstamps))]
-        deltas_ms = [d/1000000.0 for d in deltas]
-        avg = sum(deltas_ms) / len(deltas_ms)
-        var = sum([d*d for d in deltas_ms]) / len(deltas_ms) - avg * avg
-        range0 = min(deltas_ms) - avg
-        range1 = max(deltas_ms) - avg
-        print "Average:", avg
-        print "Variance:", var
-        print "Jitter range:", range0, "to", range1
-
-        # Draw a plot.
-        pylab.plot(range(len(deltas_ms)), deltas_ms)
-        matplotlib.pyplot.savefig("%s_deltas.png" % (NAME))
-
-        # Test for pass/fail.
-        assert(avg > MIN_AVG_FRAME_DELTA)
-        assert(var < MAX_VAR_FRAME_DELTA)
-        assert(abs(range0) < MAX_FRAME_DELTA_JITTER)
-        assert(abs(range1) < MAX_FRAME_DELTA_JITTER)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/test_metadata.py b/apps/CameraITS/tests/scene0/test_metadata.py
deleted file mode 100644
index b4ca4cb..0000000
--- a/apps/CameraITS/tests/scene0/test_metadata.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.device
-import its.objects
-import its.target
-import its.caps
-
-def main():
-    """Test the validity of some metadata entries.
-
-    Looks at capture results and at the camera characteristics objects.
-    """
-    global md, props, failed
-
-    with its.device.ItsSession() as cam:
-        # Arbitrary capture request exposure values; image content is not
-        # important for this test, only the metadata.
-        props = cam.get_camera_properties()
-        auto_req = its.objects.auto_capture_request()
-        cap = cam.do_capture(auto_req)
-        md = cap["metadata"]
-
-    print "Hardware level"
-    print "  Legacy:", its.caps.legacy(props)
-    print "  Limited:", its.caps.limited(props)
-    print "  Full:", its.caps.full(props)
-    print "Capabilities"
-    print "  Manual sensor:", its.caps.manual_sensor(props)
-    print "  Manual post-proc:", its.caps.manual_post_proc(props)
-    print "  Raw:", its.caps.raw(props)
-    print "  Sensor fusion:", its.caps.sensor_fusion(props)
-
-    # Test: hardware level should be a valid value.
-    check('props.has_key("android.info.supportedHardwareLevel")')
-    check('props["android.info.supportedHardwareLevel"] is not None')
-    check('props["android.info.supportedHardwareLevel"] in [0,1,2]')
-    full = getval('props["android.info.supportedHardwareLevel"]') == 1
-
-    # Test: rollingShutterSkew, and frameDuration tags must all be present,
-    # and rollingShutterSkew must be greater than zero and smaller than all
-    # of the possible frame durations.
-    check('md.has_key("android.sensor.frameDuration")')
-    check('md["android.sensor.frameDuration"] is not None')
-    check('md.has_key("android.sensor.rollingShutterSkew")')
-    check('md["android.sensor.rollingShutterSkew"] is not None')
-    check('md["android.sensor.frameDuration"] > '
-          'md["android.sensor.rollingShutterSkew"] > 0')
-
-    # Test: timestampSource must be a valid value.
-    check('props.has_key("android.sensor.info.timestampSource")')
-    check('props["android.sensor.info.timestampSource"] is not None')
-    check('props["android.sensor.info.timestampSource"] in [0,1]')
-
-    # Test: croppingType must be a valid value, and for full devices, it
-    # must be FREEFORM=1.
-    check('props.has_key("android.scaler.croppingType")')
-    check('props["android.scaler.croppingType"] is not None')
-    check('props["android.scaler.croppingType"] in [0,1]')
-    if full:
-        check('props["android.scaler.croppingType"] == 1')
-
-    assert(not failed)
-
-def getval(expr, default=None):
-    try:
-        return eval(expr)
-    except:
-        return default
-
-failed = False
-def check(expr):
-    global md, props, failed
-    try:
-        if eval(expr):
-            print "Passed>", expr
-        else:
-            print "Failed>>", expr
-            failed = True
-    except:
-        print "Failed>>", expr
-        failed = True
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
deleted file mode 100644
index eb9a3c1..0000000
--- a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-
-def main():
-    """Test that the android.sensor.sensitivity parameter is applied properly
-    within a burst. Inspects the output metadata only (not the image data).
-    """
-
-    NUM_STEPS = 3
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.manual_sensor(props):
-            print "Test skipped"
-            return
-
-        sens_range = props['android.sensor.info.sensitivityRange']
-        sens_step = (sens_range[1] - sens_range[0]) / NUM_STEPS
-        sens_list = range(sens_range[0], sens_range[1], sens_step)
-        e = min(props['android.sensor.info.exposureTimeRange'])
-        reqs = [its.objects.manual_capture_request(s,e) for s in sens_list]
-        _,fmt = its.objects.get_fastest_manual_capture_settings(props)
-
-        caps = cam.do_capture(reqs, fmt)
-        for i,cap in enumerate(caps):
-            s_req = sens_list[i]
-            s_res = cap["metadata"]["android.sensor.sensitivity"]
-            assert(s_req == s_res)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/test_sensor_events.py b/apps/CameraITS/tests/scene0/test_sensor_events.py
deleted file mode 100644
index 61f0383..0000000
--- a/apps/CameraITS/tests/scene0/test_sensor_events.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2014 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.
-
-import its.device
-import its.caps
-import time
-
-def main():
-    """Basic test to query and print out sensor events.
-
-    Test will only work if the screen is on (i.e.) the device isn't in standby.
-    Pass if some of each event are received.
-    """
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        # Only run test if the appropriate caps are claimed.
-        if not its.caps.sensor_fusion(props):
-            print "Test skipped"
-            return
-
-        cam.start_sensor_events()
-        time.sleep(1)
-        events = cam.get_sensor_events()
-        print "Events over 1s: %d gyro, %d accel, %d mag"%(
-                len(events["gyro"]), len(events["accel"]), len(events["mag"]))
-        assert(len(events["gyro"]) > 0)
-        assert(len(events["accel"]) > 0)
-        assert(len(events["mag"]) > 0)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene0/test_unified_timestamps.py b/apps/CameraITS/tests/scene0/test_unified_timestamps.py
deleted file mode 100644
index cdc9567..0000000
--- a/apps/CameraITS/tests/scene0/test_unified_timestamps.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2014 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.
-
-import its.device
-import its.objects
-import its.caps
-import time
-
-def main():
-    """Test if image and motion sensor events are in the same time domain.
-    """
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-
-        # Only run test if the appropriate caps are claimed.
-        if not its.caps.sensor_fusion(props):
-            print "Test skipped"
-            return
-
-        # Get the timestamp of a captured image.
-        req, fmt = its.objects.get_fastest_manual_capture_settings(props)
-        cap = cam.do_capture(req, fmt)
-        ts_image0 = cap['metadata']['android.sensor.timestamp']
-
-        # Get the timestamps of motion events.
-        print "Reading sensor measurements"
-        cam.start_sensor_events()
-        time.sleep(0.5)
-        events = cam.get_sensor_events()
-        assert(len(events["gyro"]) > 0)
-        assert(len(events["accel"]) > 0)
-        assert(len(events["mag"]) > 0)
-        ts_gyro0 = events["gyro"][0]["time"]
-        ts_gyro1 = events["gyro"][-1]["time"]
-        ts_accel0 = events["accel"][0]["time"]
-        ts_accel1 = events["accel"][-1]["time"]
-        ts_mag0 = events["mag"][0]["time"]
-        ts_mag1 = events["mag"][-1]["time"]
-
-        # Get the timestamp of another image.
-        cap = cam.do_capture(req, fmt)
-        ts_image1 = cap['metadata']['android.sensor.timestamp']
-
-        print "Image timestamps:", ts_image0, ts_image1
-        print "Gyro timestamps:", ts_gyro0, ts_gyro1
-        print "Accel timestamps:", ts_accel0, ts_accel1
-        print "Mag timestamps:", ts_mag0, ts_mag1
-
-        # The motion timestamps must be between the two image timestamps.
-        assert ts_image0 < min(ts_gyro0, ts_accel0, ts_mag0) < ts_image1
-        assert ts_image0 < max(ts_gyro1, ts_accel1, ts_mag1) < ts_image1
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/README b/apps/CameraITS/tests/scene1/README
deleted file mode 100755
index 93543d9..0000000
--- a/apps/CameraITS/tests/scene1/README
+++ /dev/null
@@ -1,16 +0,0 @@
-Scene 1 description:
-* Camera on tripod in portrait or landscape orientation
-* Scene mostly filled by grey card, with white background behind grey card
-* Illuminated by simple light source, for example a desk lamp
-* Uniformity of lighting and target positioning need not be precise
-
-This is intended to be a very simple setup that can be recreated on an
-engineer's desk without any large or expensive equipment. The tests for this
-scene in general only look at a patch in the middle of the image (which is
-assumed to be within the bounds of the grey card).
-
-Note that the scene should not be completely uniform; don't have the grey card
-100% fill the field of view and use a high quality uniform light source, for
-example, and don't use a diffuser on top of the camera to simulate a grey
-scene.
-
diff --git a/apps/CameraITS/tests/scene1/test_3a.py b/apps/CameraITS/tests/scene1/test_3a.py
deleted file mode 100644
index b53fc73..0000000
--- a/apps/CameraITS/tests/scene1/test_3a.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2013 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.
-
-import its.device
-import its.caps
-
-def main():
-    """Basic test for bring-up of 3A.
-
-    To pass, 3A must converge. Check that the returned 3A values are legal.
-    """
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.read_3a(props):
-            print "Test skipped"
-            return
-
-        sens, exp, gains, xform, focus = cam.do_3a(get_results=True)
-        print "AE: sensitivity %d, exposure %dms" % (sens, exp/1000000)
-        print "AWB: gains", gains, "transform", xform
-        print "AF: distance", focus
-        assert(sens > 0)
-        assert(exp > 0)
-        assert(len(gains) == 4)
-        assert(len(xform) == 9)
-        assert(focus >= 0)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_ae_precapture_trigger.py b/apps/CameraITS/tests/scene1/test_ae_precapture_trigger.py
deleted file mode 100644
index 59b7db1..0000000
--- a/apps/CameraITS/tests/scene1/test_ae_precapture_trigger.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright 2014 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.
-
-import its.device
-import its.caps
-import its.objects
-import its.target
-
-def main():
-    """Test the AE state machine when using the precapture trigger.
-    """
-
-    INACTIVE = 0
-    SEARCHING = 1
-    CONVERGED = 2
-    LOCKED = 3
-    FLASHREQUIRED = 4
-    PRECAPTURE = 5
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        _,fmt = its.objects.get_fastest_manual_capture_settings(props)
-
-        # Capture 5 manual requests, with AE disabled, and the last request
-        # has an AE precapture trigger (which should be ignored since AE is
-        # disabled).
-        manual_reqs = []
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        manual_req = its.objects.manual_capture_request(s,e)
-        manual_req['android.control.aeMode'] = 0 # Off
-        manual_reqs += [manual_req]*4
-        precap_req = its.objects.manual_capture_request(s,e)
-        precap_req['android.control.aeMode'] = 0 # Off
-        precap_req['android.control.aePrecaptureTrigger'] = 1 # Start
-        manual_reqs.append(precap_req)
-        caps = cam.do_capture(manual_reqs, fmt)
-        for cap in caps:
-            assert(cap['metadata']['android.control.aeState'] == INACTIVE)
-
-        # Capture an auto request and verify the AE state; no trigger.
-        auto_req = its.objects.auto_capture_request()
-        auto_req['android.control.aeMode'] = 1  # On
-        cap = cam.do_capture(auto_req, fmt)
-        state = cap['metadata']['android.control.aeState']
-        print "AE state after auto request:", state
-        assert(state in [SEARCHING, CONVERGED])
-
-        # Capture with auto request with a precapture trigger.
-        auto_req['android.control.aePrecaptureTrigger'] = 1  # Start
-        cap = cam.do_capture(auto_req, fmt)
-        state = cap['metadata']['android.control.aeState']
-        print "AE state after auto request with precapture trigger:", state
-        assert(state in [SEARCHING, CONVERGED, PRECAPTURE])
-
-        # Capture some more auto requests, and AE should converge.
-        auto_req['android.control.aePrecaptureTrigger'] = 0
-        caps = cam.do_capture([auto_req]*5, fmt)
-        state = caps[-1]['metadata']['android.control.aeState']
-        print "AE state after auto request:", state
-        assert(state == CONVERGED)
-
-if __name__ == '__main__':
-    main()
diff --git a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py b/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
deleted file mode 100644
index a9d5ce4..0000000
--- a/apps/CameraITS/tests/scene1/test_auto_vs_manual.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import os.path
-import math
-
-def main():
-    """Capture auto and manual shots that should look the same.
-
-    Manual shots taken with just manual WB, and also with manual WB+tonemap.
-
-    In all cases, the general color/look of the shots should be the same,
-    however there can be variations in brightness/contrast due to different
-    "auto" ISP blocks that may be disabled in the manual flows.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if (not its.caps.manual_sensor(props) or
-            not its.caps.manual_post_proc(props)):
-            print "Test skipped"
-            return
-
-        # Converge 3A and get the estimates.
-        sens, exp, gains, xform, focus = cam.do_3a(get_results=True)
-        xform_rat = its.objects.float_to_rational(xform)
-        print "AE sensitivity %d, exposure %dms" % (sens, exp/1000000.0)
-        print "AWB gains", gains
-        print "AWB transform", xform
-        print "AF distance", focus
-
-        # Auto capture.
-        req = its.objects.auto_capture_request()
-        cap_auto = cam.do_capture(req)
-        img_auto = its.image.convert_capture_to_rgb_image(cap_auto)
-        its.image.write_image(img_auto, "%s_auto.jpg" % (NAME))
-        xform_a = its.objects.rational_to_float(
-                cap_auto["metadata"]["android.colorCorrection.transform"])
-        gains_a = cap_auto["metadata"]["android.colorCorrection.gains"]
-        print "Auto gains:", gains_a
-        print "Auto transform:", xform_a
-
-        # Manual capture 1: WB
-        req = its.objects.manual_capture_request(sens, exp)
-        req["android.colorCorrection.transform"] = xform_rat
-        req["android.colorCorrection.gains"] = gains
-        cap_man1 = cam.do_capture(req)
-        img_man1 = its.image.convert_capture_to_rgb_image(cap_man1)
-        its.image.write_image(img_man1, "%s_manual_wb.jpg" % (NAME))
-        xform_m1 = its.objects.rational_to_float(
-                cap_man1["metadata"]["android.colorCorrection.transform"])
-        gains_m1 = cap_man1["metadata"]["android.colorCorrection.gains"]
-        print "Manual wb gains:", gains_m1
-        print "Manual wb transform:", xform_m1
-
-        # Manual capture 2: WB + tonemap
-        gamma = sum([[i/63.0,math.pow(i/63.0,1/2.2)] for i in xrange(64)],[])
-        req["android.tonemap.mode"] = 0
-        req["android.tonemap.curveRed"] = gamma
-        req["android.tonemap.curveGreen"] = gamma
-        req["android.tonemap.curveBlue"] = gamma
-        cap_man2 = cam.do_capture(req)
-        img_man2 = its.image.convert_capture_to_rgb_image(cap_man2)
-        its.image.write_image(img_man2, "%s_manual_wb_tm.jpg" % (NAME))
-        xform_m2 = its.objects.rational_to_float(
-                cap_man2["metadata"]["android.colorCorrection.transform"])
-        gains_m2 = cap_man2["metadata"]["android.colorCorrection.gains"]
-        print "Manual wb+tm gains:", gains_m2
-        print "Manual wb+tm transform:", xform_m2
-
-        # Check that the WB gains and transform reported in each capture
-        # result match with the original AWB estimate from do_3a.
-        for g,x in [(gains_a,xform_a),(gains_m1,xform_m1),(gains_m2,xform_m2)]:
-            assert(all([abs(xform[i] - x[i]) < 0.05 for i in range(9)]))
-            assert(all([abs(gains[i] - g[i]) < 0.05 for i in range(4)]))
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_black_white.py b/apps/CameraITS/tests/scene1/test_black_white.py
deleted file mode 100644
index e471602..0000000
--- a/apps/CameraITS/tests/scene1/test_black_white.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that the device will produce full black+white images.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    r_means = []
-    g_means = []
-    b_means = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.manual_sensor(props):
-            print "Test skipped"
-            return
-
-        expt_range = props['android.sensor.info.exposureTimeRange']
-        sens_range = props['android.sensor.info.sensitivityRange']
-
-        # Take a shot with very low ISO and exposure time. Expect it to
-        # be black.
-        print "Black shot: sens = %d, exp time = %.4fms" % (
-                sens_range[0], expt_range[0]/1000000.0)
-        req = its.objects.manual_capture_request(sens_range[0], expt_range[0])
-        cap = cam.do_capture(req)
-        img = its.image.convert_capture_to_rgb_image(cap)
-        its.image.write_image(img, "%s_black.jpg" % (NAME))
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        black_means = its.image.compute_image_means(tile)
-        r_means.append(black_means[0])
-        g_means.append(black_means[1])
-        b_means.append(black_means[2])
-        print "Dark pixel means:", black_means
-
-        # Take a shot with very high ISO and exposure time. Expect it to
-        # be white.
-        print "White shot: sens = %d, exp time = %.2fms" % (
-                sens_range[1], expt_range[1]/1000000.0)
-        req = its.objects.manual_capture_request(sens_range[1], expt_range[1])
-        cap = cam.do_capture(req)
-        img = its.image.convert_capture_to_rgb_image(cap)
-        its.image.write_image(img, "%s_white.jpg" % (NAME))
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        white_means = its.image.compute_image_means(tile)
-        r_means.append(white_means[0])
-        g_means.append(white_means[1])
-        b_means.append(white_means[2])
-        print "Bright pixel means:", white_means
-
-        # Draw a plot.
-        pylab.plot([0,1], r_means, 'r')
-        pylab.plot([0,1], g_means, 'g')
-        pylab.plot([0,1], b_means, 'b')
-        pylab.ylim([0,1])
-        matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-        for val in black_means:
-            assert(val < 0.025)
-        for val in white_means:
-            assert(val > 0.975)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_burst_sameness_manual.py b/apps/CameraITS/tests/scene1/test_burst_sameness_manual.py
deleted file mode 100644
index 3858c0c..0000000
--- a/apps/CameraITS/tests/scene1/test_burst_sameness_manual.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-import numpy
-
-def main():
-    """Take long bursts of images and check that they're all identical.
-
-    Assumes a static scene. Can be used to idenfity if there are sporadic
-    frames that are processed differently or have artifacts. Uses manual
-    capture settings.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    BURST_LEN = 50
-    BURSTS = 5
-    FRAMES = BURST_LEN * BURSTS
-
-    SPREAD_THRESH = 0.03
-
-    with its.device.ItsSession() as cam:
-
-        # Capture at the smallest resolution.
-        props = cam.get_camera_properties()
-        if not its.caps.manual_sensor(props):
-            print "Test skipped"
-            return
-
-        _, fmt = its.objects.get_fastest_manual_capture_settings(props)
-        e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
-        req = its.objects.manual_capture_request(s, e)
-        w,h = fmt["width"], fmt["height"]
-
-        # Capture bursts of YUV shots.
-        # Get the mean values of a center patch for each.
-        # Also build a 4D array, which is an array of all RGB images.
-        r_means = []
-        g_means = []
-        b_means = []
-        imgs = numpy.empty([FRAMES,h,w,3])
-        for j in range(BURSTS):
-            caps = cam.do_capture([req]*BURST_LEN, [fmt])
-            for i,cap in enumerate(caps):
-                n = j*BURST_LEN + i
-                imgs[n] = its.image.convert_capture_to_rgb_image(cap)
-                tile = its.image.get_image_patch(imgs[n], 0.45, 0.45, 0.1, 0.1)
-                means = its.image.compute_image_means(tile)
-                r_means.append(means[0])
-                g_means.append(means[1])
-                b_means.append(means[2])
-
-        # Dump all images.
-        print "Dumping images"
-        for i in range(FRAMES):
-            its.image.write_image(imgs[i], "%s_frame%03d.jpg"%(NAME,i))
-
-        # The mean image.
-        img_mean = imgs.mean(0)
-        its.image.write_image(img_mean, "%s_mean.jpg"%(NAME))
-
-        # Pass/fail based on center patch similarity.
-        for means in [r_means, g_means, b_means]:
-            spread = max(means) - min(means)
-            print spread
-            assert(spread < SPREAD_THRESH)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_capture_result.py b/apps/CameraITS/tests/scene1/test_capture_result.py
deleted file mode 100644
index 304e811..0000000
--- a/apps/CameraITS/tests/scene1/test_capture_result.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import os.path
-import numpy
-import matplotlib.pyplot
-
-# Required for 3d plot to work
-import mpl_toolkits.mplot3d
-
-def main():
-    """Test that valid data comes back in CaptureResult objects.
-    """
-    global NAME, auto_req, manual_req, w_map, h_map
-    global manual_tonemap, manual_transform, manual_gains, manual_region
-    global manual_exp_time, manual_sensitivity, manual_gains_ok
-
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if (not its.caps.manual_sensor(props) or
-            not its.caps.manual_post_proc(props)):
-            print "Test skipped"
-            return
-
-        manual_tonemap = [0,0, 1,1] # Linear
-        manual_transform = its.objects.int_to_rational([1,2,3, 4,5,6, 7,8,9])
-        manual_gains = [1,2,3,4]
-        manual_region = [{"x":8,"y":8,"width":128,"height":128,"weight":1}]
-        manual_exp_time = min(props['android.sensor.info.exposureTimeRange'])
-        manual_sensitivity = min(props['android.sensor.info.sensitivityRange'])
-
-        # The camera HAL may not support different gains for two G channels.
-        manual_gains_ok = [[1,2,3,4],[1,2,2,4],[1,3,3,4]]
-
-        auto_req = its.objects.auto_capture_request()
-        auto_req["android.statistics.lensShadingMapMode"] = 1
-
-        manual_req = {
-            "android.control.mode": 0,
-            "android.control.aeMode": 0,
-            "android.control.awbMode": 0,
-            "android.control.afMode": 0,
-            "android.sensor.frameDuration": 0,
-            "android.sensor.sensitivity": manual_sensitivity,
-            "android.sensor.exposureTime": manual_exp_time,
-            "android.colorCorrection.mode": 0,
-            "android.colorCorrection.transform": manual_transform,
-            "android.colorCorrection.gains": manual_gains,
-            "android.tonemap.mode": 0,
-            "android.tonemap.curveRed": manual_tonemap,
-            "android.tonemap.curveGreen": manual_tonemap,
-            "android.tonemap.curveBlue": manual_tonemap,
-            "android.control.aeRegions": manual_region,
-            "android.control.afRegions": manual_region,
-            "android.control.awbRegions": manual_region,
-            "android.statistics.lensShadingMapMode":1
-            }
-
-        w_map = props["android.lens.info.shadingMapSize"]["width"]
-        h_map = props["android.lens.info.shadingMapSize"]["height"]
-
-        print "Testing auto capture results"
-        lsc_map_auto = test_auto(cam, w_map, h_map)
-        print "Testing manual capture results"
-        test_manual(cam, w_map, h_map, lsc_map_auto)
-        print "Testing auto capture results again"
-        test_auto(cam, w_map, h_map)
-
-# A very loose definition for two floats being close to each other;
-# there may be different interpolation and rounding used to get the
-# two values, and all this test is looking at is whether there is
-# something obviously broken; it's not looking for a perfect match.
-def is_close_float(n1, n2):
-    return abs(n1 - n2) < 0.05
-
-def is_close_rational(n1, n2):
-    return is_close_float(its.objects.rational_to_float(n1),
-                          its.objects.rational_to_float(n2))
-
-def draw_lsc_plot(w_map, h_map, lsc_map, name):
-    for ch in range(4):
-        fig = matplotlib.pyplot.figure()
-        ax = fig.gca(projection='3d')
-        xs = numpy.array([range(w_map)] * h_map).reshape(h_map, w_map)
-        ys = numpy.array([[i]*w_map for i in range(h_map)]).reshape(
-                h_map, w_map)
-        zs = numpy.array(lsc_map[ch::4]).reshape(h_map, w_map)
-        ax.plot_wireframe(xs, ys, zs)
-        matplotlib.pyplot.savefig("%s_plot_lsc_%s_ch%d.png"%(NAME,name,ch))
-
-def test_auto(cam, w_map, h_map):
-    # Get 3A lock first, so the auto values in the capture result are
-    # populated properly.
-    rect = [[0,0,1,1,1]]
-    cam.do_3a(rect, rect, rect, do_af=False)
-
-    cap = cam.do_capture(auto_req)
-    cap_res = cap["metadata"]
-
-    gains = cap_res["android.colorCorrection.gains"]
-    transform = cap_res["android.colorCorrection.transform"]
-    exp_time = cap_res['android.sensor.exposureTime']
-    lsc_map = cap_res["android.statistics.lensShadingMap"]
-    ctrl_mode = cap_res["android.control.mode"]
-
-    print "Control mode:", ctrl_mode
-    print "Gains:", gains
-    print "Transform:", [its.objects.rational_to_float(t)
-                         for t in transform]
-    print "AE region:", cap_res['android.control.aeRegions']
-    print "AF region:", cap_res['android.control.afRegions']
-    print "AWB region:", cap_res['android.control.awbRegions']
-    print "LSC map:", w_map, h_map, lsc_map[:8]
-
-    assert(ctrl_mode == 1)
-
-    # Color correction gain and transform must be valid.
-    assert(len(gains) == 4)
-    assert(len(transform) == 9)
-    assert(all([g > 0 for g in gains]))
-    assert(all([t["denominator"] != 0 for t in transform]))
-
-    # Color correction should not match the manual settings.
-    assert(any([not is_close_float(gains[i], manual_gains[i])
-                for i in xrange(4)]))
-    assert(any([not is_close_rational(transform[i], manual_transform[i])
-                for i in xrange(9)]))
-
-    # Exposure time must be valid.
-    assert(exp_time > 0)
-
-    # Lens shading map must be valid.
-    assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map))
-    assert(all([m >= 1 for m in lsc_map]))
-
-    draw_lsc_plot(w_map, h_map, lsc_map, "auto")
-
-    return lsc_map
-
-def test_manual(cam, w_map, h_map, lsc_map_auto):
-    cap = cam.do_capture(manual_req)
-    cap_res = cap["metadata"]
-
-    gains = cap_res["android.colorCorrection.gains"]
-    transform = cap_res["android.colorCorrection.transform"]
-    curves = [cap_res["android.tonemap.curveRed"],
-              cap_res["android.tonemap.curveGreen"],
-              cap_res["android.tonemap.curveBlue"]]
-    exp_time = cap_res['android.sensor.exposureTime']
-    lsc_map = cap_res["android.statistics.lensShadingMap"]
-    ctrl_mode = cap_res["android.control.mode"]
-
-    print "Control mode:", ctrl_mode
-    print "Gains:", gains
-    print "Transform:", [its.objects.rational_to_float(t)
-                         for t in transform]
-    print "Tonemap:", curves[0][1::16]
-    print "AE region:", cap_res['android.control.aeRegions']
-    print "AF region:", cap_res['android.control.afRegions']
-    print "AWB region:", cap_res['android.control.awbRegions']
-    print "LSC map:", w_map, h_map, lsc_map[:8]
-
-    assert(ctrl_mode == 0)
-
-    # Color correction gain and transform must be valid.
-    # Color correction gains and transform should be the same size and
-    # values as the manually set values.
-    assert(len(gains) == 4)
-    assert(len(transform) == 9)
-    assert( all([is_close_float(gains[i], manual_gains_ok[0][i])
-                 for i in xrange(4)]) or
-            all([is_close_float(gains[i], manual_gains_ok[1][i])
-                 for i in xrange(4)]) or
-            all([is_close_float(gains[i], manual_gains_ok[2][i])
-                 for i in xrange(4)]))
-    assert(all([is_close_rational(transform[i], manual_transform[i])
-                for i in xrange(9)]))
-
-    # Tonemap must be valid.
-    # The returned tonemap must be linear.
-    for c in curves:
-        assert(len(c) > 0)
-        assert(all([is_close_float(c[i], c[i+1])
-                    for i in xrange(0,len(c),2)]))
-
-    # Exposure time must be close to the requested exposure time.
-    assert(is_close_float(exp_time/1000000.0, manual_exp_time/1000000.0))
-
-    # Lens shading map must be valid.
-    assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map))
-    assert(all([m >= 1 for m in lsc_map]))
-
-    draw_lsc_plot(w_map, h_map, lsc_map, "manual")
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_crop_region_raw.py b/apps/CameraITS/tests/scene1/test_crop_region_raw.py
deleted file mode 100644
index 94c8e2b..0000000
--- a/apps/CameraITS/tests/scene1/test_crop_region_raw.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import numpy
-import os.path
-
-def main():
-    """Test that raw streams are not croppable.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    DIFF_THRESH = 0.05
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if (not its.caps.compute_target_exposure(props) or
-            not its.caps.raw16(props)):
-            print "Test skipped"
-            return
-
-        a = props['android.sensor.info.activeArraySize']
-        ax, ay = a["left"], a["top"]
-        aw, ah = a["right"] - a["left"], a["bottom"] - a["top"]
-        print "Active sensor region: (%d,%d %dx%d)" % (ax, ay, aw, ah)
-
-        # Capture without a crop region.
-        # Use a manual request with a linear tonemap so that the YUV and RAW
-        # should look the same (once converted by the its.image module).
-        e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
-        req = its.objects.manual_capture_request(s,e, True)
-        cap1_raw, cap1_yuv = cam.do_capture(req, cam.CAP_RAW_YUV)
-
-        # Capture with a center crop region.
-        req["android.scaler.cropRegion"] = {
-                "top": ay + ah/3,
-                "left": ax + aw/3,
-                "right": ax + 2*aw/3,
-                "bottom": ay + 2*ah/3}
-        cap2_raw, cap2_yuv = cam.do_capture(req, cam.CAP_RAW_YUV)
-
-        reported_crops = []
-        imgs = {}
-        for s,cap in [("yuv_full",cap1_yuv), ("raw_full",cap1_raw),
-                ("yuv_crop",cap2_yuv), ("raw_crop",cap2_raw)]:
-            img = its.image.convert_capture_to_rgb_image(cap, props=props)
-            its.image.write_image(img, "%s_%s.jpg" % (NAME, s))
-            r = cap["metadata"]["android.scaler.cropRegion"]
-            x, y = a["left"], a["top"]
-            w, h = a["right"] - a["left"], a["bottom"] - a["top"]
-            reported_crops.append((x,y,w,h))
-            imgs[s] = img
-            print "Crop on %s: (%d,%d %dx%d)" % (s, x,y,w,h)
-
-        # The metadata should report uncropped for all shots (since there is
-        # at least 1 uncropped stream in each case).
-        for (x,y,w,h) in reported_crops:
-            assert((ax,ay,aw,ah) == (x,y,w,h))
-
-        # Also check the image content; 3 of the 4 shots should match.
-        # Note that all the shots are RGB below; the variable names correspond
-        # to what was captured.
-        # Average the images down 4x4 -> 1 prior to comparison to smooth out
-        # noise.
-        # Shrink the YUV images an additional 2x2 -> 1 to account for the size
-        # reduction that the raw images went through in the RGB conversion.
-        imgs2 = {}
-        for s,img in imgs.iteritems():
-            h,w,ch = img.shape
-            m = 4
-            if s in ["yuv_full", "yuv_crop"]:
-                m = 8
-            img = img.reshape(h/m,m,w/m,m,3).mean(3).mean(1).reshape(h/m,w/m,3)
-            imgs2[s] = img
-            print s, img.shape
-
-        # Strip any border pixels from the raw shots (since the raw images may
-        # be larger than the YUV images). Assume a symmetric padded border.
-        xpad = (imgs2["raw_full"].shape[1] - imgs2["yuv_full"].shape[1]) / 2
-        ypad = (imgs2["raw_full"].shape[0] - imgs2["yuv_full"].shape[0]) / 2
-        wyuv = imgs2["yuv_full"].shape[1]
-        hyuv = imgs2["yuv_full"].shape[0]
-        imgs2["raw_full"]=imgs2["raw_full"][ypad:ypad+hyuv:,xpad:xpad+wyuv:,::]
-        imgs2["raw_crop"]=imgs2["raw_crop"][ypad:ypad+hyuv:,xpad:xpad+wyuv:,::]
-        print "Stripping padding before comparison:", xpad, ypad
-
-        for s,img in imgs2.iteritems():
-            its.image.write_image(img, "%s_comp_%s.jpg" % (NAME, s))
-
-        # Compute image diffs.
-        diff_yuv = numpy.fabs((imgs2["yuv_full"] - imgs2["yuv_crop"])).mean()
-        diff_raw = numpy.fabs((imgs2["raw_full"] - imgs2["raw_crop"])).mean()
-        print "YUV diff (crop vs. non-crop):", diff_yuv
-        print "RAW diff (crop vs. non-crop):", diff_raw
-
-        assert(diff_yuv > DIFF_THRESH)
-        assert(diff_raw < DIFF_THRESH)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_crop_regions.py b/apps/CameraITS/tests/scene1/test_crop_regions.py
deleted file mode 100644
index da0cd0a..0000000
--- a/apps/CameraITS/tests/scene1/test_crop_regions.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-import numpy
-
-def main():
-    """Test that crop regions work.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # A list of 5 regions, specified in normalized (x,y,w,h) coords.
-    # The regions correspond to: TL, TR, BL, BR, CENT
-    REGIONS = [(0.0, 0.0, 0.5, 0.5),
-               (0.5, 0.0, 0.5, 0.5),
-               (0.0, 0.5, 0.5, 0.5),
-               (0.5, 0.5, 0.5, 0.5),
-               (0.25, 0.25, 0.5, 0.5)]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        a = props['android.sensor.info.activeArraySize']
-        ax, ay = a["left"], a["top"]
-        aw, ah = a["right"] - a["left"], a["bottom"] - a["top"]
-        e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
-        print "Active sensor region (%d,%d %dx%d)" % (ax, ay, aw, ah)
-
-        # Uses a 2x digital zoom.
-        assert(props['android.scaler.availableMaxDigitalZoom'] >= 2)
-
-        # Capture a full frame.
-        req = its.objects.manual_capture_request(s,e)
-        cap_full = cam.do_capture(req)
-        img_full = its.image.convert_capture_to_rgb_image(cap_full)
-        its.image.write_image(img_full, "%s_full.jpg" % (NAME))
-        wfull, hfull = cap_full["width"], cap_full["height"]
-
-        # Capture a burst of crop region frames.
-        # Note that each region is 1/2x1/2 of the full frame, and is digitally
-        # zoomed into the full size output image, so must be downscaled (below)
-        # by 2x when compared to a tile of the full image.
-        reqs = []
-        for x,y,w,h in REGIONS:
-            req = its.objects.manual_capture_request(s,e)
-            req["android.scaler.cropRegion"] = {
-                    "top": int(ah * y),
-                    "left": int(aw * x),
-                    "right": int(aw * (x + w)),
-                    "bottom": int(ah * (y + h))}
-            reqs.append(req)
-        caps_regions = cam.do_capture(reqs)
-        match_failed = False
-        for i,cap in enumerate(caps_regions):
-            a = cap["metadata"]["android.scaler.cropRegion"]
-            ax, ay = a["left"], a["top"]
-            aw, ah = a["right"] - a["left"], a["bottom"] - a["top"]
-
-            # Match this crop image against each of the five regions of
-            # the full image, to find the best match (which should be
-            # the region that corresponds to this crop image).
-            img_crop = its.image.convert_capture_to_rgb_image(cap)
-            img_crop = its.image.downscale_image(img_crop, 2)
-            its.image.write_image(img_crop, "%s_crop%d.jpg" % (NAME, i))
-            min_diff = None
-            min_diff_region = None
-            for j,(x,y,w,h) in enumerate(REGIONS):
-                tile_full = its.image.get_image_patch(img_full, x,y,w,h)
-                wtest = min(tile_full.shape[1], aw)
-                htest = min(tile_full.shape[0], ah)
-                tile_full = tile_full[0:htest:, 0:wtest:, ::]
-                tile_crop = img_crop[0:htest:, 0:wtest:, ::]
-                its.image.write_image(tile_full, "%s_fullregion%d.jpg"%(NAME,j))
-                diff = numpy.fabs(tile_full - tile_crop).mean()
-                if min_diff is None or diff < min_diff:
-                    min_diff = diff
-                    min_diff_region = j
-            if i != min_diff_region:
-                match_failed = True
-            print "Crop image %d (%d,%d %dx%d) best match with region %d"%(
-                    i, ax, ay, aw, ah, min_diff_region)
-
-        assert(not match_failed)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_exposure.py b/apps/CameraITS/tests/scene1/test_exposure.py
deleted file mode 100644
index 8676358..0000000
--- a/apps/CameraITS/tests/scene1/test_exposure.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import pylab
-import numpy
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that a constant exposure is seen as ISO and exposure time vary.
-
-    Take a series of shots that have ISO and exposure time chosen to balance
-    each other; result should be the same brightness, but over the sequence
-    the images should get noisier.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_MAX_OUTLIER_DIFF = 0.1
-    THRESHOLD_MIN_LEVEL = 0.1
-    THRESHOLD_MAX_LEVEL = 0.9
-    THRESHOLD_MAX_ABS_GRAD = 0.001
-
-    mults = []
-    r_means = []
-    g_means = []
-    b_means = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        e,s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
-        expt_range = props['android.sensor.info.exposureTimeRange']
-        sens_range = props['android.sensor.info.sensitivityRange']
-
-        m = 1
-        while s*m < sens_range[1] and e/m > expt_range[0]:
-            mults.append(m)
-            req = its.objects.manual_capture_request(s*m, e/m)
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_mult=%02d.jpg" % (NAME, m))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile)
-            r_means.append(rgb_means[0])
-            g_means.append(rgb_means[1])
-            b_means.append(rgb_means[2])
-            m = m + 4
-
-    # Draw a plot.
-    pylab.plot(mults, r_means, 'r')
-    pylab.plot(mults, g_means, 'g')
-    pylab.plot(mults, b_means, 'b')
-    pylab.ylim([0,1])
-    matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-    # Check for linearity. For each R,G,B channel, fit a line y=mx+b, and
-    # assert that the gradient is close to 0 (flat) and that there are no
-    # crazy outliers. Also ensure that the images aren't clamped to 0 or 1
-    # (which would make them look like flat lines).
-    for chan in xrange(3):
-        values = [r_means, g_means, b_means][chan]
-        m, b = numpy.polyfit(mults, values, 1).tolist()
-        print "Channel %d line fit (y = mx+b): m = %f, b = %f" % (chan, m, b)
-        assert(abs(m) < THRESHOLD_MAX_ABS_GRAD)
-        assert(b > THRESHOLD_MIN_LEVEL and b < THRESHOLD_MAX_LEVEL)
-        for v in values:
-            assert(v > THRESHOLD_MIN_LEVEL and v < THRESHOLD_MAX_LEVEL)
-            assert(abs(v - b) < THRESHOLD_MAX_OUTLIER_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_format_combos.py b/apps/CameraITS/tests/scene1/test_format_combos.py
deleted file mode 100644
index a021102..0000000
--- a/apps/CameraITS/tests/scene1/test_format_combos.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.error
-import its.target
-import sys
-import os
-import os.path
-
-# Change this to True, to have the test break at the first failure.
-stop_at_first_failure = False
-
-def main():
-    """Test different combinations of output formats.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-
-        props = cam.get_camera_properties()
-        if (not its.caps.compute_target_exposure(props) or
-            not its.caps.raw16(props)):
-            print "Test skipped"
-            return
-
-        successes = []
-        failures = []
-
-        # Two different requests: auto, and manual.
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req_aut = its.objects.auto_capture_request()
-        req_man = its.objects.manual_capture_request(s, e)
-        reqs = [req_aut, # R0
-                req_man] # R1
-
-        # 10 different combos of output formats; some are single surfaces, and
-        # some are multiple surfaces.
-        wyuv,hyuv = its.objects.get_available_output_sizes("yuv", props)[-1]
-        wjpg,hjpg = its.objects.get_available_output_sizes("jpg", props)[-1]
-        fmt_yuv_prev = {"format":"yuv", "width":wyuv, "height":hyuv}
-        fmt_yuv_full = {"format":"yuv"}
-        fmt_jpg_prev = {"format":"jpeg","width":wjpg, "height":hjpg}
-        fmt_jpg_full = {"format":"jpeg"}
-        fmt_raw_full = {"format":"raw"}
-        fmt_combos =[
-                [fmt_yuv_prev],                             # F0
-                [fmt_yuv_full],                             # F1
-                [fmt_jpg_prev],                             # F2
-                [fmt_jpg_full],                             # F3
-                [fmt_raw_full],                             # F4
-                [fmt_yuv_prev, fmt_jpg_prev],               # F5
-                [fmt_yuv_prev, fmt_jpg_full],               # F6
-                [fmt_yuv_prev, fmt_raw_full],               # F7
-                [fmt_yuv_prev, fmt_jpg_prev, fmt_raw_full], # F8
-                [fmt_yuv_prev, fmt_jpg_full, fmt_raw_full]] # F9
-
-        # Two different burst lengths: single frame, and 3 frames.
-        burst_lens = [1, # B0
-                      3] # B1
-
-        # There are 2x10x2=40 different combinations. Run through them all.
-        n = 0
-        for r,req in enumerate(reqs):
-            for f,fmt_combo in enumerate(fmt_combos):
-                for b,burst_len in enumerate(burst_lens):
-                    try:
-                        caps = cam.do_capture([req]*burst_len, fmt_combo)
-                        successes.append((n,r,f,b))
-                        print "==> Success[%02d]: R%d F%d B%d" % (n,r,f,b)
-
-                        # Dump the captures out to jpegs.
-                        if not isinstance(caps, list):
-                            caps = [caps]
-                        elif isinstance(caps[0], list):
-                            caps = sum(caps, [])
-                        for c,cap in enumerate(caps):
-                            img = its.image.convert_capture_to_rgb_image(cap,
-                                    props=props)
-                            its.image.write_image(img,
-                                    "%s_n%02d_r%d_f%d_b%d_c%d.jpg"%(NAME,n,r,f,b,c))
-
-                    except Exception as e:
-                        print e
-                        print "==> Failure[%02d]: R%d F%d B%d" % (n,r,f,b)
-                        failures.append((n,r,f,b))
-                        if stop_at_first_failure:
-                            sys.exit(0)
-                    n += 1
-
-        num_fail = len(failures)
-        num_success = len(successes)
-        num_total = len(reqs)*len(fmt_combos)*len(burst_lens)
-        num_not_run = num_total - num_success - num_fail
-
-        print "\nFailures (%d / %d):" % (num_fail, num_total)
-        for (n,r,f,b) in failures:
-            print "  %02d: R%d F%d B%d" % (n,r,f,b)
-        print "\nSuccesses (%d / %d):" % (num_success, num_total)
-        for (n,r,f,b) in successes:
-            print "  %02d: R%d F%d B%d" % (n,r,f,b)
-        if num_not_run > 0:
-            print "\nNumber of tests not run: %d / %d" % (num_not_run, num_total)
-        print ""
-
-        # The test passes if all the combinations successfully capture.
-        assert(num_fail == 0)
-        assert(num_success == num_total)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_jpeg.py b/apps/CameraITS/tests/scene1/test_jpeg.py
deleted file mode 100644
index bc2d64e..0000000
--- a/apps/CameraITS/tests/scene1/test_jpeg.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-import math
-
-def main():
-    """Test that converted YUV images and device JPEG images look the same.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_MAX_RMS_DIFF = 0.01
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
-
-        # YUV
-        size = its.objects.get_available_output_sizes("yuv", props)[0]
-        out_surface = {"width":size[0], "height":size[1], "format":"yuv"}
-        cap = cam.do_capture(req, out_surface)
-        img = its.image.convert_capture_to_rgb_image(cap)
-        its.image.write_image(img, "%s_fmt=yuv.jpg" % (NAME))
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        rgb0 = its.image.compute_image_means(tile)
-
-        # JPEG
-        size = its.objects.get_available_output_sizes("jpg", props)[0]
-        out_surface = {"width":size[0], "height":size[1], "format":"jpg"}
-        cap = cam.do_capture(req, out_surface)
-        img = its.image.decompress_jpeg_to_rgb_image(cap["data"])
-        its.image.write_image(img, "%s_fmt=jpg.jpg" % (NAME))
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        rgb1 = its.image.compute_image_means(tile)
-
-        rms_diff = math.sqrt(
-                sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
-        print "RMS difference:", rms_diff
-        assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_latching.py b/apps/CameraITS/tests/scene1/test_latching.py
deleted file mode 100644
index bef41ac..0000000
--- a/apps/CameraITS/tests/scene1/test_latching.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that settings latch on the right frame.
-
-    Takes a bunch of shots using back-to-back requests, varying the capture
-    request parameters between shots. Checks that the images that come back
-    have the expected properties.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.full(props):
-            print "Test skipped"
-            return
-
-        _,fmt = its.objects.get_fastest_manual_capture_settings(props)
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        e /= 2.0
-
-        r_means = []
-        g_means = []
-        b_means = []
-
-        reqs = [
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s*2,e,   True),
-            its.objects.manual_capture_request(s*2,e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e*2, True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s*2,e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e*2, True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e*2, True),
-            its.objects.manual_capture_request(s,  e*2, True),
-            ]
-
-        caps = cam.do_capture(reqs, fmt)
-        for i,cap in enumerate(caps):
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_i=%02d.jpg" % (NAME, i))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile)
-            r_means.append(rgb_means[0])
-            g_means.append(rgb_means[1])
-            b_means.append(rgb_means[2])
-
-        # Draw a plot.
-        idxs = range(len(r_means))
-        pylab.plot(idxs, r_means, 'r')
-        pylab.plot(idxs, g_means, 'g')
-        pylab.plot(idxs, b_means, 'b')
-        pylab.ylim([0,1])
-        matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-        g_avg = sum(g_means) / len(g_means)
-        g_ratios = [g / g_avg for g in g_means]
-        g_hilo = [g>1.0 for g in g_ratios]
-        assert(g_hilo == [False, False, True, True, False, False, True,
-                          False, True, False, True, False, True, True])
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_linearity.py b/apps/CameraITS/tests/scene1/test_linearity.py
deleted file mode 100644
index fed0324..0000000
--- a/apps/CameraITS/tests/scene1/test_linearity.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import numpy
-import math
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that device processing can be inverted to linear pixels.
-
-    Captures a sequence of shots with the device pointed at a uniform
-    target. Attempts to invert all the ISP processing to get back to
-    linear R,G,B pixel data.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    RESIDUAL_THRESHOLD = 0.00005
-
-    # The HAL3.2 spec requires that curves up to 64 control points in length
-    # must be supported.
-    L = 64
-    LM1 = float(L-1)
-
-    gamma_lut = numpy.array(
-            sum([[i/LM1, math.pow(i/LM1, 1/2.2)] for i in xrange(L)], []))
-    inv_gamma_lut = numpy.array(
-            sum([[i/LM1, math.pow(i/LM1, 2.2)] for i in xrange(L)], []))
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        e,s = its.target.get_target_exposure_combos(cam)["midSensitivity"]
-        s /= 2
-        sens_range = props['android.sensor.info.sensitivityRange']
-        sensitivities = [s*1.0/3.0, s*2.0/3.0, s, s*4.0/3.0, s*5.0/3.0]
-        sensitivities = [s for s in sensitivities
-                if s > sens_range[0] and s < sens_range[1]]
-
-        req = its.objects.manual_capture_request(0, e)
-        req["android.blackLevel.lock"] = True
-        req["android.tonemap.mode"] = 0
-        req["android.tonemap.curveRed"] = gamma_lut.tolist()
-        req["android.tonemap.curveGreen"] = gamma_lut.tolist()
-        req["android.tonemap.curveBlue"] = gamma_lut.tolist()
-
-        r_means = []
-        g_means = []
-        b_means = []
-
-        for sens in sensitivities:
-            req["android.sensor.sensitivity"] = sens
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(
-                    img, "%s_sens=%04d.jpg" % (NAME, sens))
-            img = its.image.apply_lut_to_image(img, inv_gamma_lut[1::2] * LM1)
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile)
-            r_means.append(rgb_means[0])
-            g_means.append(rgb_means[1])
-            b_means.append(rgb_means[2])
-
-        pylab.plot(sensitivities, r_means, 'r')
-        pylab.plot(sensitivities, g_means, 'g')
-        pylab.plot(sensitivities, b_means, 'b')
-        pylab.ylim([0,1])
-        matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-        # Check that each plot is actually linear.
-        for means in [r_means, g_means, b_means]:
-            line,residuals,_,_,_  = numpy.polyfit(range(5),means,1,full=True)
-            print "Line: m=%f, b=%f, resid=%f"%(line[0], line[1], residuals[0])
-            assert(residuals[0] < RESIDUAL_THRESHOLD)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_locked_burst.py b/apps/CameraITS/tests/scene1/test_locked_burst.py
deleted file mode 100644
index 83cfa25..0000000
--- a/apps/CameraITS/tests/scene1/test_locked_burst.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.device
-import its.objects
-import os.path
-import numpy
-import pylab
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test 3A lock + YUV burst (using auto settings).
-
-    This is a test that is designed to pass even on limited devices that
-    don't have MANUAL_SENSOR or PER_FRAME_CONTROLS. (They must be able to
-    capture bursts with full res @ full frame rate to pass, however).
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    BURST_LEN = 10
-    SPREAD_THRESH = 0.005
-    FPS_MAX_DIFF = 2.0
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-
-        # Converge 3A prior to capture.
-        cam.do_3a(do_af=False, lock_ae=True, lock_awb=True)
-
-        # After 3A has converged, lock AE+AWB for the duration of the test.
-        req = its.objects.auto_capture_request()
-        req["android.control.awbLock"] = True
-        req["android.control.aeLock"] = True
-
-        # Capture bursts of YUV shots.
-        # Get the mean values of a center patch for each.
-        r_means = []
-        g_means = []
-        b_means = []
-        caps = cam.do_capture([req]*BURST_LEN)
-        for i,cap in enumerate(caps):
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_frame%d.jpg"%(NAME,i))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            means = its.image.compute_image_means(tile)
-            r_means.append(means[0])
-            g_means.append(means[1])
-            b_means.append(means[2])
-
-        # Pass/fail based on center patch similarity.
-        for means in [r_means, g_means, b_means]:
-            spread = max(means) - min(means)
-            print "Patch mean spread", spread
-            assert(spread < SPREAD_THRESH)
-
-        # Also ensure that the burst was at full frame rate.
-        fmt_code = 0x23
-        configs = props['android.scaler.streamConfigurationMap']\
-                       ['availableStreamConfigurations']
-        min_duration = None
-        for cfg in configs:
-            if cfg['format'] == fmt_code and cfg['input'] == False and \
-                    cfg['width'] == caps[0]["width"] and \
-                    cfg['height'] == caps[0]["height"]:
-                min_duration = cfg["minFrameDuration"]
-        assert(min_duration is not None)
-        tstamps = [c['metadata']['android.sensor.timestamp'] for c in caps]
-        deltas = [tstamps[i]-tstamps[i-1] for i in range(1,len(tstamps))]
-        actual_fps = 1.0 / (max(deltas) / 1000000000.0)
-        max_fps = 1.0 / (min_duration / 1000000000.0)
-        print "FPS measured %.1f, max advertized %.1f" %(actual_fps, max_fps)
-        assert(max_fps - FPS_MAX_DIFF <= actual_fps <= max_fps)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_param_color_correction.py b/apps/CameraITS/tests/scene1/test_param_color_correction.py
deleted file mode 100644
index 82f2342..0000000
--- a/apps/CameraITS/tests/scene1/test_param_color_correction.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that the android.colorCorrection.* params are applied when set.
-
-    Takes shots with different transform and gains values, and tests that
-    they look correspondingly different. The transform and gains are chosen
-    to make the output go redder or bluer.
-
-    Uses a linear tonemap.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_MAX_DIFF = 0.1
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        # Baseline request
-        e, s = its.target.get_target_exposure_combos(cam)["midSensitivity"]
-        req = its.objects.manual_capture_request(s, e, True)
-        req["android.colorCorrection.mode"] = 0
-
-        # Transforms:
-        # 1. Identity
-        # 2. Identity
-        # 3. Boost blue
-        transforms = [its.objects.int_to_rational([1,0,0, 0,1,0, 0,0,1]),
-                      its.objects.int_to_rational([1,0,0, 0,1,0, 0,0,1]),
-                      its.objects.int_to_rational([1,0,0, 0,1,0, 0,0,2])]
-
-        # Gains:
-        # 1. Unit
-        # 2. Boost red
-        # 3. Unit
-        gains = [[1,1,1,1], [2,1,1,1], [1,1,1,1]]
-
-        r_means = []
-        g_means = []
-        b_means = []
-
-        # Capture requests:
-        # 1. With unit gains, and identity transform.
-        # 2. With a higher red gain, and identity transform.
-        # 3. With unit gains, and a transform that boosts blue.
-        for i in range(len(transforms)):
-            req["android.colorCorrection.transform"] = transforms[i]
-            req["android.colorCorrection.gains"] = gains[i]
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_req=%d.jpg" % (NAME, i))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile)
-            r_means.append(rgb_means[0])
-            g_means.append(rgb_means[1])
-            b_means.append(rgb_means[2])
-            ratios = [rgb_means[0] / rgb_means[1], rgb_means[2] / rgb_means[1]]
-            print "Means = ", rgb_means, "   Ratios =", ratios
-
-        # Draw a plot.
-        domain = range(len(transforms))
-        pylab.plot(domain, r_means, 'r')
-        pylab.plot(domain, g_means, 'g')
-        pylab.plot(domain, b_means, 'b')
-        pylab.ylim([0,1])
-        matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-        # Expect G0 == G1 == G2, R0 == 0.5*R1 == R2, B0 == B1 == 0.5*B2
-        # Also need to ensure that the imasge is not clamped to white/black.
-        assert(all(g_means[i] > 0.2 and g_means[i] < 0.8 for i in xrange(3)))
-        assert(abs(g_means[1] - g_means[0]) < THRESHOLD_MAX_DIFF)
-        assert(abs(g_means[2] - g_means[1]) < THRESHOLD_MAX_DIFF)
-        assert(abs(r_means[2] - r_means[0]) < THRESHOLD_MAX_DIFF)
-        assert(abs(r_means[1] - 2.0 * r_means[0]) < THRESHOLD_MAX_DIFF)
-        assert(abs(b_means[1] - b_means[0]) < THRESHOLD_MAX_DIFF)
-        assert(abs(b_means[2] - 2.0 * b_means[0]) < THRESHOLD_MAX_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_param_exposure_time.py b/apps/CameraITS/tests/scene1/test_param_exposure_time.py
deleted file mode 100644
index 390fd3c..0000000
--- a/apps/CameraITS/tests/scene1/test_param_exposure_time.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that the android.sensor.exposureTime parameter is applied.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    exp_times = []
-    r_means = []
-    g_means = []
-    b_means = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        e,s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        for i,e_mult in enumerate([0.8, 0.9, 1.0, 1.1, 1.2]):
-            req = its.objects.manual_capture_request(s, e * e_mult, True)
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(
-                    img, "%s_frame%d.jpg" % (NAME, i))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile)
-            exp_times.append(e * e_mult)
-            r_means.append(rgb_means[0])
-            g_means.append(rgb_means[1])
-            b_means.append(rgb_means[2])
-
-    # Draw a plot.
-    pylab.plot(exp_times, r_means, 'r')
-    pylab.plot(exp_times, g_means, 'g')
-    pylab.plot(exp_times, b_means, 'b')
-    pylab.ylim([0,1])
-    matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-    # Test for pass/fail: check that each shot is brighter than the previous.
-    for means in [r_means, g_means, b_means]:
-        for i in range(len(means)-1):
-            assert(means[i+1] > means[i])
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_param_flash_mode.py b/apps/CameraITS/tests/scene1/test_param_flash_mode.py
deleted file mode 100644
index 6d1be4f..0000000
--- a/apps/CameraITS/tests/scene1/test_param_flash_mode.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-
-def main():
-    """Test that the android.flash.mode parameter is applied.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        flash_modes_reported = []
-        flash_states_reported = []
-        g_means = []
-
-        # Manually set the exposure to be a little on the dark side, so that
-        # it should be obvious whether the flash fired or not, and use a
-        # linear tonemap.
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        e /= 4
-        req = its.objects.manual_capture_request(s, e, True)
-
-        for f in [0,1,2]:
-            req["android.flash.mode"] = f
-            cap = cam.do_capture(req)
-            flash_modes_reported.append(cap["metadata"]["android.flash.mode"])
-            flash_states_reported.append(cap["metadata"]["android.flash.state"])
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_mode=%d.jpg" % (NAME, f))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb = its.image.compute_image_means(tile)
-            g_means.append(rgb[1])
-
-        assert(flash_modes_reported == [0,1,2])
-        assert(flash_states_reported[0] not in [3,4])
-        assert(flash_states_reported[1] in [3,4])
-        assert(flash_states_reported[2] in [3,4])
-
-        print "G brightnesses:", g_means
-        assert(g_means[1] > g_means[0])
-        assert(g_means[2] > g_means[0])
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_param_noise_reduction.py b/apps/CameraITS/tests/scene1/test_param_noise_reduction.py
deleted file mode 100644
index 618f8a7..0000000
--- a/apps/CameraITS/tests/scene1/test_param_noise_reduction.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that the android.noiseReduction.mode param is applied when set.
-
-    Capture images with the camera dimly lit. Uses a high analog gain to
-    ensure the captured image is noisy.
-
-    Captures three images, for NR off, "fast", and "high quality".
-    Also captures an image with low gain and NR off, and uses the variance
-    of this as the baseline.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # List of variances for Y,U,V.
-    variances = [[],[],[]]
-
-    # Reference (baseline) variance for each of Y,U,V.
-    ref_variance = []
-
-    nr_modes_reported = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        # NR mode 0 with low gain
-        e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
-        req = its.objects.manual_capture_request(s, e)
-        req["android.noiseReduction.mode"] = 0
-        cap = cam.do_capture(req)
-        its.image.write_image(
-                its.image.convert_capture_to_rgb_image(cap),
-                "%s_low_gain.jpg" % (NAME))
-        planes = its.image.convert_capture_to_planes(cap)
-        for j in range(3):
-            img = planes[j]
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            ref_variance.append(its.image.compute_image_variances(tile)[0])
-        print "Ref variances:", ref_variance
-
-        for i in range(3):
-            # NR modes 0, 1, 2 with high gain
-            e, s = its.target.get_target_exposure_combos(cam)["maxSensitivity"]
-            req = its.objects.manual_capture_request(s, e)
-            req["android.noiseReduction.mode"] = i
-            cap = cam.do_capture(req)
-            nr_modes_reported.append(
-                    cap["metadata"]["android.noiseReduction.mode"])
-            its.image.write_image(
-                    its.image.convert_capture_to_rgb_image(cap),
-                    "%s_high_gain_nr=%d.jpg" % (NAME, i))
-            planes = its.image.convert_capture_to_planes(cap)
-            for j in range(3):
-                img = planes[j]
-                tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-                variance = its.image.compute_image_variances(tile)[0]
-                variances[j].append(variance / ref_variance[j])
-        print "Variances with NR mode [0,1,2]:", variances
-
-    # Draw a plot.
-    for j in range(3):
-        pylab.plot(range(3), variances[j], "rgb"[j])
-    matplotlib.pyplot.savefig("%s_plot_variances.png" % (NAME))
-
-    assert(nr_modes_reported == [0,1,2])
-
-    # Check that the variance of the NR=0 image is higher than for the
-    # NR=1 and NR=2 images.
-    for j in range(3):
-        for i in range(1,3):
-            assert(variances[j][i] < variances[j][0])
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_param_sensitivity.py b/apps/CameraITS/tests/scene1/test_param_sensitivity.py
deleted file mode 100644
index c26e9f9..0000000
--- a/apps/CameraITS/tests/scene1/test_param_sensitivity.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Test that the android.sensor.sensitivity parameter is applied.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    NUM_STEPS = 5
-
-    sensitivities = None
-    r_means = []
-    g_means = []
-    b_means = []
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        expt,_ = its.target.get_target_exposure_combos(cam)["midSensitivity"]
-        sens_range = props['android.sensor.info.sensitivityRange']
-        sens_step = (sens_range[1] - sens_range[0]) / float(NUM_STEPS-1)
-        sensitivities = [sens_range[0] + i * sens_step for i in range(NUM_STEPS)]
-
-        for s in sensitivities:
-            req = its.objects.manual_capture_request(s, expt)
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(
-                    img, "%s_iso=%04d.jpg" % (NAME, s))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means = its.image.compute_image_means(tile)
-            r_means.append(rgb_means[0])
-            g_means.append(rgb_means[1])
-            b_means.append(rgb_means[2])
-
-    # Draw a plot.
-    pylab.plot(sensitivities, r_means, 'r')
-    pylab.plot(sensitivities, g_means, 'g')
-    pylab.plot(sensitivities, b_means, 'b')
-    pylab.ylim([0,1])
-    matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
-
-    # Test for pass/fail: check that each shot is brighter than the previous.
-    for means in [r_means, g_means, b_means]:
-        for i in range(len(means)-1):
-            assert(means[i+1] > means[i])
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py b/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
deleted file mode 100644
index fbd452c..0000000
--- a/apps/CameraITS/tests/scene1/test_param_tonemap_mode.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os
-import os.path
-
-def main():
-    """Test that the android.tonemap.mode param is applied.
-
-    Applies different tonemap curves to each R,G,B channel, and checks
-    that the output images are modified as expected.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_RATIO_MIN_DIFF = 0.1
-    THRESHOLD_DIFF_MAX_DIFF = 0.05
-
-    # The HAL3.2 spec requires that curves up to 64 control points in length
-    # must be supported.
-    L = 32
-    LM1 = float(L-1)
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        e /= 2
-
-        # Test 1: that the tonemap curves have the expected effect. Take two
-        # shots, with n in [0,1], where each has a linear tonemap, with the
-        # n=1 shot having a steeper gradient. The gradient for each R,G,B
-        # channel increases (i.e.) R[n=1] should be brighter than R[n=0],
-        # and G[n=1] should be brighter than G[n=0] by a larger margin, etc.
-        rgb_means = []
-
-        for n in [0,1]:
-            req = its.objects.manual_capture_request(s,e)
-            req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = (
-                    sum([[i/LM1, min(1.0,(1+0.5*n)*i/LM1)] for i in range(L)], []))
-            req["android.tonemap.curveGreen"] = (
-                    sum([[i/LM1, min(1.0,(1+1.0*n)*i/LM1)] for i in range(L)], []))
-            req["android.tonemap.curveBlue"] = (
-                    sum([[i/LM1, min(1.0,(1+1.5*n)*i/LM1)] for i in range(L)], []))
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(
-                    img, "%s_n=%d.jpg" %(NAME, n))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means.append(its.image.compute_image_means(tile))
-
-        rgb_ratios = [rgb_means[1][i] / rgb_means[0][i] for i in xrange(3)]
-        print "Test 1: RGB ratios:", rgb_ratios
-        assert(rgb_ratios[0] + THRESHOLD_RATIO_MIN_DIFF < rgb_ratios[1])
-        assert(rgb_ratios[1] + THRESHOLD_RATIO_MIN_DIFF < rgb_ratios[2])
-
-
-        # Test 2: that the length of the tonemap curve (i.e. number of control
-        # points) doesn't affect the output.
-        rgb_means = []
-
-        for size in [32,64]:
-            m = float(size-1)
-            curve = sum([[i/m, i/m] for i in range(size)], [])
-            req = its.objects.manual_capture_request(s,e)
-            req["android.tonemap.mode"] = 0
-            req["android.tonemap.curveRed"] = curve
-            req["android.tonemap.curveGreen"] = curve
-            req["android.tonemap.curveBlue"] = curve
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(
-                    img, "%s_size=%02d.jpg" %(NAME, size))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb_means.append(its.image.compute_image_means(tile))
-
-        rgb_diffs = [rgb_means[1][i] - rgb_means[0][i] for i in xrange(3)]
-        print "Test 2: RGB diffs:", rgb_diffs
-        assert(abs(rgb_diffs[0]) < THRESHOLD_DIFF_MAX_DIFF)
-        assert(abs(rgb_diffs[1]) < THRESHOLD_DIFF_MAX_DIFF)
-        assert(abs(rgb_diffs[2]) < THRESHOLD_DIFF_MAX_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
deleted file mode 100644
index bf0e2ea..0000000
--- a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2014 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.
-
-import its.device
-import its.caps
-import its.objects
-import its.image
-import os.path
-import pylab
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Capture a set of raw images with increasing gains and measure the noise.
-
-    Capture raw-only, in a burst.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # Each shot must be 1% noisier (by the variance metric) than the previous
-    # one.
-    VAR_THRESH = 1.01
-
-    NUM_STEPS = 5
-
-    with its.device.ItsSession() as cam:
-
-        props = cam.get_camera_properties()
-        if not its.caps.raw16(props) or \
-           not its.caps.manual_sensor(props) or \
-           not its.caps.read_3a(props):
-            print "Test skipped"
-            return
-
-        # Expose for the scene with min sensitivity
-        sens_min, sens_max = props['android.sensor.info.sensitivityRange']
-        sens_step = (sens_max - sens_min) / NUM_STEPS
-        s_ae,e_ae,_,_,_  = cam.do_3a(get_results=True)
-        s_e_prod = s_ae * e_ae
-
-        reqs = []
-        settings = []
-        for s in range(sens_min, sens_max, sens_step):
-            e = int(s_e_prod / float(s))
-            req = its.objects.manual_capture_request(s, e)
-            reqs.append(req)
-            settings.append((s,e))
-
-        caps = cam.do_capture(reqs, cam.CAP_RAW)
-
-        variances = []
-        for i,cap in enumerate(caps):
-            (s,e) = settings[i]
-
-            # Measure the variance. Each shot should be noisier than the
-            # previous shot (as the gain is increasing).
-            plane = its.image.convert_capture_to_planes(cap, props)[1]
-            tile = its.image.get_image_patch(plane, 0.45,0.45,0.1,0.1)
-            var = its.image.compute_image_variances(tile)[0]
-            variances.append(var)
-
-            img = its.image.convert_capture_to_rgb_image(cap, props=props)
-            its.image.write_image(img, "%s_s=%05d_var=%f.jpg" % (NAME,s,var))
-            print "s=%d, e=%d, var=%e"%(s,e,var)
-
-        pylab.plot(range(len(variances)), variances)
-        matplotlib.pyplot.savefig("%s_variances.png" % (NAME))
-
-        # Test that each shot is noisier than the previous one.
-        for i in range(len(variances) - 1):
-            assert(variances[i] < variances[i+1] / VAR_THRESH)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
deleted file mode 100644
index 8e36219..0000000
--- a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2014 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.
-
-import its.device
-import its.caps
-import its.objects
-import its.image
-import os.path
-import pylab
-import matplotlib
-import matplotlib.pyplot
-
-def main():
-    """Capture a set of raw images with increasing gains and measure the noise.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # Each shot must be 1% noisier (by the variance metric) than the previous
-    # one.
-    VAR_THRESH = 1.01
-
-    NUM_STEPS = 5
-
-    with its.device.ItsSession() as cam:
-
-        props = cam.get_camera_properties()
-        if (not its.caps.raw16(props) or
-            not its.caps.manual_sensor(props) or
-            not its.caps.read_3a(props)):
-            print "Test skipped"
-            return
-
-        # Expose for the scene with min sensitivity
-        sens_min, sens_max = props['android.sensor.info.sensitivityRange']
-        sens_step = (sens_max - sens_min) / NUM_STEPS
-        s_ae,e_ae,_,_,_  = cam.do_3a(get_results=True)
-        s_e_prod = s_ae * e_ae
-
-        variances = []
-        for s in range(sens_min, sens_max, sens_step):
-
-            e = int(s_e_prod / float(s))
-            req = its.objects.manual_capture_request(s, e)
-
-            # Capture raw+yuv, but only look at the raw.
-            cap,_ = cam.do_capture(req, cam.CAP_RAW_YUV)
-
-            # Measure the variance. Each shot should be noisier than the
-            # previous shot (as the gain is increasing).
-            plane = its.image.convert_capture_to_planes(cap, props)[1]
-            tile = its.image.get_image_patch(plane, 0.45,0.45,0.1,0.1)
-            var = its.image.compute_image_variances(tile)[0]
-            variances.append(var)
-
-            img = its.image.convert_capture_to_rgb_image(cap, props=props)
-            its.image.write_image(img, "%s_s=%05d_var=%f.jpg" % (NAME,s,var))
-            print "s=%d, e=%d, var=%e"%(s,e,var)
-
-        pylab.plot(range(len(variances)), variances)
-        matplotlib.pyplot.savefig("%s_variances.png" % (NAME))
-
-        # Test that each shot is noisier than the previous one.
-        for i in range(len(variances) - 1):
-            assert(variances[i] < variances[i+1] / VAR_THRESH)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
deleted file mode 100644
index 7af51c5..0000000
--- a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import os.path
-import numpy
-
-def main():
-    """Test a sequence of shots with different tonemap curves.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # There should be 3 identical frames followed by a different set of
-    # 3 identical frames.
-    MAX_SAME_DELTA = 0.01
-    MIN_DIFF_DELTA = 0.10
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if (not its.caps.manual_sensor(props) or
-            not its.caps.manual_post_proc(props)):
-            print "Test skipped"
-            return
-
-        sens, exp_time, _,_,_ = cam.do_3a(do_af=False,get_results=True)
-
-        means = []
-
-        # Capture 3 manual shots with a linear tonemap.
-        req = its.objects.manual_capture_request(sens, exp_time, True)
-        for i in [0,1,2]:
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_i=%d.jpg" % (NAME, i))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            means.append(tile.mean(0).mean(0))
-
-        # Capture 3 manual shots with the default tonemap.
-        req = its.objects.manual_capture_request(sens, exp_time, False)
-        for i in [3,4,5]:
-            cap = cam.do_capture(req)
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_i=%d.jpg" % (NAME, i))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            means.append(tile.mean(0).mean(0))
-
-        # Compute the delta between each consecutive frame pair.
-        deltas = [numpy.max(numpy.fabs(means[i+1]-means[i])) \
-                  for i in range(len(means)-1)]
-        print "Deltas between consecutive frames:", deltas
-
-        assert(all([abs(deltas[i]) < MAX_SAME_DELTA for i in [0,1,3,4]]))
-        assert(abs(deltas[2]) > MIN_DIFF_DELTA)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
deleted file mode 100644
index 2367ca2..0000000
--- a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright 2013 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-import math
-
-def main():
-    """Test that the reported sizes and formats for image capture work.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_MAX_RMS_DIFF = 0.03
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        # Use a manual request with a linear tonemap so that the YUV and JPEG
-        # should look the same (once converted by the its.image module).
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
-
-        rgbs = []
-
-        for size in its.objects.get_available_output_sizes("yuv", props):
-            out_surface = {"width":size[0], "height":size[1], "format":"yuv"}
-            cap = cam.do_capture(req, out_surface)
-            assert(cap["format"] == "yuv")
-            assert(cap["width"] == size[0])
-            assert(cap["height"] == size[1])
-            print "Captured YUV %dx%d" % (cap["width"], cap["height"])
-            img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_yuv_w%d_h%d.jpg"%(
-                    NAME,size[0],size[1]))
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb = its.image.compute_image_means(tile)
-            rgbs.append(rgb)
-
-        for size in its.objects.get_available_output_sizes("jpg", props):
-            out_surface = {"width":size[0], "height":size[1], "format":"jpg"}
-            cap = cam.do_capture(req, out_surface)
-            assert(cap["format"] == "jpeg")
-            assert(cap["width"] == size[0])
-            assert(cap["height"] == size[1])
-            img = its.image.decompress_jpeg_to_rgb_image(cap["data"])
-            its.image.write_image(img, "%s_jpg_w%d_h%d.jpg"%(
-                    NAME,size[0], size[1]))
-            assert(img.shape[0] == size[1])
-            assert(img.shape[1] == size[0])
-            assert(img.shape[2] == 3)
-            print "Captured JPEG %dx%d" % (cap["width"], cap["height"])
-            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-            rgb = its.image.compute_image_means(tile)
-            rgbs.append(rgb)
-
-        max_diff = 0
-        rgb0 = rgbs[0]
-        for rgb1 in rgbs[1:]:
-            rms_diff = math.sqrt(
-                    sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
-            max_diff = max(max_diff, rms_diff)
-        print "Max RMS difference:", max_diff
-        assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_dng.py b/apps/CameraITS/tests/scene1/test_yuv_plus_dng.py
deleted file mode 100644
index 4924c7b..0000000
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_dng.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import os.path
-
-def main():
-    """Test capturing a single frame as both DNG and YUV outputs.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if (not its.caps.raw(props) or
-            not its.caps.read_3a(props)):
-            print "Test skipped"
-            return
-
-        cam.do_3a()
-
-        req = its.objects.auto_capture_request()
-        cap_dng, cap_yuv = cam.do_capture(req, cam.CAP_DNG_YUV)
-
-        img = its.image.convert_capture_to_rgb_image(cap_yuv)
-        its.image.write_image(img, "%s.jpg" % (NAME))
-
-        with open("%s.dng"%(NAME), "wb") as f:
-            f.write(cap_dng["data"])
-
-        # No specific pass/fail check; test is assumed to have succeeded if
-        # it completes.
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py b/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
deleted file mode 100644
index 15aa17c..0000000
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-import math
-
-def main():
-    """Test capturing a single frame as both YUV and JPEG outputs.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_MAX_RMS_DIFF = 0.01
-
-    fmt_yuv =  {"format":"yuv"}
-    fmt_jpeg = {"format":"jpeg"}
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if not its.caps.compute_target_exposure(props):
-            print "Test skipped"
-            return
-
-        # Use a manual request with a linear tonemap so that the YUV and JPEG
-        # should look the same (once converted by the its.image module).
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
-
-        cap_yuv, cap_jpeg = cam.do_capture(req, [fmt_yuv, fmt_jpeg])
-
-        img = its.image.convert_capture_to_rgb_image(cap_yuv, True)
-        its.image.write_image(img, "%s_yuv.jpg" % (NAME))
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        rgb0 = its.image.compute_image_means(tile)
-
-        img = its.image.convert_capture_to_rgb_image(cap_jpeg, True)
-        its.image.write_image(img, "%s_jpeg.jpg" % (NAME))
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        rgb1 = its.image.compute_image_means(tile)
-
-        rms_diff = math.sqrt(
-                sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
-        print "RMS difference:", rms_diff
-        assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
deleted file mode 100644
index 7a345c9..0000000
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-import math
-
-def main():
-    """Test capturing a single frame as both RAW and YUV outputs.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_MAX_RMS_DIFF = 0.02
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-        if (not its.caps.compute_target_exposure(props) or
-            not its.caps.raw16(props)):
-            print "Test skipped"
-            return
-
-        # Use a manual request with a linear tonemap so that the YUV and RAW
-        # should look the same (once converted by the its.image module).
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
-
-        cap_raw, cap_yuv = cam.do_capture(req, cam.CAP_RAW_YUV)
-
-        img = its.image.convert_capture_to_rgb_image(cap_yuv)
-        its.image.write_image(img, "%s_yuv.jpg" % (NAME), True)
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        rgb0 = its.image.compute_image_means(tile)
-
-        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the
-        # tile appropriately.
-        img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
-        its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
-        tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05)
-        rgb1 = its.image.compute_image_means(tile)
-
-        rms_diff = math.sqrt(
-                sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
-        print "RMS difference:", rms_diff
-        assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
deleted file mode 100644
index 15612c5..0000000
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2014 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.
-
-import its.image
-import its.caps
-import its.device
-import its.objects
-import its.target
-import os.path
-import math
-
-def main():
-    """Test capturing a single frame as both RAW10 and YUV outputs.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    THRESHOLD_MAX_RMS_DIFF = 0.02
-
-    with its.device.ItsSession() as cam:
-        props = cam.get_camera_properties()
-
-        if (not its.caps.compute_target_exposure(props) or
-            not its.caps.raw10(props)):
-            print "Test skipped"
-            return
-
-        # Use a manual request with a linear tonemap so that the YUV and RAW
-        # should look the same (once converted by the its.image module).
-        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
-
-        cap_raw, cap_yuv = cam.do_capture(req,
-                [{"format":"raw10"}, {"format":"yuv"}])
-
-        img = its.image.convert_capture_to_rgb_image(cap_yuv)
-        its.image.write_image(img, "%s_yuv.jpg" % (NAME), True)
-        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
-        rgb0 = its.image.compute_image_means(tile)
-
-        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the
-        # tile appropriately.
-        img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
-        its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
-        tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05)
-        rgb1 = its.image.compute_image_means(tile)
-
-        rms_diff = math.sqrt(
-                sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
-        print "RMS difference:", rms_diff
-        assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/tutorial.py b/apps/CameraITS/tests/tutorial.py
deleted file mode 100644
index 1b1999e..0000000
--- a/apps/CameraITS/tests/tutorial.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# Copyright 2014 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.
-
-# --------------------------------------------------------------------------- #
-# The Google Python style guide should be used for scripts:                   #
-# http://google-styleguide.googlecode.com/svn/trunk/pyguide.html              #
-# --------------------------------------------------------------------------- #
-
-# The ITS modules that are in the pymodules/its/ directory. To see formatted
-# docs, use the "pydoc" command:
-#
-# > pydoc its.image
-#
-import its.image
-import its.device
-import its.objects
-import its.target
-
-# Standard Python modules.
-import os.path
-import pprint
-import math
-
-# Modules from the numpy, scipy, and matplotlib libraries. These are used for
-# the image processing code, and images are represented as numpy arrays.
-import pylab
-import numpy
-import matplotlib
-import matplotlib.pyplot
-
-# Each script has a "main" function.
-def main():
-
-    # Each script has a string description of what it does. This is the first
-    # entry inside the main function.
-    """Tutorial script to show how to use the ITS infrastructure.
-    """
-
-    # A convention in each script is to use the filename (without the extension)
-    # as the name of the test, when printing results to the screen or dumping
-    # files.
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    # The standard way to open a session with a connected camera device. This
-    # creates a cam object which encapsulates the session and which is active
-    # within the scope of the "with" block; when the block exits, the camera
-    # session is closed.
-    with its.device.ItsSession() as cam:
-
-        # Get the static properties of the camera device. Returns a Python
-        # associative array object; print it to the console.
-        props = cam.get_camera_properties()
-        pprint.pprint(props)
-
-        # Grab a YUV frame with manual exposure of sensitivity = 200, exposure
-        # duration = 50ms.
-        req = its.objects.manual_capture_request(200, 50*1000*1000)
-        cap = cam.do_capture(req)
-
-        # Print the properties of the captured frame; width and height are
-        # integers, and the metadata is a Python associative array object.
-        print "Captured image width:", cap["width"]
-        print "Captured image height:", cap["height"]
-        pprint.pprint(cap["metadata"])
-
-        # The captured image is YUV420. Convert to RGB, and save as a file.
-        rgbimg = its.image.convert_capture_to_rgb_image(cap)
-        its.image.write_image(rgbimg, "%s_rgb_1.jpg" % (NAME))
-
-        # Can also get the Y,U,V planes separately; save these to greyscale
-        # files.
-        yimg,uimg,vimg = its.image.convert_capture_to_planes(cap)
-        its.image.write_image(yimg, "%s_y_plane_1.jpg" % (NAME))
-        its.image.write_image(uimg, "%s_u_plane_1.jpg" % (NAME))
-        its.image.write_image(vimg, "%s_v_plane_1.jpg" % (NAME))
-
-        # Run 3A on the device. In this case, just use the entire image as the
-        # 3A region, and run each of AWB,AE,AF. Can also change the region and
-        # specify independently for each of AE,AWB,AF whether it should run.
-        #
-        # NOTE: This may fail, if the camera isn't pointed at a reasonable
-        # target scene. If it fails, the script will end. The logcat messages
-        # can be inspected to see the status of 3A running on the device.
-        #
-        # > adb logcat -s 'ItsService:v'
-        #
-        # If this keeps on failing, try also rebooting the device before
-        # running the test.
-        sens, exp, gains, xform, focus = cam.do_3a(get_results=True)
-        print "AE: sensitivity %d, exposure %dms" % (sens, exp/1000000.0)
-        print "AWB: gains", gains, "transform", xform
-        print "AF: distance", focus
-
-        # Grab a new manual frame, using the 3A values, and convert it to RGB
-        # and save it to a file too. Note that the "req" object is just a
-        # Python dictionary that is pre-populated by the its.objets module
-        # functions (in this case a default manual capture), and the key/value
-        # pairs in the object can be used to set any field of the capture
-        # request. Here, the AWB gains and transform (CCM) are being used.
-        # Note that the CCM transform is in a rational format in capture
-        # requests, meaning it is an object with integer numerators and
-        # denominators. The 3A routine returns simple floats instead, however,
-        # so a conversion from float to rational must be performed.
-        req = its.objects.manual_capture_request(sens, exp)
-        xform_rat = its.objects.float_to_rational(xform)
-
-        req["android.colorCorrection.transform"] = xform_rat
-        req["android.colorCorrection.gains"] = gains
-        cap = cam.do_capture(req)
-        rgbimg = its.image.convert_capture_to_rgb_image(cap)
-        its.image.write_image(rgbimg, "%s_rgb_2.jpg" % (NAME))
-
-        # Print out the actual capture request object that was used.
-        pprint.pprint(req)
-
-        # Images are numpy arrays. The dimensions are (h,w,3) when indexing,
-        # in the case of RGB images. Greyscale images are (h,w,1). Pixels are
-        # generally float32 values in the [0,1] range, however some of the
-        # helper functions in its.image deal with the packed YUV420 and other
-        # formats of images that come from the device (and convert them to
-        # float32).
-        # Print the dimensions of the image, and the top-left pixel value,
-        # which is an array of 3 floats.
-        print "RGB image dimensions:", rgbimg.shape
-        print "RGB image top-left pixel:", rgbimg[0,0]
-
-        # Grab a center tile from the image; this returns a new image. Save
-        # this tile image. In this case, the tile is the middle 10% x 10%
-        # rectangle.
-        tile = its.image.get_image_patch(rgbimg, 0.45, 0.45, 0.1, 0.1)
-        its.image.write_image(tile, "%s_rgb_2_tile.jpg" % (NAME))
-
-        # Compute the mean values of the center tile image.
-        rgb_means = its.image.compute_image_means(tile)
-        print "RGB means:", rgb_means
-
-        # Apply a lookup table to the image, and save the new version. The LUT
-        # is basically a tonemap, and can be used to implement a gamma curve.
-        # In this case, the LUT is used to double the value of each pixel.
-        lut = numpy.array([2*i for i in xrange(65536)])
-        rgbimg_lut = its.image.apply_lut_to_image(rgbimg, lut)
-        its.image.write_image(rgbimg_lut, "%s_rgb_2_lut.jpg" % (NAME))
-
-        # Apply a 3x3 matrix to the image, and save the new version. The matrix
-        # is a numpy array, in row major order, and the pixel values are right-
-        # multipled to it (when considered as column vectors). The example
-        # matrix here just boosts the blue channel by 10%.
-        mat = numpy.array([[1, 0, 0  ],
-                           [0, 1, 0  ],
-                           [0, 0, 1.1]])
-        rgbimg_mat = its.image.apply_matrix_to_image(rgbimg, mat)
-        its.image.write_image(rgbimg_mat, "%s_rgb_2_mat.jpg" % (NAME))
-
-        # Compute a histogram of the luma image, in 256 buckeits.
-        yimg,_,_ = its.image.convert_capture_to_planes(cap)
-        hist,_ = numpy.histogram(yimg*255, 256, (0,256))
-
-        # Plot the histogram using matplotlib, and save as a PNG image.
-        pylab.plot(range(256), hist.tolist())
-        pylab.xlabel("Luma DN")
-        pylab.ylabel("Pixel count")
-        pylab.title("Histogram of luma channel of captured image")
-        matplotlib.pyplot.savefig("%s_histogram.png" % (NAME))
-
-        # Capture a frame to be returned as a JPEG. Load it as an RGB image,
-        # then save it back as a JPEG.
-        cap = cam.do_capture(req, cam.CAP_JPEG)
-        rgbimg = its.image.convert_capture_to_rgb_image(cap)
-        its.image.write_image(rgbimg, "%s_jpg.jpg" % (NAME))
-        r,g,b = its.image.convert_capture_to_planes(cap)
-        its.image.write_image(r, "%s_r.jpg" % (NAME))
-
-# This is the standard boilerplate in each test that allows the script to both
-# be executed directly and imported as a module.
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tools/compute_dng_noise_model.py b/apps/CameraITS/tools/compute_dng_noise_model.py
deleted file mode 100644
index e089ffc..0000000
--- a/apps/CameraITS/tools/compute_dng_noise_model.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright 2014 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.
-
-import its.device
-import its.objects
-import its.image
-import pprint
-import pylab
-import os.path
-import matplotlib
-import matplotlib.pyplot
-import numpy
-import math
-
-def main():
-    """Compute the DNG noise model from a color checker chart.
-
-    TODO: Make this more robust; some manual futzing may be needed.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-
-        props = cam.get_camera_properties()
-
-        white_level = float(props['android.sensor.info.whiteLevel'])
-        black_levels = props['android.sensor.blackLevelPattern']
-        idxs = its.image.get_canonical_cfa_order(props)
-        black_levels = [black_levels[i] for i in idxs]
-
-        # Expose for the scene with min sensitivity
-        sens_min, sens_max = props['android.sensor.info.sensitivityRange']
-        s_ae,e_ae,awb_gains,awb_ccm,_  = cam.do_3a(get_results=True)
-        s_e_prod = s_ae * e_ae
-
-        # Make the image brighter since the script looks at linear Bayer
-        # raw patches rather than gamma-encoded YUV patches (and the AE
-        # probably under-exposes a little for this use-case).
-        s_e_prod *= 2
-
-        # Capture raw frames across the full sensitivity range.
-        NUM_SENS_STEPS = 15
-        sens_step = int((sens_max - sens_min - 1) / float(NUM_SENS_STEPS))
-        reqs = []
-        sens = []
-        for s in range(sens_min, sens_max, sens_step):
-            e = int(s_e_prod / float(s))
-            req = its.objects.manual_capture_request(s, e)
-            req["android.colorCorrection.transform"] = \
-                    its.objects.float_to_rational(awb_ccm)
-            req["android.colorCorrection.gains"] = awb_gains
-            reqs.append(req)
-            sens.append(s)
-
-        caps = cam.do_capture(reqs, cam.CAP_RAW)
-
-        # A list of the (x,y) coords of the center pixel of a collection of
-        # patches of a color checker chart. Each patch should be uniform,
-        # however the actual color doesn't matter. Note that the coords are
-        # relative to the *converted* RGB image, which is 1/2 x 1/2 of the
-        # full size; convert back to full.
-        img = its.image.convert_capture_to_rgb_image(caps[0], props=props)
-        patches = its.image.get_color_checker_chart_patches(img, NAME+"_debug")
-        patches = [(2*x,2*y) for (x,y) in sum(patches,[])]
-
-        lines = []
-        for (s,cap) in zip(sens,caps):
-            # For each capture, compute the mean value in each patch, for each
-            # Bayer plane; discard patches where pixels are close to clamped.
-            # Also compute the variance.
-            CLAMP_THRESH = 0.2
-            planes = its.image.convert_capture_to_planes(cap, props)
-            points = []
-            for i,plane in enumerate(planes):
-                plane = (plane * white_level - black_levels[i]) / (
-                        white_level - black_levels[i])
-                for j,(x,y) in enumerate(patches):
-                    tile = plane[y/2-16:y/2+16:,x/2-16:x/2+16:,::]
-                    mean = its.image.compute_image_means(tile)[0]
-                    var = its.image.compute_image_variances(tile)[0]
-                    if (mean > CLAMP_THRESH and mean < 1.0-CLAMP_THRESH):
-                        # Each point is a (mean,variance) tuple for a patch;
-                        # for a given ISO, there should be a linear
-                        # relationship between these values.
-                        points.append((mean,var))
-
-            # Fit a line to the points, with a line equation: y = mx + b.
-            # This line is the relationship between mean and variance (i.e.)
-            # between signal level and noise, for this particular sensor.
-            # In the DNG noise model, the gradient (m) is "S", and the offset
-            # (b) is "O".
-            points.sort()
-            xs = [x for (x,y) in points]
-            ys = [y for (x,y) in points]
-            m,b = numpy.polyfit(xs, ys, 1)
-            lines.append((s,m,b))
-            print s, "->", m, b
-
-            # TODO: Clean up these checks (which currently fail in some cases).
-            # Some sanity checks:
-            # * Noise levels should increase with brightness.
-            # * Extrapolating to a black image, the noise should be positive.
-            # Basically, the "b" value should correspnd to the read noise,
-            # which is the noise level if the sensor was operating in zero
-            # light.
-            #assert(m > 0)
-            #assert(b >= 0)
-
-            # Draw a plot.
-            pylab.plot(xs, ys, 'r')
-            pylab.plot([0,xs[-1]],[b,m*xs[-1]+b],'b')
-            matplotlib.pyplot.savefig("%s_plot_mean_vs_variance.png" % (NAME))
-
-        # Now fit a line across the (m,b) line parameters for each sensitivity.
-        # The gradient (m) params are fit to the "S" line, and the offset (b)
-        # params are fit to the "O" line, both as a function of sensitivity.
-        gains = [d[0] for d in lines]
-        Ss = [d[1] for d in lines]
-        Os = [d[2] for d in lines]
-        mS,bS = numpy.polyfit(gains, Ss, 1)
-        mO,bO = numpy.polyfit(gains, Os, 1)
-
-        # Plot curve "O" as 10x, so it fits in the same scale as curve "S".
-        pylab.plot(gains, [10*o for o in Os], 'r')
-        pylab.plot([gains[0],gains[-1]],
-                [10*mO*gains[0]+10*bO, 10*mO*gains[-1]+10*bO], 'b')
-        pylab.plot(gains, Ss, 'r')
-        pylab.plot([gains[0],gains[-1]], [mS*gains[0]+bS, mS*gains[-1]+bS], 'b')
-        matplotlib.pyplot.savefig("%s_plot_S_O.png" % (NAME))
-
-        print """
-        /* Generated test code to dump a table of data for external validation
-         * of the noise model parameters.
-         */
-        #include <stdio.h>
-        #include <assert.h>
-        double compute_noise_model_entry_S(int sens);
-        double compute_noise_model_entry_O(int sens);
-        int main(void) {
-            int sens;
-            for (sens = %d; sens <= %d; sens += 100) {
-                double o = compute_noise_model_entry_O(sens);
-                double s = compute_noise_model_entry_S(sens);
-                printf("%%d,%%lf,%%lf\\n", sens, o, s);
-            }
-            return 0;
-        }
-
-        /* Generated functions to map a given sensitivity to the O and S noise
-         * model parameters in the DNG noise model.
-         */
-        double compute_noise_model_entry_S(int sens) {
-            double s = %e * sens + %e;
-            return s < 0.0 ? 0.0 : s;
-        }
-        double compute_noise_model_entry_O(int sens) {
-            double o = %e * sens + %e;
-            return o < 0.0 ? 0.0 : o;
-        }
-        """%(sens_min,sens_max,mS,bS,mO,bO)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tools/config.py b/apps/CameraITS/tools/config.py
deleted file mode 100644
index 6e83412..0000000
--- a/apps/CameraITS/tools/config.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2013 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.
-
-import its.device
-import its.target
-import sys
-
-def main():
-    """Set the target exposure.
-
-    This program is just a wrapper around the its.target module, to allow the
-    functions in it to be invoked from the command line.
-
-    Usage:
-        python config.py        - Measure the target exposure, and cache it.
-        python config.py EXP    - Hard-code (and cache) the target exposure.
-
-    The "reboot" or "reboot=<N>" and "camera=<N>" arguments may also be
-    provided, just as with all the test scripts. The "target" argument is
-    may also be provided but it has no effect on this script since the cached
-    exposure value is cleared regardless.
-
-    If no exposure value is provided, the camera will be used to measure
-    the scene and set a level that will result in the luma (with linear
-    tonemap) being at the 0.5 level. This requires camera 3A and capture
-    to be functioning.
-
-    For bring-up purposes, the exposure value may be manually set to a hard-
-    coded value, without the camera having to be able to perform 3A (or even
-    capture a shot reliably).
-    """
-
-    # Command line args, ignoring any args that will be passed down to the
-    # ItsSession constructor.
-    args = [s for s in sys.argv if s[:6] not in \
-            ["reboot", "camera", "target", "noinit"]]
-
-    if len(args) == 1:
-        with its.device.ItsSession() as cam:
-            # Automatically measure target exposure.
-            its.target.clear_cached_target_exposure()
-            exposure = its.target.get_target_exposure(cam)
-    elif len(args) == 2:
-        # Hard-code the target exposure.
-        exposure = int(args[1])
-        its.target.set_hardcoded_exposure(exposure)
-    else:
-        print "Usage: python %s [EXPOSURE]"
-        sys.exit(0)
-    print "New target exposure set to", exposure
-    print "This corresponds to %dms at ISO 100" % int(exposure/100/1000000.0)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
deleted file mode 100644
index 4677331..0000000
--- a/apps/CameraITS/tools/run_all_tests.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2014 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.
-
-import os
-import os.path
-import tempfile
-import subprocess
-import time
-import sys
-
-def main():
-    """Run all the automated tests, saving intermediate files, and producing
-    a summary/report of the results.
-
-    Script should be run from the top-level CameraITS directory.
-    """
-
-    # Get all the scene0 and scene1 tests, which can be run using the same
-    # physical setup.
-    scenes = ["scene0", "scene1"]
-    tests = []
-    for d in scenes:
-        tests += [(d,s[:-3],os.path.join("tests", d, s))
-                  for s in os.listdir(os.path.join("tests",d))
-                  if s[-3:] == ".py"]
-    tests.sort()
-
-    # Make output directories to hold the generated files.
-    topdir = tempfile.mkdtemp()
-    for d in scenes:
-        os.mkdir(os.path.join(topdir, d))
-    print "Saving output files to:", topdir, "\n"
-
-    # Run each test, capturing stdout and stderr.
-    numpass = 0
-    for (scene,testname,testpath) in tests:
-        cmd = ['python', os.path.join(os.getcwd(),testpath)] + sys.argv[1:]
-        outdir = os.path.join(topdir,scene)
-        outpath = os.path.join(outdir,testname+"_stdout.txt")
-        errpath = os.path.join(outdir,testname+"_stderr.txt")
-        t0 = time.time()
-        with open(outpath,"w") as fout, open(errpath,"w") as ferr:
-            retcode = subprocess.call(cmd,stderr=ferr,stdout=fout,cwd=outdir)
-        t1 = time.time()
-        print "%s %s/%s [%.1fs]" % (
-                "PASS" if retcode==0 else "FAIL", scene, testname, t1-t0)
-        if retcode == 0:
-            numpass += 1
-
-    print "\n%d / %d tests passed (%.1f%%)" % (
-            numpass, len(tests), 100.0*float(numpass)/len(tests))
-
-if __name__ == '__main__':
-    main()
-