17c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala/*
27c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * Copyright (C) 2014 The Android Open Source Project
37c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *
47c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
57c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * you may not use this file except in compliance with the License.
67c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * You may obtain a copy of the License at
77c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *
87c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
97c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *
107c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
117c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
127c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * See the License for the specific language governing permissions and
147c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * limitations under the License.
157c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala */
167c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
177c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalapackage com.android.testingcamera2;
187c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
197c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport java.util.ArrayList;
207c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport java.util.List;
217c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
227c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.content.Context;
237c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.graphics.SurfaceTexture;
247c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.hardware.camera2.CameraCharacteristics;
25684d44a36b4ac32e2e162caf9ce4e625bd13b555Igor Murashkinimport android.hardware.camera2.params.StreamConfigurationMap;
26e82937211409e869f32c8398ee16ce6bb77bfce6Igor Murashkinimport android.util.Size;
277c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.util.AttributeSet;
280b631a014c90c9053a8e17be141351abab66d30eEino-Ville Talvalaimport android.util.Size;
297c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.view.LayoutInflater;
307c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.view.Surface;
31e82937211409e869f32c8398ee16ce6bb77bfce6Igor Murashkinimport android.view.SurfaceHolder;
327c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.view.TextureView;
337c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.view.View;
347c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.widget.AdapterView;
357c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.widget.ArrayAdapter;
367c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.widget.LinearLayout;
377c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.widget.Spinner;
387c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.widget.AdapterView.OnItemSelectedListener;
397c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
407c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalapublic class TextureViewSubPane extends TargetSubPane implements TextureView.SurfaceTextureListener {
417c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
427c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    private static final int NO_SIZE = -1;
43684d44a36b4ac32e2e162caf9ce4e625bd13b555Igor Murashkin    private final TextureView mTextureView;
447c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    private SurfaceTexture mSurfaceTexture;
457c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
46684d44a36b4ac32e2e162caf9ce4e625bd13b555Igor Murashkin    private final Spinner mSizeSpinner;
477c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    private Size[] mSizes;
487c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    private int mCurrentSizeId = NO_SIZE;
497c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    private CameraControlPane mCurrentCamera;
507c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
517c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public TextureViewSubPane(Context context, AttributeSet attrs) {
527c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        super(context, attrs);
537c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
547c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        LayoutInflater inflater =
557c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
567c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
577c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        inflater.inflate(R.layout.textureview_target_subpane, this);
587c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        this.setOrientation(VERTICAL);
597c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
607c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        mTextureView = (TextureView) this.findViewById(R.id.target_subpane_texture_view_view);
617c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        mTextureView.setSurfaceTextureListener(this);
627c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        mSizeSpinner = (Spinner) this.findViewById(R.id.target_subpane_texture_view_size_spinner);
637c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        mSizeSpinner.setOnItemSelectedListener(mSizeSpinnerListener);
647c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
657c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
667c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
677c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public void setTargetCameraPane(CameraControlPane target) {
687c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        if (target != null) {
697c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            Size oldSize = null;
707c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            if (mCurrentSizeId != NO_SIZE) {
717c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                oldSize = mSizes[mCurrentSizeId];
727c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            }
737c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
74e82937211409e869f32c8398ee16ce6bb77bfce6Igor Murashkin            {
75e82937211409e869f32c8398ee16ce6bb77bfce6Igor Murashkin                CameraCharacteristics info = target.getCharacteristics();
76e82937211409e869f32c8398ee16ce6bb77bfce6Igor Murashkin                StreamConfigurationMap streamConfigMap =
77e82937211409e869f32c8398ee16ce6bb77bfce6Igor Murashkin                        info.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
78e82937211409e869f32c8398ee16ce6bb77bfce6Igor Murashkin                mSizes = streamConfigMap.getOutputSizes(SurfaceTexture.class);
797c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            }
807c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
817c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            int newSelectionId = 0;
827c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            for (int i = 0; i < mSizes.length; i++) {
837c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                if (mSizes[i].equals(oldSize)) {
847c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                    newSelectionId = i;
857c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                    break;
867c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                }
877c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            }
887c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            String[] outputSizeItems = new String[mSizes.length];
897c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            for (int i = 0; i < outputSizeItems.length; i++) {
907c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                outputSizeItems[i] = mSizes[i].toString();
917c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            }
927c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
937c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mSizeSpinner.setAdapter(new ArrayAdapter<String>(getContext(), R.layout.spinner_item,
947c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                    outputSizeItems));
957c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mSizeSpinner.setSelection(newSelectionId);
967c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        } else {
977c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mSizeSpinner.setAdapter(null);
987c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mCurrentSizeId = NO_SIZE;
997c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1007c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1017c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1020b631a014c90c9053a8e17be141351abab66d30eEino-Ville Talvala    @Override
1030b631a014c90c9053a8e17be141351abab66d30eEino-Ville Talvala    public void setUiOrientation(int orientation) {
1040b631a014c90c9053a8e17be141351abab66d30eEino-Ville Talvala        // TODO Auto-generated method stub
1050b631a014c90c9053a8e17be141351abab66d30eEino-Ville Talvala
1060b631a014c90c9053a8e17be141351abab66d30eEino-Ville Talvala    }
1070b631a014c90c9053a8e17be141351abab66d30eEino-Ville Talvala
1087c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    private void updateSizes() {
1097c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        if (mCurrentSizeId != NO_SIZE) {
1107c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            Size s = mSizes[mCurrentSizeId];
1117c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            if (mSurfaceTexture != null) {
1127c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                mSurfaceTexture.setDefaultBufferSize(s.getWidth(), s.getHeight());
1137c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            }
1147c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            int width = getWidth();
1157c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            int height = width * s.getHeight() / s.getWidth();
1167c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mTextureView.setLayoutParams(new LinearLayout.LayoutParams(width, height));
1177c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        } else {
1187c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            // Make sure the view has some reasonable size even when there's no
1197c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            // target camera for aspect-ratio correct sizing
1207c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            int width = getWidth();
1217c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            int height = width / 2;
1227c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mTextureView.setLayoutParams(new LinearLayout.LayoutParams(width, height));
1237c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1247c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1257c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1267c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
1277c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public Surface getOutputSurface() {
1287c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        return (mSurfaceTexture != null) ? new Surface(mSurfaceTexture) : null;
1297c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1307c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
131684d44a36b4ac32e2e162caf9ce4e625bd13b555Igor Murashkin    private final OnItemSelectedListener mSizeSpinnerListener = new OnItemSelectedListener() {
1327c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        @Override
1337c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
1347c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mCurrentSizeId = pos;
1357c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            updateSizes();
1367c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        };
1377c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1387c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        @Override
1397c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        public void onNothingSelected(AdapterView<?> parent) {
1407c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mCurrentSizeId = NO_SIZE;
1417c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        };
1427c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    };
1437c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1447c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
1457c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width,
1467c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            final int height) {
1477c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        mSurfaceTexture = surface;
1487c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        updateSizes();
1497c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1507c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1517c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
1527c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
1537c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        return false;
1547c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1557c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1567c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
1577c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
1587c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        // ignore
1597c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1607c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1617c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
1627c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
1637c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        // ignore
1647c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1657c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala}
166