Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package android.hardware.camera2.marshal.impl;
     17 
     18 import android.hardware.camera2.marshal.Marshaler;
     19 import android.hardware.camera2.marshal.MarshalQueryable;
     20 import android.hardware.camera2.marshal.MarshalRegistry;
     21 import android.hardware.camera2.utils.TypeReference;
     22 import android.util.Range;
     23 
     24 import java.lang.reflect.Constructor;
     25 import java.lang.reflect.InvocationTargetException;
     26 import java.lang.reflect.ParameterizedType;
     27 import java.lang.reflect.Type;
     28 import java.nio.ByteBuffer;
     29 
     30 import static android.hardware.camera2.impl.CameraMetadataNative.*;
     31 import static android.hardware.camera2.marshal.MarshalHelpers.*;
     32 
     33 /**
     34  * Marshal {@link Range} to/from any native type
     35  */
     36 public class MarshalQueryableRange<T extends Comparable<? super T>>
     37         implements MarshalQueryable<Range<T>> {
     38     private static final int RANGE_COUNT = 2;
     39 
     40     private class MarshalerRange extends Marshaler<Range<T>> {
     41         private final Class<? super Range<T>> mClass;
     42         private final Constructor<Range<T>> mConstructor;
     43         /** Marshal the {@code T} inside of {@code Range<T>} */
     44         private final Marshaler<T> mNestedTypeMarshaler;
     45 
     46         @SuppressWarnings("unchecked")
     47         protected MarshalerRange(TypeReference<Range<T>> typeReference,
     48                 int nativeType) {
     49             super(MarshalQueryableRange.this, typeReference, nativeType);
     50 
     51             mClass = typeReference.getRawType();
     52 
     53             /*
     54              * Lookup the actual type argument, e.g. Range<Integer> --> Integer
     55              * and then get the marshaler for that managed type.
     56              */
     57             ParameterizedType paramType;
     58             try {
     59                 paramType = (ParameterizedType) typeReference.getType();
     60             } catch (ClassCastException e) {
     61                 throw new AssertionError("Raw use of Range is not supported", e);
     62             }
     63             Type actualTypeArgument = paramType.getActualTypeArguments()[0];
     64 
     65             TypeReference<?> actualTypeArgToken =
     66                     TypeReference.createSpecializedTypeReference(actualTypeArgument);
     67 
     68             mNestedTypeMarshaler = (Marshaler<T>)MarshalRegistry.getMarshaler(
     69                     actualTypeArgToken, mNativeType);
     70             try {
     71                 mConstructor = (Constructor<Range<T>>)mClass.getConstructor(
     72                         Comparable.class, Comparable.class);
     73             } catch (NoSuchMethodException e) {
     74                 throw new AssertionError(e);
     75             }
     76         }
     77 
     78         @Override
     79         public void marshal(Range<T> value, ByteBuffer buffer) {
     80             mNestedTypeMarshaler.marshal(value.getLower(), buffer);
     81             mNestedTypeMarshaler.marshal(value.getUpper(), buffer);
     82         }
     83 
     84         @Override
     85         public Range<T> unmarshal(ByteBuffer buffer) {
     86             T lower = mNestedTypeMarshaler.unmarshal(buffer);
     87             T upper = mNestedTypeMarshaler.unmarshal(buffer);
     88 
     89             try {
     90                 return mConstructor.newInstance(lower, upper);
     91             } catch (InstantiationException e) {
     92                 throw new AssertionError(e);
     93             } catch (IllegalAccessException e) {
     94                 throw new AssertionError(e);
     95             } catch (IllegalArgumentException e) {
     96                 throw new AssertionError(e);
     97             } catch (InvocationTargetException e) {
     98                 throw new AssertionError(e);
     99             }
    100         }
    101 
    102         @Override
    103         public int getNativeSize() {
    104             int nestedSize = mNestedTypeMarshaler.getNativeSize();
    105 
    106             if (nestedSize != NATIVE_SIZE_DYNAMIC) {
    107                 return nestedSize * RANGE_COUNT;
    108             } else {
    109                 return NATIVE_SIZE_DYNAMIC;
    110             }
    111         }
    112 
    113         @Override
    114         public int calculateMarshalSize(Range<T> value) {
    115             int nativeSize = getNativeSize();
    116 
    117             if (nativeSize != NATIVE_SIZE_DYNAMIC) {
    118                 return nativeSize;
    119             } else {
    120                 int lowerSize = mNestedTypeMarshaler.calculateMarshalSize(value.getLower());
    121                 int upperSize = mNestedTypeMarshaler.calculateMarshalSize(value.getUpper());
    122 
    123                 return lowerSize + upperSize;
    124             }
    125         }
    126     }
    127 
    128     @Override
    129     public Marshaler<Range<T>> createMarshaler(TypeReference<Range<T>> managedType,
    130             int nativeType) {
    131         return new MarshalerRange(managedType, nativeType);
    132     }
    133 
    134     @Override
    135     public boolean isTypeMappingSupported(TypeReference<Range<T>> managedType, int nativeType) {
    136         return (Range.class.equals(managedType.getRawType()));
    137     }
    138 
    139 }
    140