Public API changes for CameraProfile and CamcorderProfile classes

1. CamcorderProfile: “@see” links are broken; Remove m prefix from fields; remove “final”
2. CamcorderProfile.Quality: use an int rather than an enum
3. Add API on MediaRecorder to pass in a CamcorderProfile
4. CameraProfile.getImageEncodingQualityLevels @hide or make it consistent with CamcorderProfile
5. Remove a convenient method and instead let the (mms) app do that task

bug - 2553862

Change-Id: I759215c7892f772aeddf3651d17038489c6fbc50
diff --git a/api/current.xml b/api/current.xml
index 34a0e00..53f5178 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -82509,163 +82509,151 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="quality" type="android.media.CamcorderProfile.Quality">
+<parameter name="quality" type="int">
 </parameter>
 </method>
-<method name="getMmsRecordingDurationInSeconds"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
+<field name="QUALITY_HIGH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
  static="true"
  final="true"
  deprecated="not deprecated"
  visibility="public"
 >
-</method>
-<field name="mAudioBitRate"
+</field>
+<field name="QUALITY_LOW"
  type="int"
  transient="false"
  volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mAudioChannels"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mAudioCodec"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mAudioSampleRate"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mFileFormat"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mQuality"
- type="android.media.CamcorderProfile.Quality"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mVideoBitRate"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mVideoCodec"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mVideoFrameHeight"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mVideoFrameRate"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="mVideoFrameWidth"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="CamcorderProfile.Quality"
- extends="java.lang.Enum"
- abstract="false"
+ value="0"
  static="true"
  final="true"
  deprecated="not deprecated"
  visibility="public"
 >
-<method name="valueOf"
- return="android.media.CamcorderProfile.Quality"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
+</field>
+<field name="audioBitRate"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="name" type="java.lang.String">
-</parameter>
-</method>
-<method name="values"
- return="android.media.CamcorderProfile.Quality[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="true"
+</field>
+<field name="audioChannels"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-</method>
+</field>
+<field name="audioCodec"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="audioSampleRate"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="duration"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="fileFormat"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quality"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="videoBitRate"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="videoCodec"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="videoFrameHeight"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="videoFrameRate"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="videoFrameWidth"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="CameraProfile"
  extends="java.lang.Object"
@@ -82683,8 +82671,8 @@
  visibility="public"
 >
 </constructor>
-<method name="getImageEncodingQualityLevels"
- return="int[]"
+<method name="getJpegEncodingQualityParameter"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -82693,7 +82681,42 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="quality" type="int">
+</parameter>
 </method>
+<field name="QUALITY_HIGH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="QUALITY_LOW"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="QUALITY_MEDIUM"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ExifInterface"
  extends="java.lang.Object"
@@ -84608,6 +84631,19 @@
 <parameter name="sv" type="android.view.Surface">
 </parameter>
 </method>
+<method name="setProfile"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="profile" type="android.media.CamcorderProfile">
+</parameter>
+</method>
 <method name="setVideoEncoder"
  return="void"
  abstract="false"
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index eb96d20..a4eea2a 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -24,8 +24,8 @@
 namespace android {
 
 enum camcorder_quality {
-    CAMCORDER_QUALITY_HIGH = 0,
-    CAMCORDER_QUALITY_LOW  = 1
+    CAMCORDER_QUALITY_LOW  = 0,
+    CAMCORDER_QUALITY_HIGH = 1
 };
 
 enum video_decoder {
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index 09ac0ac..64d6460 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -19,17 +19,19 @@
 /**
  * The CamcorderProfile class is used to retrieve the
  * predefined camcorder profile settings for camcorder applications.
+ * These settings are read-only.
+ *
  * The compressed output from a recording session with a given
  * CamcorderProfile contains two tracks: one for auido and one for video.
  *
  * <p>Each profile specifies the following set of parameters:
  * <ul>
- * <li> The file output format, @see android.media.MediaRecorder.OutputFormat
- * <li> Video codec format, @see android.media.MediaRecorder.VideoEncoder
+ * <li> The file output format
+ * <li> Video codec format
  * <li> Video bit rate in bits per second
  * <li> Video frame rate in frames per second
  * <li> Video frame width and height,
- * <li> Audio codec format, @see android.media.MediaRecorder.AudioEncoder
+ * <li> Audio codec format
  * <li> Audio bit rate in bits per second,
  * <li> Audio sample rate
  * <li> Number of audio channels for recording.
@@ -37,98 +39,95 @@
  */
 public class CamcorderProfile
 {
-    private final int mDuration;  // Recording duration in seconds
-
     /**
-     * The Quality class represents the quality level of each CamcorderProfile.
+     * The output from camcorder recording sessions can have different quality levels.
      *
-     * The output from recording sessions with high quality level usually may have
-     * larger output bit rate, better video and/or audio recording quality, and
-     * laerger video frame resolution and higher audio sampling rate, etc, than those
-     * with low quality level.
+     * Currently, we define two quality levels: high quality and low quality.
+     * A camcorder recording session with high quality level usually has higher output bit
+     * rate, better video and/or audio recording quality, larger video frame
+     * resolution and higher audio sampling rate, etc, than those with low quality
+     * level.
+     *
+     * Do not change these values/ordinals without updating their counterpart
+     * in include/media/MediaProfiles.h!
      */
-    public enum Quality {
-       /* Do not change these values/ordinals without updating their counterpart
-        * in include/media/MediaProfiles.h!
-        */
-        HIGH,
-        LOW
-    };
+    public static final int QUALITY_LOW  = 0;
+    public static final int QUALITY_HIGH = 1;
 
     /**
-     * Returns the recording duration in seconds for LOW quality CamcorderProfile
-     * used by the MMS application.
+     * Default recording duration in seconds before the session is terminated.
+     * This is useful for applications like MMS has limited file size requirement.
      */
-    public static final int getMmsRecordingDurationInSeconds() {
-        return get(Quality.LOW).mDuration;
-    }
+    public int duration;
 
     /**
      * The quality level of the camcorder profile
-     * @see android.media.CamcorderProfile.Quality
      */
-    public final Quality mQuality;
+    public int quality;
 
     /**
      * The file output format of the camcorder profile
      * @see android.media.MediaRecorder.OutputFormat
      */
-    public final int mFileFormat;
+    public int fileFormat;
 
     /**
      * The video encoder being used for the video track
      * @see android.media.MediaRecorder.VideoEncoder
      */
-    public final int mVideoCodec;
+    public int videoCodec;
 
     /**
      * The target video output bit rate in bits per second
      */
-    public final int mVideoBitRate;
+    public int videoBitRate;
 
     /**
      * The target video frame rate in frames per second
      */
-    public final int mVideoFrameRate;
+    public int videoFrameRate;
 
     /**
      * The target video frame width in pixels
      */
-    public final int mVideoFrameWidth;
+    public int videoFrameWidth;
 
     /**
      * The target video frame height in pixels
      */
-    public final int mVideoFrameHeight;
+    public int videoFrameHeight;
 
     /**
      * The audio encoder being used for the audio track.
      * @see android.media.MediaRecorder.AudioEncoder
      */
-    public final int mAudioCodec;
+    public int audioCodec;
 
     /**
      * The target audio output bit rate in bits per second
      */
-    public final int mAudioBitRate;
+    public int audioBitRate;
 
     /**
      * The audio sampling rate used for the audio track
      */
-    public final int mAudioSampleRate;
+    public int audioSampleRate;
 
     /**
      * The number of audio channels used for the audio track
      */
-    public final int mAudioChannels;
+    public int audioChannels;
 
     /**
-     * Returns the camcorder profile for the given quality.
+     * Returns the camcorder profile for the given quality level.
      * @param quality the target quality level for the camcorder profile
-     * @see android.media.CamcorderProfile.Quality
      */
-    public static CamcorderProfile get(Quality quality) {
-        return native_get_camcorder_profile(quality.ordinal());
+    public static CamcorderProfile get(int quality) {
+        if (quality < QUALITY_LOW || quality > QUALITY_HIGH) {
+            String errMessage = "Unsupported quality level: " + quality;
+            throw new IllegalArgumentException(errMessage);
+        }
+        return native_get_camcorder_profile(quality);
     }
 
     static {
@@ -150,18 +149,18 @@
                              int audioSampleRate,
                              int audioChannels) {
 
-        mDuration         = duration;
-        mQuality          = Quality.values()[quality];
-        mFileFormat       = fileFormat;
-        mVideoCodec       = videoCodec;
-        mVideoBitRate     = videoBitRate;
-        mVideoFrameRate   = videoFrameRate;
-        mVideoFrameWidth  = videoWidth;
-        mVideoFrameHeight = videoHeight;
-        mAudioCodec       = audioCodec;
-        mAudioBitRate     = audioBitRate;
-        mAudioSampleRate  = audioSampleRate;
-        mAudioChannels    = audioChannels;
+        this.duration         = duration;
+        this.quality          = quality;
+        this.fileFormat       = fileFormat;
+        this.videoCodec       = videoCodec;
+        this.videoBitRate     = videoBitRate;
+        this.videoFrameRate   = videoFrameRate;
+        this.videoFrameWidth  = videoWidth;
+        this.videoFrameHeight = videoHeight;
+        this.audioCodec       = audioCodec;
+        this.audioBitRate     = audioBitRate;
+        this.audioSampleRate  = audioSampleRate;
+        this.audioChannels    = audioChannels;
     }
 
     // Methods implemented by JNI
diff --git a/media/java/android/media/CameraProfile.java b/media/java/android/media/CameraProfile.java
index f1616cc..f8d3935 100644
--- a/media/java/android/media/CameraProfile.java
+++ b/media/java/android/media/CameraProfile.java
@@ -16,6 +16,8 @@
 
 package android.media;
 
+import java.util.Arrays;
+
 /**
  * The CameraProfile class is used to retrieve the pre-defined still image
  * capture (jpeg) quality levels (0-100) used for low, medium, and high
@@ -25,23 +27,52 @@
 public class CameraProfile
 {
     /**
-     * Returns a list of the pre-defined still image capture (jpeg) quality levels
-     * used for low, medium and high quality settings in the Camera application.
+     * Define three quality levels for JPEG image encoding.
      */
-    public static int[] getImageEncodingQualityLevels() {
-        int nLevels = native_get_num_image_encoding_quality_levels();
-        if (nLevels == 0) return null;
+    /*
+     * Don't change the values for these constants unless getImageEncodingQualityLevels()
+     * method is also changed accordingly.
+     */
+    public static final int QUALITY_LOW    = 0;
+    public static final int QUALITY_MEDIUM = 1;
+    public static final int QUALITY_HIGH   = 2;
 
-        int[] levels = new int[nLevels];
-        for (int i = 0; i < nLevels; ++i) {
-            levels[i] = native_get_image_encoding_quality_level(i);
+    /*
+     * Cache the Jpeg encoding quality parameters
+     */
+    private static final int[] sJpegEncodingQualityParameters;
+
+    /**
+     * Returns a pre-defined still image capture (jpeg) quality level
+     * used for the given quality level in the Camera application.
+     *
+     * @param quality The target quality level
+     */
+    public static int getJpegEncodingQualityParameter(int quality) {
+        if (quality < QUALITY_LOW || quality > QUALITY_HIGH) {
+            throw new IllegalArgumentException("Unsupported quality level: " + quality);
         }
-        return levels;
+        return sJpegEncodingQualityParameters[quality];
     }
 
     static {
         System.loadLibrary("media_jni");
         native_init();
+        sJpegEncodingQualityParameters = getImageEncodingQualityLevels();
+    }
+
+    private static int[] getImageEncodingQualityLevels() {
+        int nLevels = native_get_num_image_encoding_quality_levels();
+        if (nLevels != QUALITY_HIGH + 1) {
+            throw new RuntimeException("Unexpected Jpeg encoding quality levels " + nLevels);
+        }
+
+        int[] levels = new int[nLevels];
+        for (int i = 0; i < nLevels; ++i) {
+            levels[i] = native_get_image_encoding_quality_level(i);
+        }
+        Arrays.sort(levels);  // Lower quality level ALWAYS comes before higher one
+        return levels;
     }
 
     // Methods implemented by JNI
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 5988d34..47a8cfc 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.media.CamcorderProfile;
 import android.hardware.Camera;
 import android.os.Handler;
 import android.os.Looper;
@@ -259,6 +260,25 @@
             throws IllegalStateException;
 
     /**
+     * Uses the settings from a CamcorderProfile object for recording. This method should
+     * be called after the video AND audio sources are set, and before setOutputFile().
+     *
+     * @param profile the CamcorderProfile to use
+     * @see android.media.CamcorderProfile
+     */
+    public void setProfile(CamcorderProfile profile) {
+        setOutputFormat(profile.fileFormat);
+        setVideoFrameRate(profile.videoFrameRate);
+        setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
+        setVideoEncodingBitRate(profile.videoBitRate);
+        setAudioEncodingBitRate(profile.audioBitRate);
+        setAudioChannels(profile.audioChannels);
+        setAudioSamplingRate(profile.audioSampleRate);
+        setVideoEncoder(profile.videoCodec);
+        setAudioEncoder(profile.audioCodec);
+    }
+
+    /**
      * Sets the format of the output file produced during recording. Call this
      * after setAudioSource()/setVideoSource() but before prepare().
      *