camera_metadata: Add support to generate Keys for generic types

Also adds the following keys:
* android.control.maxRegionsAe
* android.control.maxRegionsAwb
* android.control.maxRegionsAf
* android.request.maxNumOutputRaw
* android.request.maxNumOutputProc
* android.request.maxNumOutputProcStalling

Changes the following keys' type generations:
* android.control.aeTargetFpsRange (Range<Integer>)
* android.control.aeAvailableTargetFpsRanges (Range<Integer>[])
* android.control.aeCompensationRange (Range<Integer>)
* android.lens.focusRange (Range<Float>)

When trying to generate code for a generic type such as a
"Range<Float>", the generated static key initializers will now use
a TypeReference<T> instead of a T.class.

Non-generic types will proceed to use the older T.class variant.

Bug: 14628001
Change-Id: I141847dffc4b0d89cea37c19a54d6d5faf24a9bb
diff --git a/camera/docs/CameraMetadataKeys.mako b/camera/docs/CameraMetadataKeys.mako
index 27da332..7c14a1f 100644
--- a/camera/docs/CameraMetadataKeys.mako
+++ b/camera/docs/CameraMetadataKeys.mako
@@ -74,7 +74,7 @@
     @Deprecated
   % endif
     public static final Key<${jtype_boxed(entry)}> ${entry.name | jkey_identifier} =
-            new Key<${jtype_boxed(entry)}>("${entry.name}", ${jclass(entry)});
+            new Key<${jtype_boxed(entry)}>("${entry.name}", ${jkey_type_token(entry)});
 </%def>\
 ##
 ## Generate a list of only Static, Controls, or Dynamic properties.
diff --git a/camera/docs/docs.html b/camera/docs/docs.html
index 15b173a..e98fe97 100644
--- a/camera/docs/docs.html
+++ b/camera/docs/docs.html
@@ -204,6 +204,12 @@
             <li
             ><a href="#static_android.control.maxRegions">android.control.maxRegions</a></li>
             <li
+            ><a href="#static_android.control.maxRegionsAe">android.control.maxRegionsAe</a></li>
+            <li
+            ><a href="#static_android.control.maxRegionsAwb">android.control.maxRegionsAwb</a></li>
+            <li
+            ><a href="#static_android.control.maxRegionsAf">android.control.maxRegionsAf</a></li>
+            <li
             ><a href="#static_android.control.sceneModeOverrides">android.control.sceneModeOverrides</a></li>
           </ul>
         </li>
@@ -582,6 +588,12 @@
             <li
             ><a href="#static_android.request.maxNumOutputStreams">android.request.maxNumOutputStreams</a></li>
             <li
+            ><a href="#static_android.request.maxNumOutputRaw">android.request.maxNumOutputRaw</a></li>
+            <li
+            ><a href="#static_android.request.maxNumOutputProc">android.request.maxNumOutputProc</a></li>
+            <li
+            ><a href="#static_android.request.maxNumOutputProcStalling">android.request.maxNumOutputProcStalling</a></li>
+            <li
                 class="toc_deprecated"
             ><a href="#static_android.request.maxNumReprocessStreams">android.request.maxNumReprocessStreams</a></li>
             <li
@@ -2016,7 +2028,7 @@
                 <span class="entry_type_array">
                   2
                 </span>
-              <span class="entry_type_visibility"> [public]</span>
+              <span class="entry_type_visibility"> [public as rangeInt]</span>
 
 
 
@@ -3346,7 +3358,7 @@
                 <span class="entry_type_array">
                   2 x n
                 </span>
-              <span class="entry_type_visibility"> [public]</span>
+              <span class="entry_type_visibility"> [public as rangeInt]</span>
 
 
 
@@ -3388,7 +3400,7 @@
                 <span class="entry_type_array">
                   2
                 </span>
-              <span class="entry_type_visibility"> [public]</span>
+              <span class="entry_type_visibility"> [public as rangeInt]</span>
 
 
 
@@ -3763,7 +3775,7 @@
                 <span class="entry_type_array">
                   3
                 </span>
-              <span class="entry_type_visibility"> [public]</span>
+              <span class="entry_type_visibility"> [hidden]</span>
 
 
 
@@ -3801,6 +3813,158 @@
            <!-- end of entry -->
         
                 
+          <tr class="entry" id="static_android.control.maxRegionsAe">
+            <td class="entry_name
+             " rowspan="3">
+              android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Ae
+            </td>
+            <td class="entry_type">
+                <span class="entry_type_name">int32</span>
+
+              <span class="entry_type_visibility"> [public]</span>
+
+              <span class="entry_type_synthetic">[synthetic] </span>
+
+
+
+
+            </td> <!-- entry_type -->
+
+            <td class="entry_description">
+              <p>List of the maximum number of regions that can be used for metering in
+auto-exposure (AE);
+this corresponds to the the maximum number of elements in
+<a href="#controls_android.control.aeRegions">android.<wbr/>control.<wbr/>ae<wbr/>Regions</a>.<wbr/></p>
+            </td>
+
+            <td class="entry_units">
+            </td>
+
+            <td class="entry_range">
+              <p>Value will be &gt;= 0.<wbr/> For FULL-capability devices,<wbr/> this
+value will be &gt;= 1.<wbr/></p>
+            </td>
+
+            <td class="entry_tags">
+            </td>
+
+          </tr>
+
+          <tr class="entries_header">
+            <th class="th_details" colspan="5">HAL Implementation Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="5">
+              <p>This entry is private to the framework.<wbr/> Fill in
+maxRegions to have this entry be automatically populated.<wbr/></p>
+            </td>
+          </tr>
+
+          <tr class="entry_spacer"><td class="entry_spacer" colspan="6"></td></tr>
+           <!-- end of entry -->
+        
+                
+          <tr class="entry" id="static_android.control.maxRegionsAwb">
+            <td class="entry_name
+             " rowspan="3">
+              android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Awb
+            </td>
+            <td class="entry_type">
+                <span class="entry_type_name">int32</span>
+
+              <span class="entry_type_visibility"> [public]</span>
+
+              <span class="entry_type_synthetic">[synthetic] </span>
+
+
+
+
+            </td> <!-- entry_type -->
+
+            <td class="entry_description">
+              <p>List of the maximum number of regions that can be used for metering in
+auto-white balance (AWB);
+this corresponds to the the maximum number of elements in
+<a href="#controls_android.control.awbRegions">android.<wbr/>control.<wbr/>awb<wbr/>Regions</a>.<wbr/></p>
+            </td>
+
+            <td class="entry_units">
+            </td>
+
+            <td class="entry_range">
+              <p>Value will be &gt;= 0.<wbr/></p>
+            </td>
+
+            <td class="entry_tags">
+            </td>
+
+          </tr>
+
+          <tr class="entries_header">
+            <th class="th_details" colspan="5">HAL Implementation Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="5">
+              <p>This entry is private to the framework.<wbr/> Fill in
+maxRegions to have this entry be automatically populated.<wbr/></p>
+            </td>
+          </tr>
+
+          <tr class="entry_spacer"><td class="entry_spacer" colspan="6"></td></tr>
+           <!-- end of entry -->
+        
+                
+          <tr class="entry" id="static_android.control.maxRegionsAf">
+            <td class="entry_name
+             " rowspan="3">
+              android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Af
+            </td>
+            <td class="entry_type">
+                <span class="entry_type_name">int32</span>
+
+              <span class="entry_type_visibility"> [public]</span>
+
+              <span class="entry_type_synthetic">[synthetic] </span>
+
+
+
+
+            </td> <!-- entry_type -->
+
+            <td class="entry_description">
+              <p>List of the maximum number of regions that can be used for metering in
+auto-focus (AF);
+this corresponds to the the maximum number of elements in
+<a href="#controls_android.control.afRegions">android.<wbr/>control.<wbr/>af<wbr/>Regions</a>.<wbr/></p>
+            </td>
+
+            <td class="entry_units">
+            </td>
+
+            <td class="entry_range">
+              <p>Value will be &gt;= 0.<wbr/> For FULL-capability devices,<wbr/> this
+value will be &gt;= 1.<wbr/></p>
+            </td>
+
+            <td class="entry_tags">
+            </td>
+
+          </tr>
+
+          <tr class="entries_header">
+            <th class="th_details" colspan="5">HAL Implementation Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="5">
+              <p>This entry is private to the framework.<wbr/> Fill in
+maxRegions to have this entry be automatically populated.<wbr/></p>
+            </td>
+          </tr>
+
+          <tr class="entry_spacer"><td class="entry_spacer" colspan="6"></td></tr>
+           <!-- end of entry -->
+        
+                
           <tr class="entry" id="static_android.control.sceneModeOverrides">
             <td class="entry_name
              " rowspan="5">
@@ -4414,7 +4578,7 @@
                 <span class="entry_type_array">
                   2
                 </span>
-              <span class="entry_type_visibility"> [public]</span>
+              <span class="entry_type_visibility"> [public as rangeInt]</span>
 
 
 
@@ -10100,7 +10264,7 @@
                 <span class="entry_type_array">
                   2
                 </span>
-              <span class="entry_type_visibility"> [public]</span>
+              <span class="entry_type_visibility"> [public as rangeFloat]</span>
 
 
 
@@ -11373,7 +11537,7 @@
                 <span class="entry_type_array">
                   3
                 </span>
-              <span class="entry_type_visibility"> [public]</span>
+              <span class="entry_type_visibility"> [hidden]</span>
 
 
 
@@ -11416,7 +11580,7 @@
 number is 3,<wbr/> and max JPEG stream number is 2,<wbr/> then this tuple should be <code>(1,<wbr/> 3,<wbr/> 2)</code>.<wbr/></p>
 <p>This lists the upper bound of the number of output streams supported by
 the camera device.<wbr/> Using more streams simultaneously may require more hardware and
-CPU resources that will consume more power.<wbr/> The image format for a output stream can
+CPU resources that will consume more power.<wbr/> The image format for an output stream can
 be any supported format provided by <a href="#static_android.scaler.availableStreamConfigurations">android.<wbr/>scaler.<wbr/>available<wbr/>Stream<wbr/>Configurations</a>.<wbr/>
 The formats defined in <a href="#static_android.scaler.availableStreamConfigurations">android.<wbr/>scaler.<wbr/>available<wbr/>Stream<wbr/>Configurations</a> can be catergorized
 into the 3 stream types as below:</p>
@@ -11435,6 +11599,186 @@
            <!-- end of entry -->
         
                 
+          <tr class="entry" id="static_android.request.maxNumOutputRaw">
+            <td class="entry_name
+             " rowspan="3">
+              android.<wbr/>request.<wbr/>max<wbr/>Num<wbr/>Output<wbr/>Raw
+            </td>
+            <td class="entry_type">
+                <span class="entry_type_name">int32</span>
+
+              <span class="entry_type_visibility"> [public]</span>
+
+              <span class="entry_type_synthetic">[synthetic] </span>
+
+
+
+
+            </td> <!-- entry_type -->
+
+            <td class="entry_description">
+              <p>The maximum numbers of different types of output streams
+that can be configured and used simultaneously by a camera device
+for any <code>RAW</code> formats.<wbr/></p>
+            </td>
+
+            <td class="entry_units">
+            </td>
+
+            <td class="entry_range">
+              <p>&gt;= 0</p>
+            </td>
+
+            <td class="entry_tags">
+            </td>
+
+          </tr>
+          <tr class="entries_header">
+            <th class="th_details" colspan="5">Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="5">
+              <p>This value contains the max number of output simultaneous
+streams from the raw sensor.<wbr/></p>
+<p>This lists the upper bound of the number of output streams supported by
+the camera device.<wbr/> Using more streams simultaneously may require more hardware and
+CPU resources that will consume more power.<wbr/> The image format for this kind of an output stream can
+be any <code>RAW</code> and supported format provided by <a href="#static_android.scaler.streamConfigurationMap">android.<wbr/>scaler.<wbr/>stream<wbr/>Configuration<wbr/>Map</a>.<wbr/></p>
+<p>In particular,<wbr/> a <code>RAW</code> format is typically one of:</p>
+<ul>
+<li>ImageFormat#RAW_<wbr/>SENSOR</li>
+<li>Opaque <code>RAW</code></li>
+</ul>
+            </td>
+          </tr>
+
+
+          <tr class="entry_spacer"><td class="entry_spacer" colspan="6"></td></tr>
+           <!-- end of entry -->
+        
+                
+          <tr class="entry" id="static_android.request.maxNumOutputProc">
+            <td class="entry_name
+             " rowspan="3">
+              android.<wbr/>request.<wbr/>max<wbr/>Num<wbr/>Output<wbr/>Proc
+            </td>
+            <td class="entry_type">
+                <span class="entry_type_name">int32</span>
+
+              <span class="entry_type_visibility"> [public]</span>
+
+              <span class="entry_type_synthetic">[synthetic] </span>
+
+
+
+
+            </td> <!-- entry_type -->
+
+            <td class="entry_description">
+              <p>The maximum numbers of different types of output streams
+that can be configured and used simultaneously by a camera device
+for any processed (but not-stalling) formats.<wbr/></p>
+            </td>
+
+            <td class="entry_units">
+            </td>
+
+            <td class="entry_range">
+              <p>&gt;= 3
+for FULL mode devices (<code><a href="#static_android.info.supportedHardwareLevel">android.<wbr/>info.<wbr/>supported<wbr/>Hardware<wbr/>Level</a> == FULL</code>);
+&gt;= 2 for LIMITED mode devices (<code><a href="#static_android.info.supportedHardwareLevel">android.<wbr/>info.<wbr/>supported<wbr/>Hardware<wbr/>Level</a> == LIMITED</code>).<wbr/></p>
+            </td>
+
+            <td class="entry_tags">
+            </td>
+
+          </tr>
+          <tr class="entries_header">
+            <th class="th_details" colspan="5">Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="5">
+              <p>This value contains the max number of output simultaneous
+streams for any processed (but not-stalling) formats.<wbr/></p>
+<p>This lists the upper bound of the number of output streams supported by
+the camera device.<wbr/> Using more streams simultaneously may require more hardware and
+CPU resources that will consume more power.<wbr/> The image format for this kind of an output stream can
+be any non-<code>RAW</code> and supported format provided by <a href="#static_android.scaler.streamConfigurationMap">android.<wbr/>scaler.<wbr/>stream<wbr/>Configuration<wbr/>Map</a>.<wbr/></p>
+<p>Processed (but not-stalling) is defined as any non-RAW format without a stall duration.<wbr/>
+Typically:</p>
+<ul>
+<li>Image<wbr/>Format#YUV_<wbr/>420_<wbr/>888</li>
+<li>ImageFormat#NV21</li>
+<li>ImageFormat#YV12</li>
+<li>Implementation-defined formats,<wbr/> i.<wbr/>e.<wbr/> StreamConfiguration#isOutputSupportedFor(Class)</li>
+</ul>
+<p>For full guarantees,<wbr/> query StreamConfigurationMap#getOutputStallDuration with
+a processed format -- it will return 0 for a non-stalling stream.<wbr/></p>
+            </td>
+          </tr>
+
+
+          <tr class="entry_spacer"><td class="entry_spacer" colspan="6"></td></tr>
+           <!-- end of entry -->
+        
+                
+          <tr class="entry" id="static_android.request.maxNumOutputProcStalling">
+            <td class="entry_name
+             " rowspan="3">
+              android.<wbr/>request.<wbr/>max<wbr/>Num<wbr/>Output<wbr/>Proc<wbr/>Stalling
+            </td>
+            <td class="entry_type">
+                <span class="entry_type_name">int32</span>
+
+              <span class="entry_type_visibility"> [public]</span>
+
+              <span class="entry_type_synthetic">[synthetic] </span>
+
+
+
+
+            </td> <!-- entry_type -->
+
+            <td class="entry_description">
+              <p>The maximum numbers of different types of output streams
+that can be configured and used simultaneously by a camera device
+for any processed (and stalling) formats.<wbr/></p>
+            </td>
+
+            <td class="entry_units">
+            </td>
+
+            <td class="entry_range">
+              <p>&gt;= 1</p>
+            </td>
+
+            <td class="entry_tags">
+            </td>
+
+          </tr>
+          <tr class="entries_header">
+            <th class="th_details" colspan="5">Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="5">
+              <p>This value contains the max number of output simultaneous
+streams for any processed (but not-stalling) formats.<wbr/></p>
+<p>This lists the upper bound of the number of output streams supported by
+the camera device.<wbr/> Using more streams simultaneously may require more hardware and
+CPU resources that will consume more power.<wbr/> The image format for this kind of an output stream can
+be any non-<code>RAW</code> and supported format provided by <a href="#static_android.scaler.streamConfigurationMap">android.<wbr/>scaler.<wbr/>stream<wbr/>Configuration<wbr/>Map</a>.<wbr/></p>
+<p>A processed and stalling format is defined as any non-RAW format with a stallDurations &gt; 0.<wbr/>
+Typically only the <code>JPEG</code> format (ImageFormat#JPEG)</p>
+<p>For full guarantees,<wbr/> query StreamConfigurationMap#getOutputStallDuration with
+a processed format -- it will return a non-0 value for a stalling stream.<wbr/></p>
+            </td>
+          </tr>
+
+
+          <tr class="entry_spacer"><td class="entry_spacer" colspan="6"></td></tr>
+           <!-- end of entry -->
+        
+                
           <tr class="entry" id="static_android.request.maxNumReprocessStreams">
             <td class="entry_name
                 entry_name_deprecated
diff --git a/camera/docs/metadata_helpers.py b/camera/docs/metadata_helpers.py
index a69a853..f0828ac 100644
--- a/camera/docs/metadata_helpers.py
+++ b/camera/docs/metadata_helpers.py
@@ -427,6 +427,27 @@
   unboxed_type = jtype_unboxed(entry)
   return _jtype_box(unboxed_type)
 
+def _is_jtype_generic(entry):
+  """
+  Determine whether or not the Java type represented by the entry type
+  string and/or typedef is a Java generic.
+
+  For example, "Range<Integer>" would be considered a generic, whereas
+  a "MeteringRectangle" or a plain "Integer" would not be considered a generic.
+
+  Args:
+    entry: An instance of an Entry node
+
+  Returns:
+    True if it's a java generic, False otherwise.
+  """
+  if entry.typedef:
+    local_typedef = _jtypedef_type(entry)
+    if local_typedef:
+      match = re.search(r'<.*>', local_typedef)
+      return bool(match)
+  return False
+
 def _jtype_primitive(what):
   """
   Calculate the Java type from an entry type string.
@@ -472,6 +493,23 @@
 
   return "%s.class" %jtype_unboxed(entry)
 
+def jkey_type_token(entry):
+  """
+  Calculate the java type token compatible with a Key constructor.
+  This will be the Java Class<T> for non-generic classes, and a
+  TypeReference<T> for generic classes.
+
+  Args:
+    entry: An entry node
+
+  Returns:
+    The ClassName.class string, or 'new TypeReference<ClassName>() {{ }}' string
+  """
+  if _is_jtype_generic(entry):
+    return "new TypeReference<%s>() {{ }}" %(jtype_boxed(entry))
+  else:
+    return jclass(entry)
+
 def jidentifier(what):
   """
   Convert the input string into a valid Java identifier.
diff --git a/camera/docs/metadata_properties.xml b/camera/docs/metadata_properties.xml
index b0afb96..dffb494 100644
--- a/camera/docs/metadata_properties.xml
+++ b/camera/docs/metadata_properties.xml
@@ -74,6 +74,12 @@
     <typedef name="meteringRectangle">
       <language name="java">android.hardware.camera2.params.MeteringRectangle</language>
     </typedef>
+    <typedef name="rangeFloat">
+      <language name="java">android.util.Range&lt;Float&gt;</language>
+    </typedef>
+    <typedef name="rangeInt">
+      <language name="java">android.util.Range&lt;Integer&gt;</language>
+    </typedef>
   </types>
 
   <namespace name="android">
@@ -488,7 +494,7 @@
           <tag id="BC" />
         </entry>
         <entry name="aeTargetFpsRange" type="int32" visibility="public"
-               container="array">
+               container="array" typedef="rangeInt">
           <array>
             <size>2</size>
           </array>
@@ -1170,7 +1176,7 @@
         </entry>
         <entry name="aeAvailableTargetFpsRanges" type="int32" visibility="public"
                type_notes="list of pairs of frame rates"
-               container="array">
+               container="array" typedef="rangeInt">
           <array>
             <size>2</size>
             <size>n</size>
@@ -1179,7 +1185,7 @@
           AE algorithm/hardware</description>
         </entry>
         <entry name="aeCompensationRange" type="int32" visibility="public"
-               container="array">
+               container="array" typedef="rangeInt">
           <array>
             <size>2</size>
           </array>
@@ -1298,7 +1304,7 @@
           </details>
           <tag id="BC" />
         </entry>
-        <entry name="maxRegions" type="int32" visibility="public" container="array">
+        <entry name="maxRegions" type="int32" visibility="hidden" container="array">
           <array>
             <size>3</size>
           </array>
@@ -1315,6 +1321,50 @@
           `(AE, AWB, AF)`.</range>
           <tag id="BC" />
         </entry>
+        <entry name="maxRegionsAe" type="int32" visibility="public" synthetic="true">
+          <description>
+          List of the maximum number of regions that can be used for metering in
+          auto-exposure (AE);
+          this corresponds to the the maximum number of elements in
+          android.control.aeRegions.
+          </description>
+          <range>
+          Value will be &amp;gt;= 0. For FULL-capability devices, this
+          value will be &amp;gt;= 1.
+          </range>
+          <hal_details>This entry is private to the framework. Fill in
+          maxRegions to have this entry be automatically populated.
+          </hal_details>
+        </entry>
+        <entry name="maxRegionsAwb" type="int32" visibility="public" synthetic="true">
+          <description>
+          List of the maximum number of regions that can be used for metering in
+          auto-white balance (AWB);
+          this corresponds to the the maximum number of elements in
+          android.control.awbRegions.
+          </description>
+          <range>
+          Value will be &amp;gt;= 0.
+          </range>
+          <hal_details>This entry is private to the framework. Fill in
+          maxRegions to have this entry be automatically populated.
+          </hal_details>
+        </entry>
+        <entry name="maxRegionsAf" type="int32" visibility="public" synthetic="true">
+          <description>
+          List of the maximum number of regions that can be used for metering in
+          auto-focus (AF);
+          this corresponds to the the maximum number of elements in
+          android.control.afRegions.
+          </description>
+          <range>
+          Value will be &amp;gt;= 0. For FULL-capability devices, this
+          value will be &amp;gt;= 1.
+          </range>
+          <hal_details>This entry is private to the framework. Fill in
+          maxRegions to have this entry be automatically populated.
+          </hal_details>
+        </entry>
         <entry name="sceneModeOverrides" type="byte" visibility="system"
                container="array">
           <array>
@@ -2443,7 +2493,7 @@
         </clone>
         <entry name="focusRange" type="float" visibility="public"
         type_notes="Range of scene distances that are in focus"
-        container="array">
+        container="array" typedef="rangeFloat">
           <array>
             <size>2</size>
           </array>
@@ -2747,7 +2797,7 @@
         </entry>
       </controls>
       <static>
-        <entry name="maxNumOutputStreams" type="int32" visibility="public"
+        <entry name="maxNumOutputStreams" type="int32" visibility="hidden"
         container="array">
           <array>
             <size>3</size>
@@ -2773,7 +2823,7 @@
 
           This lists the upper bound of the number of output streams supported by
           the camera device. Using more streams simultaneously may require more hardware and
-          CPU resources that will consume more power. The image format for a output stream can
+          CPU resources that will consume more power. The image format for an output stream can
           be any supported format provided by android.scaler.availableStreamConfigurations.
           The formats defined in android.scaler.availableStreamConfigurations can be catergorized
           into the 3 stream types as below:
@@ -2786,6 +2836,84 @@
           </details>
           <tag id="BC" />
         </entry>
+        <entry name="maxNumOutputRaw" type="int32" visibility="public" synthetic="true">
+          <description>The maximum numbers of different types of output streams
+          that can be configured and used simultaneously by a camera device
+          for any `RAW` formats.
+          </description>
+          <range>
+          &amp;gt;= 0
+          </range>
+          <details>
+          This value contains the max number of output simultaneous
+          streams from the raw sensor.
+
+          This lists the upper bound of the number of output streams supported by
+          the camera device. Using more streams simultaneously may require more hardware and
+          CPU resources that will consume more power. The image format for this kind of an output stream can
+          be any `RAW` and supported format provided by android.scaler.streamConfigurationMap.
+
+          In particular, a `RAW` format is typically one of:
+
+          * ImageFormat#RAW_SENSOR
+          * Opaque `RAW`
+          </details>
+        </entry>
+        <entry name="maxNumOutputProc" type="int32" visibility="public" synthetic="true">
+          <description>The maximum numbers of different types of output streams
+          that can be configured and used simultaneously by a camera device
+          for any processed (but not-stalling) formats.
+          </description>
+          <range>
+          &amp;gt;= 3
+          for FULL mode devices (`android.info.supportedHardwareLevel == FULL`);
+          &amp;gt;= 2 for LIMITED mode devices (`android.info.supportedHardwareLevel == LIMITED`).
+          </range>
+          <details>
+          This value contains the max number of output simultaneous
+          streams for any processed (but not-stalling) formats.
+
+          This lists the upper bound of the number of output streams supported by
+          the camera device. Using more streams simultaneously may require more hardware and
+          CPU resources that will consume more power. The image format for this kind of an output stream can
+          be any non-`RAW` and supported format provided by android.scaler.streamConfigurationMap.
+
+          Processed (but not-stalling) is defined as any non-RAW format without a stall duration.
+          Typically:
+
+          * ImageFormat#YUV_420_888
+          * ImageFormat#NV21
+          * ImageFormat#YV12
+          * Implementation-defined formats, i.e. StreamConfiguration#isOutputSupportedFor(Class)
+
+          For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
+          a processed format -- it will return 0 for a non-stalling stream.
+          </details>
+        </entry>
+        <entry name="maxNumOutputProcStalling" type="int32" visibility="public" synthetic="true">
+          <description>The maximum numbers of different types of output streams
+          that can be configured and used simultaneously by a camera device
+          for any processed (and stalling) formats.
+          </description>
+          <range>
+          &amp;gt;= 1
+          </range>
+          <details>
+          This value contains the max number of output simultaneous
+          streams for any processed (but not-stalling) formats.
+
+          This lists the upper bound of the number of output streams supported by
+          the camera device. Using more streams simultaneously may require more hardware and
+          CPU resources that will consume more power. The image format for this kind of an output stream can
+          be any non-`RAW` and supported format provided by android.scaler.streamConfigurationMap.
+
+          A processed and stalling format is defined as any non-RAW format with a stallDurations &amp;gt; 0.
+          Typically only the `JPEG` format (ImageFormat#JPEG)
+
+          For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
+          a processed format -- it will return a non-0 value for a stalling stream.
+          </details>
+        </entry>
         <entry name="maxNumReprocessStreams" type="int32" visibility="system"
         deprecated="true" container="array">
           <array>
diff --git a/camera/docs/metadata_template.mako b/camera/docs/metadata_template.mako
index a1b9b72..91ff9c6 100644
--- a/camera/docs/metadata_template.mako
+++ b/camera/docs/metadata_template.mako
@@ -33,7 +33,7 @@
 % for typedef in metadata.types:
   <typedef name="${typedef.name}">
     % for (language, klass) in typedef.languages.iteritems():
-      <language name="${language}">${klass}</language>
+      <language name="${language}">${klass | h}</language>
     % endfor
   </typedef>
 % endfor