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