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.graphics.SurfaceTexture;
24 import android.hardware.camera2.CameraCharacteristics;
25 import android.hardware.camera2.params.StreamConfigurationMap;
26 import android.util.Size;
27 import android.util.AttributeSet;
28 import android.util.Size;
29 import android.view.LayoutInflater;
30 import android.view.Surface;
31 import android.view.SurfaceHolder;
32 import android.view.TextureView;
33 import android.view.View;
34 import android.widget.AdapterView;
35 import android.widget.ArrayAdapter;
36 import android.widget.LinearLayout;
37 import android.widget.Spinner;
38 import android.widget.AdapterView.OnItemSelectedListener;
39 
40 public class TextureViewSubPane extends TargetSubPane implements TextureView.SurfaceTextureListener {
41 
42     private static final int NO_SIZE = -1;
43     private final TextureView mTextureView;
44     private SurfaceTexture mSurfaceTexture;
45 
46     private final Spinner mSizeSpinner;
47     private Size[] mSizes;
48     private int mCurrentSizeId = NO_SIZE;
49     private CameraControlPane mCurrentCamera;
50 
TextureViewSubPane(Context context, AttributeSet attrs)51     public TextureViewSubPane(Context context, AttributeSet attrs) {
52         super(context, attrs);
53 
54         LayoutInflater inflater =
55                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
56 
57         inflater.inflate(R.layout.textureview_target_subpane, this);
58         this.setOrientation(VERTICAL);
59 
60         mTextureView = (TextureView) this.findViewById(R.id.target_subpane_texture_view_view);
61         mTextureView.setSurfaceTextureListener(this);
62         mSizeSpinner = (Spinner) this.findViewById(R.id.target_subpane_texture_view_size_spinner);
63         mSizeSpinner.setOnItemSelectedListener(mSizeSpinnerListener);
64     }
65 
66     @Override
setTargetCameraPane(CameraControlPane target)67     public void setTargetCameraPane(CameraControlPane target) {
68         if (target != null) {
69             Size oldSize = null;
70             if (mCurrentSizeId != NO_SIZE) {
71                 oldSize = mSizes[mCurrentSizeId];
72             }
73 
74             {
75                 CameraCharacteristics info = target.getCharacteristics();
76                 StreamConfigurationMap streamConfigMap =
77                         info.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
78                 mSizes = streamConfigMap.getOutputSizes(SurfaceTexture.class);
79             }
80 
81             int newSelectionId = 0;
82             for (int i = 0; i < mSizes.length; i++) {
83                 if (mSizes[i].equals(oldSize)) {
84                     newSelectionId = i;
85                     break;
86                 }
87             }
88             String[] outputSizeItems = new String[mSizes.length];
89             for (int i = 0; i < outputSizeItems.length; i++) {
90                 outputSizeItems[i] = mSizes[i].toString();
91             }
92 
93             mSizeSpinner.setAdapter(new ArrayAdapter<String>(getContext(), R.layout.spinner_item,
94                     outputSizeItems));
95             mSizeSpinner.setSelection(newSelectionId);
96         } else {
97             mSizeSpinner.setAdapter(null);
98             mCurrentSizeId = NO_SIZE;
99         }
100     }
101 
102     @Override
setUiOrientation(int orientation)103     public void setUiOrientation(int orientation) {
104         // TODO Auto-generated method stub
105 
106     }
107 
updateSizes()108     private void updateSizes() {
109         if (mCurrentSizeId != NO_SIZE) {
110             Size s = mSizes[mCurrentSizeId];
111             if (mSurfaceTexture != null) {
112                 mSurfaceTexture.setDefaultBufferSize(s.getWidth(), s.getHeight());
113             }
114             int width = getWidth();
115             int height = width * s.getHeight() / s.getWidth();
116             mTextureView.setLayoutParams(new LinearLayout.LayoutParams(width, height));
117         } else {
118             // Make sure the view has some reasonable size even when there's no
119             // target camera for aspect-ratio correct sizing
120             int width = getWidth();
121             int height = width / 2;
122             mTextureView.setLayoutParams(new LinearLayout.LayoutParams(width, height));
123         }
124     }
125 
126     @Override
getOutputSurface()127     public Surface getOutputSurface() {
128         return (mSurfaceTexture != null) ? new Surface(mSurfaceTexture) : null;
129     }
130 
131     private final OnItemSelectedListener mSizeSpinnerListener = new OnItemSelectedListener() {
132         @Override
133         public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
134             mCurrentSizeId = pos;
135             updateSizes();
136         };
137 
138         @Override
139         public void onNothingSelected(AdapterView<?> parent) {
140             mCurrentSizeId = NO_SIZE;
141         };
142     };
143 
144     @Override
onSurfaceTextureAvailable(final SurfaceTexture surface, final int width, final int height)145     public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width,
146             final int height) {
147         mSurfaceTexture = surface;
148         updateSizes();
149     }
150 
151     @Override
onSurfaceTextureDestroyed(SurfaceTexture surface)152     public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
153         return false;
154     }
155 
156     @Override
onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)157     public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
158         // ignore
159     }
160 
161     @Override
onSurfaceTextureUpdated(SurfaceTexture surface)162     public void onSurfaceTextureUpdated(SurfaceTexture surface) {
163         // ignore
164     }
165 }
166