VideoChatTestActivity.java revision df96fff4e5162ae22eaaa32a45572d8791908908
1/*
2 * Copyright (C) 2010 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
17package com.example.android.videochatcameratest;
18
19import android.app.Activity;
20import android.graphics.ImageFormat;
21import android.hardware.Camera;
22import android.hardware.Camera.Size;
23import android.os.AsyncTask;
24import android.os.Bundle;
25import android.util.Log;
26import android.view.View;
27import android.view.View.OnClickListener;
28import android.widget.Button;
29import android.widget.CheckBox;
30import android.widget.TextView;
31
32import java.io.IOException;
33
34/**
35 * This class provides a basic demonstration of how to write an Android
36 * activity. Inside of its window, it places a single view: an EditText that
37 * displays and edits some internal text.
38 */
39public class VideoChatTestActivity extends Activity {
40
41    static final private int NUM_CAMERA_PREVIEW_BUFFERS = 2;
42
43    static final private String TAG = "VideoChatTest";
44
45    public VideoChatTestActivity() {
46    }
47
48    /** Called with the activity is first created. */
49    @Override
50    public void onCreate(Bundle savedInstanceState) {
51        super.onCreate(savedInstanceState);
52
53        // Inflate our UI from its XML layout description.
54        setContentView(R.layout.videochatcameratest_activity);
55
56        ((Button) findViewById(R.id.gobutton)).setOnClickListener(mGoListener);
57
58        ((TextView)findViewById(R.id.statushistory)).setVerticalScrollBarEnabled(true);
59
60//        // Find the text editor view inside the layout, because we
61//        // want to do various programmatic things with it.
62//        mEditor = (EditText) findViewById(R.id.editor);
63//
64//        // Hook up button presses to the appropriate event handler.
65//        ((Button) findViewById(R.id.back)).setOnClickListener(mBackListener);
66//        ((Button) findViewById(R.id.clear)).setOnClickListener(mClearListener);
67//
68//        mEditor.setText(getText(R.string.main_label));
69    }
70
71    /**
72     * Called when the activity is about to start interacting with the user.
73     */
74    @Override
75    protected void onResume() {
76        super.onResume();
77    }
78
79    /**
80     * A call-back for when the user presses the back button.
81     */
82    OnClickListener mGoListener = new OnClickListener() {
83
84        public void onClick(View v) {
85            new CameraTestRunner().execute();
86        }
87    };
88
89    private class CameraTestRunner extends AsyncTask<Void, String, Void> {
90
91        TextView mTextStatus;
92        TextView mTextStatusHistory;
93
94        @Override
95        protected Void doInBackground(Void... params) {
96            mTextStatus = (TextView)findViewById(R.id.status);
97            mTextStatusHistory = (TextView)findViewById(R.id.statushistory);
98            boolean testFrontCamera = ((CheckBox)findViewById(R.id.frontcameracheckbox)).isChecked();
99            boolean testBackCamera = ((CheckBox)findViewById(R.id.backcameracheckbox)).isChecked();
100            boolean testQVGA = ((CheckBox)findViewById(R.id.qvgacheckbox)).isChecked();
101            boolean testVGA = ((CheckBox)findViewById(R.id.vgacheckbox)).isChecked();
102            boolean test15fps = ((CheckBox)findViewById(R.id.fps15checkbox)).isChecked();
103            boolean test30fps = ((CheckBox)findViewById(R.id.fps30checkbox)).isChecked();
104
105            final int widths[] = new int[] { 320, 640 };
106            final int heights[] = new int[] { 240, 480};
107
108            final int framerates[] = new int[] { 15, 30 };
109
110            for (int whichCamera = 0; whichCamera < 2; whichCamera++) {
111                if (whichCamera == 0 && !testBackCamera) {
112                    continue;
113                }
114
115
116                if (whichCamera == 1 && !testFrontCamera) {
117                    continue;
118                }
119
120                for (int whichResolution = 0; whichResolution < 2; whichResolution++) {
121                    if (whichResolution == 0 && !testQVGA) {
122                        continue;
123                    }
124                    if (whichResolution == 1 && !testVGA) {
125                        continue;
126                    }
127
128                    for (int whichFramerate = 0; whichFramerate < 2; whichFramerate++) {
129                        if (whichFramerate == 0 && !test15fps) {
130                            continue;
131                        }
132                        if (whichFramerate == 1 && !test30fps) {
133                            continue;
134                        }
135
136                        TestCamera(whichCamera,
137                                widths[whichResolution], heights[whichResolution],
138                                framerates[whichFramerate]);
139                    }
140                }
141            }
142            // start tests
143
144            return null;
145        }
146
147        @Override
148        protected void onPostExecute(Void result) {
149            final String allDoneString = "Test complete";
150            Log.v(TAG, allDoneString);
151            mTextStatus.setText(allDoneString);
152            mTextStatusHistory.append(allDoneString + "\r\n");
153        }
154
155
156        private class FrameCatcher implements Camera.PreviewCallback {
157            public int mFrames = 0;
158
159            public FrameCatcher(int width, int height) {
160            }
161
162            @Override
163            public void onPreviewFrame(byte[] data, Camera camera) {
164                mFrames++;
165                camera.addCallbackBuffer(data);
166            }
167
168        }
169        protected void TestCamera(int whichCamera, int width, int height, int frameRate) {
170            String baseStatus = "Camera id " + whichCamera + " " +
171                width + "x" + height + " " +
172                frameRate + "fps";
173            publishProgress("Initializing " + baseStatus);
174            String status = "";
175            boolean succeeded = true;
176            Log.v(TAG, "Start test -- id " + whichCamera + " " + width + "x" + height +
177                    " " + frameRate + "fps");
178            Camera camera;
179            CameraPreviewView previewView = (CameraPreviewView)findViewById(R.id.previewrender);
180
181            camera = Camera.open(whichCamera);
182            publishProgress("Opened " + baseStatus);
183            try {
184                camera.startPreview();
185                camera.stopPreview();
186                try {
187                    camera.setPreviewDisplay(previewView.mHolder);
188                } catch (IOException exception) {
189                    succeeded = false;
190                    status = exception.toString();
191                    return;
192                }
193                camera.startPreview();
194
195                camera.setPreviewCallbackWithBuffer(null);
196                Camera.Parameters parameters = camera.getParameters();
197
198                publishProgress("Changing preview parameters " + baseStatus);
199
200                parameters.setPreviewSize(width, height);
201                parameters.setPreviewFormat(ImageFormat.NV21);
202
203                parameters.setPreviewFrameRate(frameRate);
204                camera.stopPreview();
205                camera.setParameters(parameters);
206                camera.startPreview();
207
208                publishProgress("Validating preview parameters " + baseStatus);
209
210                parameters = camera.getParameters();
211                Size setSize = parameters.getPreviewSize();
212                if (setSize.width != width || setSize.height != height) {
213                    status += "Bad reported size, wanted " + width + "x" + height + ", got " +
214                    setSize.width + "x" + setSize.height;
215                    succeeded = false;
216                }
217
218                if (parameters.getPreviewFrameRate() != frameRate) {
219                    status += "Bad reported frame rate, wanted " + frameRate
220                    + ", got " + parameters.getPreviewFrameRate();
221                    succeeded = false;
222                }
223
224                publishProgress("Initializing callback buffers " + baseStatus);
225                int imageFormat = parameters.getPreviewFormat();
226                int bufferSize;
227                bufferSize = setSize.width * setSize.height
228                                * ImageFormat.getBitsPerPixel(imageFormat) / 8;
229
230                camera.stopPreview();
231
232                for (int i = 0; i < NUM_CAMERA_PREVIEW_BUFFERS; i++) {
233                    byte [] cameraBuffer = new byte[bufferSize];
234                    camera.addCallbackBuffer(cameraBuffer);
235                }
236
237                FrameCatcher catcher = new FrameCatcher(setSize.width, setSize.height);
238                camera.setPreviewCallbackWithBuffer(catcher);
239                camera.startPreview();
240
241                if (succeeded) {
242                    publishProgress("Starting " + baseStatus);
243                } else {
244                    publishProgress("Starting " + baseStatus + " -- but " + status);
245                }
246                Log.v(TAG, "Starting rendering");
247                try {
248                    Thread.sleep(3000);
249                } catch (InterruptedException exception) {
250                    succeeded = false;
251                    status = exception.toString();
252                    return;
253                }
254
255                camera.setPreviewCallbackWithBuffer(null);
256                if (catcher.mFrames == 0) {
257                    succeeded = false;
258                    publishProgress("Preview callback received no frames from " + baseStatus);
259                } else {
260                    publishProgress("Preview callback got " + catcher.mFrames + " frames (~" +
261                            Math.round(((double)catcher.mFrames)/3.0) + "fps) " + baseStatus);
262                }
263                try {
264                    camera.setPreviewDisplay(null);
265                } catch (IOException exception) {
266                    succeeded = false;
267                    status = exception.toString();
268                    return;
269                }
270            } finally {
271                Log.v(TAG, "Releasing camera");
272
273                if (succeeded) {
274                    publishProgress("Success " + baseStatus);
275                } else {
276                    publishProgress("Finished " + baseStatus + " -- but " + status);
277                }
278
279                camera.release();
280            }
281        }
282
283        @Override
284        protected void onProgressUpdate(String... message) {
285            Log.v(TAG, message[0]);
286            mTextStatus.setText(message[0]);
287            mTextStatusHistory.append(message[0] + "\r\n");
288        }
289    }
290}
291