Home | History | Annotate | Download | only in testingcamera2
      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 
     17 package com.android.testingcamera2;
     18 
     19 import java.util.ArrayList;
     20 import java.util.List;
     21 
     22 import android.content.Context;
     23 import android.hardware.camera2.CameraCharacteristics;
     24 import android.hardware.camera2.params.StreamConfigurationMap;
     25 import android.util.Size;
     26 import android.util.AttributeSet;
     27 import android.util.Size;
     28 import android.view.LayoutInflater;
     29 import android.view.Surface;
     30 import android.view.SurfaceHolder;
     31 import android.view.SurfaceView;
     32 import android.view.View;
     33 import android.widget.AdapterView;
     34 import android.widget.ArrayAdapter;
     35 import android.widget.LinearLayout;
     36 import android.widget.Spinner;
     37 import android.widget.AdapterView.OnItemSelectedListener;
     38 
     39 public class SurfaceViewSubPane extends TargetSubPane implements SurfaceHolder.Callback {
     40 
     41     private static final int NO_SIZE = -1;
     42     private final FixedAspectSurfaceView mFixedSurfaceView;
     43     private Surface mSurface;
     44 
     45     private final Spinner mSizeSpinner;
     46     private Size[] mSizes;
     47     private int mCurrentCameraOrientation = 0;
     48     private int mCurrentUiOrientation = 0;
     49 
     50     private int mCurrentSizeId = NO_SIZE;
     51     private CameraControlPane mCurrentCamera;
     52 
     53     private float mAspectRatio = DEFAULT_ASPECT_RATIO;
     54 
     55     private static final float DEFAULT_ASPECT_RATIO = 1.5f;
     56 
     57     public SurfaceViewSubPane(Context context, AttributeSet attrs) {
     58         super(context, attrs);
     59 
     60         LayoutInflater inflater =
     61                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     62 
     63         inflater.inflate(R.layout.surfaceview_target_subpane, this);
     64         this.setOrientation(VERTICAL);
     65 
     66         mFixedSurfaceView = (FixedAspectSurfaceView) this.findViewById(R.id.target_subpane_surface_view_view);
     67         mFixedSurfaceView.getHolder().addCallback(this);
     68         mSizeSpinner = (Spinner) this.findViewById(R.id.target_subpane_surface_view_size_spinner);
     69         mSizeSpinner.setOnItemSelectedListener(mSizeSpinnerListener);
     70     }
     71 
     72     @Override
     73     public void setTargetCameraPane(CameraControlPane target) {
     74         if (target != null) {
     75             Size oldSize = null;
     76             if (mCurrentSizeId != NO_SIZE) {
     77                 oldSize = mSizes[mCurrentSizeId];
     78             }
     79 
     80             CameraCharacteristics info = target.getCharacteristics();
     81             {
     82                 StreamConfigurationMap streamConfigMap =
     83                         info.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
     84                 mSizes = streamConfigMap.getOutputSizes(SurfaceHolder.class);
     85             }
     86 
     87             int newSelectionId = 0;
     88             for (int i = 0; i < mSizes.length; i++) {
     89                 if (mSizes[i].equals(oldSize)) {
     90                     newSelectionId = i;
     91                     break;
     92                 }
     93             }
     94             String[] outputSizeItems = new String[mSizes.length];
     95             for (int i = 0; i < outputSizeItems.length; i++) {
     96                 outputSizeItems[i] = mSizes[i].toString();
     97             }
     98 
     99             mSizeSpinner.setAdapter(new ArrayAdapter<String>(getContext(), R.layout.spinner_item,
    100                     outputSizeItems));
    101             mSizeSpinner.setSelection(newSelectionId);
    102 
    103             // Map sensor orientation to Surface.ROTATE_* constants
    104             final int SENSOR_ORIENTATION_TO_SURFACE_ROTATE = 90;
    105             mCurrentCameraOrientation = info.get(CameraCharacteristics.SENSOR_ORIENTATION) /
    106                     SENSOR_ORIENTATION_TO_SURFACE_ROTATE;
    107 
    108             updateAspectRatio();
    109         } else {
    110             mSizeSpinner.setAdapter(null);
    111             mCurrentSizeId = NO_SIZE;
    112         }
    113     }
    114 
    115     @Override
    116     public void setUiOrientation(int orientation) {
    117         mCurrentUiOrientation = orientation;
    118         updateAspectRatio();
    119     }
    120 
    121     private void updateSizes() {
    122         if (mCurrentSizeId != NO_SIZE) {
    123             Size s = mSizes[mCurrentSizeId];
    124             mFixedSurfaceView.getHolder().setFixedSize(s.getWidth(), s.getHeight());
    125             mAspectRatio = ((float) s.getWidth()) / s.getHeight();
    126         } else {
    127             // Make sure the view has some reasonable size even when there's no
    128             // target camera for aspect-ratio correct sizing
    129             mAspectRatio = DEFAULT_ASPECT_RATIO;
    130         }
    131         updateAspectRatio();
    132     }
    133 
    134     private void updateAspectRatio() {
    135         // Swap aspect ratios when the UI orientation and the camera orientation don't line up
    136         boolean swapAspect = Math.abs(mCurrentUiOrientation - mCurrentCameraOrientation) % 2 == 1;
    137         if (swapAspect) {
    138             mFixedSurfaceView.setAspectRatio(1/mAspectRatio);
    139         } else {
    140             mFixedSurfaceView.setAspectRatio(mAspectRatio);
    141         }
    142     }
    143 
    144     @Override
    145     public Surface getOutputSurface() {
    146         return mSurface;
    147     }
    148 
    149     private final OnItemSelectedListener mSizeSpinnerListener = new OnItemSelectedListener() {
    150         @Override
    151         public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
    152             mCurrentSizeId = pos;
    153             updateSizes();
    154         };
    155 
    156         @Override
    157         public void onNothingSelected(AdapterView<?> parent) {
    158             mCurrentSizeId = NO_SIZE;
    159         };
    160     };
    161 
    162     @Override
    163     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    164         mSurface = holder.getSurface();
    165     }
    166 
    167     @Override
    168     public void surfaceCreated(SurfaceHolder holder) {
    169 
    170     }
    171 
    172     @Override
    173     public void surfaceDestroyed(SurfaceHolder holder) {
    174 
    175     }
    176 
    177 }
    178