Merge "Initial interface for the burst module." into ub-camera-haleakala
diff --git a/src/com/android/camera/burst/BurstArtifact.java b/src/com/android/camera/burst/BurstArtifact.java
new file mode 100644
index 0000000..4fbe566
--- /dev/null
+++ b/src/com/android/camera/burst/BurstArtifact.java
@@ -0,0 +1,44 @@
+/*
+ * 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.camera.burst;
+
+import java.util.List;
+
+/**
+ * Represents an artifact generated by burst.
+ * <p/>
+ * An artifact consists of media items of the same type. An artifact can be a
+ * collection of images, collages, GIFs or any other media item.
+ * <p/>
+ * The type of artifact is returned by {@link #getType()}.
+ */
+public interface BurstArtifact {
+    /**
+     * Gets all media items in the artifact.
+     *
+     * @return all media items in the artifact.
+     */
+    public List<BurstMediaItem> getMediaItems();
+
+    /**
+     * Returns the type name of this artifact.
+     */
+    public String getType();
+
+    /**
+     * Returns the localized name of this artifact.
+     */
+    public String getLocalizedName();
+}
\ No newline at end of file
diff --git a/src/com/android/camera/burst/BurstConfiguration.java b/src/com/android/camera/burst/BurstConfiguration.java
new file mode 100644
index 0000000..08688e3
--- /dev/null
+++ b/src/com/android/camera/burst/BurstConfiguration.java
@@ -0,0 +1,78 @@
+/*
+ * 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.camera.burst;
+
+import android.hardware.camera2.TotalCaptureResult;
+
+/**
+ * The burst configuration parameters.
+ */
+public interface BurstConfiguration {
+    /**
+     * The eviction strategy of the internal Camera image buffer.
+     * <p/>
+     * For a burst the Camera maintains an internal image buffer. This image
+     * buffer has limited memory and old images need to be evicted for storing
+     * new images. The eviction handler encapsulates the eviction strategy that
+     * the Camera uses to evict frames.
+     */
+    public interface EvictionHandler {
+        /**
+         * Return the timestamp of the image that should be dropped.
+         * <p/>
+         * This method is called when the internal image buffer is out of
+         * capacity and needs to drop an image from the buffer.
+         * <p/>
+         * This should return one of the timestamps passed into
+         * {@link #onFrameInserted(long, TotalCaptureResult)}, and which has not
+         * yet been dropped.
+         *
+         * @return the timestamp of the frame to drop.
+         */
+        long selectFrameToDrop();
+
+        /**
+         * Called when the capture result for a frame is available.
+         *
+         * @param timestamp the timestamp of the frame, this frame may or may
+         *            not be present in the image buffer.
+         * @param captureResult the capture result of the image.
+         */
+        void onFrameCaptureResultAvailable(long timestamp,
+                TotalCaptureResult captureResult);
+
+        /**
+         * Called when an image is inserted in the image buffer.
+         *
+         * @param timestamp the timestamp of the inserted frame in the image
+         *            buffer.
+         */
+        void onFrameInserted(long timestamp);
+
+        /**
+         * Called when a frame is dropped from the image buffer.
+         *
+         * @param timestamp the timestamp of the dropped frame.
+         */
+        void onFrameDropped(long timestamp);
+    }
+
+    /**
+     * Return the eviction handler associated with this instance of burst.
+     */
+    public EvictionHandler getEvictionHandler();
+}
diff --git a/src/com/android/camera/burst/BurstController.java b/src/com/android/camera/burst/BurstController.java
new file mode 100644
index 0000000..fdf040b
--- /dev/null
+++ b/src/com/android/camera/burst/BurstController.java
@@ -0,0 +1,91 @@
+/*
+ * 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.camera.burst;
+
+/**
+ * Controls the interactions with burst.
+ * <p/>
+ * A burst consists of a series of images. Burst module controls the internal
+ * camera buffer and keeps images that best represent a burst at any given point
+ * in time. The burst module makes decisions on which frames to keep by
+ * analyzing low-res preview frames and keeping the corresponding high-res
+ * images in the camera internal buffer. At the end of the burst, the burst
+ * module retrieves results from the internal camera buffer and can do post
+ * processing on the results.
+ * <p/>
+ * Camera hooks up the frame consumer for the burst module returned by
+ * {@link #getPreviewFrameConsumer()} and initializes the burst module by
+ * calling {@link #startBurst()}. The returned configuration for initialized
+ * burst module contains the eviction strategy for the internal camera buffer.
+ * This {@link BurstConfiguration#getEvictionHandler()} is then used by camera
+ * to decide which frames to keep and which to reject.
+ * <p/>
+ * Once burst finishes, camera calls the {@link #stopBurst(ResultsAccessor)} to
+ * let the burst module retrieve burst results from the internal buffer. Results
+ * of burst can be extracted by calling the
+ * {@link ResultsAccessor#extractImage(long)} method. Once extraction is
+ * finished the burst module should call {@link ResultsAccessor#close()} method
+ * to let camera free resources used by burst.
+ * <p/>
+ * Once post processing is complete, the burst module returns the final results
+ * by calling {@link BurstResultsListener#onBurstCompleted(BurstResult)} method.
+ */
+public interface BurstController {
+
+    /**
+     * Starts the burst.
+     *
+     * @return the configuration of burst that can be used to control the
+     *         ongoing burst.
+     */
+    public BurstConfiguration startBurst();
+
+    /**
+     * Stops the burst.
+     *
+     * @param resultsAccessor an instance of results accessor that can be used
+     *            to query the results of the burst.
+     */
+    public void stopBurst(ResultsAccessor resultsAccessor);
+
+    /**
+     * Called when size of the preview changes.
+     * <p>
+     * Preview size can change in case of rotation or switching cameras.
+     *
+     * @param width the width of the preview.
+     * @param height the height of the preview.
+     */
+    public void onPreviewSizeChanged(int width, int height);
+
+    /**
+     * Called when the orientation of the preview changes.
+     *
+     * @param orientation orientation of preview in degrees.
+     * @param isMirrored true if preview is mirrored.
+     */
+    public void onOrientationChanged(int orientation, boolean isMirrored);
+
+    /**
+     * Get the consumer for preview frames.
+     * <p/>
+     * Burst module streams preview frames and selects "good" frames by
+     * analyzing preview frames. Preview frames should have exact timestamps as
+     * the high-res images held in the internal image buffer.
+     */
+   // TODO: Change the return value to FrameDistributor.FrameConsumer is
+   // checked in.
+   public Object getPreviewFrameConsumer();
+}
diff --git a/src/com/android/camera/burst/BurstImage.java b/src/com/android/camera/burst/BurstImage.java
new file mode 100644
index 0000000..cc5d4fd
--- /dev/null
+++ b/src/com/android/camera/burst/BurstImage.java
@@ -0,0 +1,58 @@
+/*
+ * 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.camera.burst;
+
+import android.hardware.camera2.TotalCaptureResult;
+
+/**
+ * Holds image data and meta-data for a single image that is part of a burst.
+ * <p/>
+ * Bursts are an ordered collection of images. This class holds the data for one
+ * of these images.
+ */
+public class BurstImage {
+    /**
+     * The bytes of image that can be decoded by
+     * {@link android.graphics.BitmapFactory#decodeByteArray(byte[],
+     * int, int, android.graphics.BitmapFactory.Options)}.
+     */
+    // TODO: Fix this and use a URI here for saved image.
+    public byte[] data;
+
+    /**
+     * The timestamp of the image measured in nanoseconds.
+     * <p/>
+     * The timestamp is monotonically increasing. It is mostly useful for
+     * determining time offsets between images in burst. The zero-point and the
+     * value of the timestamp cannot be in general compared between two
+     * different bursts.
+     */
+    public long timestamp;
+
+    /**
+     * The width of the image in pixels.
+     */
+    public int width;
+
+    /**
+     * The height of the image in pixels.
+     */
+    public int height;
+
+    /**
+     * The capture result associated with the image.
+     */
+    public TotalCaptureResult captureResult;
+}
diff --git a/src/com/android/camera/burst/BurstMediaItem.java b/src/com/android/camera/burst/BurstMediaItem.java
new file mode 100644
index 0000000..dce4df3
--- /dev/null
+++ b/src/com/android/camera/burst/BurstMediaItem.java
@@ -0,0 +1,70 @@
+/*
+ * 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.camera.burst;
+
+/**
+ * Represents a media item generated by a burst.
+ */
+public interface BurstMediaItem {
+    /**
+     * Gets width of the media in pixels.
+     *
+     * @return width of the media in pixels
+     */
+    public int getWidth();
+
+    /**
+     * Gets height of the media in pixels.
+     *
+     * @return height of the media in pixels
+     */
+    public int getHeight();
+
+    /**
+     * Gets timestamp of the media in nanoseconds.
+     *
+     * @return timestamp of the media in nanoseconds
+     */
+    public long getTimestamp();
+
+    /**
+     * Gets the raw data of the media.
+     *
+     * @return raw data of the media
+     */
+    // TODO: Fix this and perhaps use a URI here for saved artifact.
+    public byte[] getData();
+
+    /**
+     * Gets the mime type of the media.
+     *
+     * @return mime type of the media
+     */
+    public String getMimeType();
+
+    /**
+     * Gets the file extension of the media.
+     *
+     * @return file extension of the media
+     */
+    public String getExtension();
+
+    /**
+     * Returns whether the media file will support Exif data.
+     *
+     * @return true if the media type supports exif data, false otherwise
+     */
+    public boolean isSupportingExifData();
+}
\ No newline at end of file
diff --git a/src/com/android/camera/burst/BurstResult.java b/src/com/android/camera/burst/BurstResult.java
new file mode 100644
index 0000000..1e281a5
--- /dev/null
+++ b/src/com/android/camera/burst/BurstResult.java
@@ -0,0 +1,50 @@
+/*
+ * 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.camera.burst;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * The result of a captured burst.
+ * <p/>
+ * A BurstResult consists of a series of BurstArtifacts. Artifacts store their
+ * media content in BurstMediaItem containers.
+ * <p/>
+ * Each artifact has a type-name that specifies the kind of artifact it
+ * represents (e.g. GIF, collage, etc.). These types are implementation
+ * specific. An artifact only contains media items of a single type. A
+ * BurstMediaItem contains media content and associated metadata and can be an
+ * image, an animated GIF, a collage or any other drawable media.
+ */
+public interface BurstResult {
+    /**
+     * Returns the list of all artifacts included in this result.
+     */
+    public List<BurstArtifact> getArtifacts();
+
+    /**
+     * Returns the set of unique artifact types included in this result.
+     */
+    public Set<String> getTypes();
+
+    /**
+     * Returns all artifacts of the specified type.
+     *
+     * @param type the type of artifacts
+     * @return list of artifacts of that type
+     */
+    public List<BurstArtifact> getArtifactsByType(String type);
+}
diff --git a/src/com/android/camera/burst/BurstResultsListener.java b/src/com/android/camera/burst/BurstResultsListener.java
new file mode 100644
index 0000000..f7e6cab
--- /dev/null
+++ b/src/com/android/camera/burst/BurstResultsListener.java
@@ -0,0 +1,54 @@
+/*
+ * 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.camera.burst;
+
+import java.util.Map;
+
+/**
+ * A listener to the various events generated during a burst.
+ */
+public interface BurstResultsListener {
+    /**
+     * Called when burst starts.
+     */
+    public void onBurstStarted();
+
+    /**
+     * Called when burst completes.
+     *
+     * @param burstResult the result of the captured burst.
+     */
+    public void onBurstCompleted(BurstResult burstResult);
+
+    /**
+     * Called when there is an unrecoverable error during capturing a burst.
+     * <p/>
+     * The burst failed with an unrecoverable error and did not produce any
+     * results.
+     */
+    public void onBurstError(Exception error);
+
+    /**
+     * Called when artifact count is available.
+     * <p/>
+     * This happens before the post processing phase.
+     *
+     * @param artifactTypeCount A map from the type of artifact to count of
+     *            artifact.
+     */
+    // TODO: Reconsider this method, perhaps return a Future for each artifact
+    // in the BurstResult.
+    public void onArtifactCountAvailable(Map<String, Integer> artifactTypeCount);
+}
diff --git a/src/com/android/camera/burst/ResultsAccessor.java b/src/com/android/camera/burst/ResultsAccessor.java
new file mode 100644
index 0000000..be2904c
--- /dev/null
+++ b/src/com/android/camera/burst/ResultsAccessor.java
@@ -0,0 +1,59 @@
+/*
+ * 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.camera.burst;
+
+import java.util.concurrent.Future;
+
+/**
+ * Accessor that can be used for retrieving high-res burst images from the
+ * internal camera image buffer.
+ * <p/>
+ * On completion of a burst Camera hands over an instance of
+ * {@link ResultsAccessor} to the burst module by calling the
+ * {@link BurstControllerImpl#stopBurst(ResultsAccessor)} method. The burst
+ * module can then retrieve images from the internal buffer by calling
+ * {@link #extractImage(long)} with the timestamp of each image.
+ * <p/>
+ * When burst module has completed retrieving the high-res images from the
+ * buffer it should call {@link #close()} to let camera free the internal buffer
+ * and resources used by the burst.
+ */
+public interface ResultsAccessor extends AutoCloseable {
+    /**
+     * Extract image which has the given timestamp.
+     * <p/>
+     * Extracting an image is an expensive operation and is done asynchronously.
+     * This method returns a <code>Future<BurstImage></code> which can be used
+     * to retrieve the image. If the provided timestamp is not a result of burst
+     * or internal buffer of Camera does not have the image, the
+     * {@link Future#get()} will return null. Camera frees up resources related
+     * to the timestamp after the first call. Calling this method with the same
+     * timestamp will result in a null image.
+     *
+     * @param timestamp the timestamp of the image to be extracted
+     * @return the future for BurstImage.
+     */
+    Future<BurstImage> extractImage(long timestamp);
+
+    /**
+     * Called when results extraction has been completed and the Camera can free
+     * up resources related to results of burst.
+     * <p/>
+     * No further images can be extracted after calling this method. Any
+     * computations for extracting images are cancelled.
+     */
+    @Override
+    void close();
+}