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 /**
     31  * Marshal {@link Range} to/from any native type
     32  */
     33 public class MarshalQueryableRange<T extends Comparable<? super T>>
     34         implements MarshalQueryable<Range<T>> {
     35     private static final int RANGE_COUNT = 2;
     36 
     37     private class MarshalerRange extends Marshaler<Range<T>> {
     38         private final Class<? super Range<T>> mClass;
     39         private final Constructor<Range<T>> mConstructor;
     40         /** Marshal the {@code T} inside of {@code Range<T>} */
     41         private final Marshaler<T> mNestedTypeMarshaler;
     42 
     43         @SuppressWarnings("unchecked")
     44         protected MarshalerRange(TypeReference<Range<T>> typeReference,
     45                 int nativeType) {
     46             super(MarshalQueryableRange.this, typeReference, nativeType);
     47 
     48             mClass = typeReference.getRawType();
     49 
     50             /*
     51              * Lookup the actual type argument, e.g. Range<Integer> --> Integer
     52              * and then get the marshaler for that managed type.
     53              */
     54             ParameterizedType paramType;
     55             try {
     56                 paramType = (ParameterizedType) typeReference.getType();
     57             } catch (ClassCastException e) {
     58                 throw new AssertionError("Raw use of Range is not supported", e);
     59             }
     60             Type actualTypeArgument = paramType.getActualTypeArguments()[0];
     61 
     62             TypeReference<?> actualTypeArgToken =
     63                     TypeReference.createSpecializedTypeReference(actualTypeArgument);
     64 
     65             mNestedTypeMarshaler = (Marshaler<T>)MarshalRegistry.getMarshaler(
     66                     actualTypeArgToken, mNativeType);
     67             try {
     68                 mConstructor = (Constructor<Range<T>>)mClass.getConstructor(
     69                         Comparable.class, Comparable.class);
     70             } catch (NoSuchMethodException e) {
     71                 throw new AssertionError(e);
     72             }
     73         }
     74 
     75         @Override
     76         public void marshal(Range<T> value, ByteBuffer buffer) {
     77             mNestedTypeMarshaler.marshal(value.getLower(), buffer);
     78             mNestedTypeMarshaler.marshal(value.getUpper(), buffer);
     79         }
     80 
     81         @Override
     82         public Range<T> unmarshal(ByteBuffer buffer) {
     83             T lower = mNestedTypeMarshaler.unmarshal(buffer);
     84             T upper = mNestedTypeMarshaler.unmarshal(buffer);
     85 
     86             try {
     87                 return mConstructor.newInstance(lower, upper);
     88             } catch (InstantiationException e) {
     89                 throw new AssertionError(e);
     90             } catch (IllegalAccessException e) {
     91                 throw new AssertionError(e);
     92             } catch (IllegalArgumentException e) {
     93                 throw new AssertionError(e);
     94             } catch (InvocationTargetException e) {
     95                 throw new AssertionError(e);
     96             }
     97         }
     98 
     99         @Override
    100         public int getNativeSize() {
    101             int nestedSize = mNestedTypeMarshaler.getNativeSize();
    102 
    103             if (nestedSize != NATIVE_SIZE_DYNAMIC) {
    104                 return nestedSize * RANGE_COUNT;
    105             } else {
    106                 return NATIVE_SIZE_DYNAMIC;
    107             }
    108         }
    109 
    110         @Override
    111         public int calculateMarshalSize(Range<T> value) {
    112             int nativeSize = getNativeSize();
    113 
    114             if (nativeSize != NATIVE_SIZE_DYNAMIC) {
    115                 return nativeSize;
    116             } else {
    117                 int lowerSize = mNestedTypeMarshaler.calculateMarshalSize(value.getLower());
    118                 int upperSize = mNestedTypeMarshaler.calculateMarshalSize(value.getUpper());
    119 
    120                 return lowerSize + upperSize;
    121             }
    122         }
    123     }
    124 
    125     @Override
    126     public Marshaler<Range<T>> createMarshaler(TypeReference<Range<T>> managedType,
    127             int nativeType) {
    128         return new MarshalerRange(managedType, nativeType);
    129     }
    130 
    131     @Override
    132     public boolean isTypeMappingSupported(TypeReference<Range<T>> managedType, int nativeType) {
    133         return (Range.class.equals(managedType.getRawType()));
    134     }
    135 
    136 }
    137