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") MarshalerRange(TypeReference<Range<T>> typeReference, int nativeType)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 marshal(Range<T> value, ByteBuffer buffer)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 unmarshal(ByteBuffer buffer)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 getNativeSize()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 calculateMarshalSize(Range<T> value)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 createMarshaler(TypeReference<Range<T>> managedType, int nativeType)126 public Marshaler<Range<T>> createMarshaler(TypeReference<Range<T>> managedType, 127 int nativeType) { 128 return new MarshalerRange(managedType, nativeType); 129 } 130 131 @Override isTypeMappingSupported(TypeReference<Range<T>> managedType, int nativeType)132 public boolean isTypeMappingSupported(TypeReference<Range<T>> managedType, int nativeType) { 133 return (Range.class.equals(managedType.getRawType())); 134 } 135 136 } 137