1ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu/* 2ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * Copyright (C) 2012 The Android Open Source Project 3ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * 4ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * Licensed under the Apache License, Version 2.0 (the "License"); 5ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * you may not use this file except in compliance with the License. 6ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * You may obtain a copy of the License at 7ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * 8ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * http://www.apache.org/licenses/LICENSE-2.0 9ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * 10ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * Unless required by applicable law or agreed to in writing, software 11ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * distributed under the License is distributed on an "AS IS" BASIS, 12ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * See the License for the specific language governing permissions and 14ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * limitations under the License. 15ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu */ 16ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 17ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liupackage com.android.camera.stress; 18ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 19ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport android.app.Instrumentation; 20ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport android.os.Environment; 21ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport android.test.ActivityInstrumentationTestCase2; 22ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport android.test.suitebuilder.annotation.LargeTest; 23ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport android.util.Log; 24ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport android.view.KeyEvent; 25ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport com.android.camera.CameraActivity; 26ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport java.io.BufferedWriter; 27ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport java.io.File; 28ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport java.io.FilenameFilter; 29ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport java.io.FileWriter; 30ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport java.io.IOException; 31ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liuimport java.util.ArrayList; 32ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 33ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu/** 34ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu * Junit / Instrumentation test case for measuring camera shot to shot latency 35ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu */ 36ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liupublic class ShotToShotLatency extends ActivityInstrumentationTestCase2<CameraActivity> { 37ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu private String TAG = "ShotToShotLatency"; 38ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu private static final int TOTAL_NUMBER_OF_SNAPSHOTS = 250; 39ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu private static final long SNAPSHOT_WAIT = 1000; 40ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu private static final String CAMERA_TEST_OUTPUT_FILE = 41ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt"; 42ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu private static final String CAMERA_IMAGE_DIRECTORY = 43ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera/"; 44ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 45ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu public ShotToShotLatency() { 46ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu super(CameraActivity.class); 47ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 48ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 49ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu @Override 50ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu protected void setUp() throws Exception { 51ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu getActivity(); 52ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu super.setUp(); 53ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 54ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 55ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu @Override 56ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu protected void tearDown() throws Exception { 57ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu super.tearDown(); 58ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 59ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 60ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu private void cleanupLatencyImages() { 61ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu try { 62ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu File sdcard = new File(CAMERA_IMAGE_DIRECTORY); 63ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu File[] pics = null; 64ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu FilenameFilter filter = new FilenameFilter() { 65ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu public boolean accept(File dir, String name) { 66ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu return name.endsWith(".jpg"); 67ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 68ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu }; 69ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu pics = sdcard.listFiles(filter); 70ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu for (File f : pics) { 71ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu f.delete(); 72ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 73ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } catch (SecurityException e) { 74ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Log.e(TAG, "Security manager access violation: " + e.toString()); 75ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 76ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 77ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 78ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu private void sleep(long time) { 79ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu try { 80ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Thread.sleep(time); 81ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } catch (InterruptedException e) { 82ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Log.e(TAG, "Sleep InterruptedException " + e.toString()); 83ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 84ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 85ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 86ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu @LargeTest 87ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu public void testShotToShotLatency() { 88ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu long sigmaOfDiffFromMeanSquared = 0; 89ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu double mean = 0; 90ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu double standardDeviation = 0; 91ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu ArrayList<Long> captureTimes = new ArrayList<Long>(); 92ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu ArrayList<Long> latencyTimes = new ArrayList<Long>(); 93ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 94ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Log.v(TAG, "start testShotToShotLatency test"); 95ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Instrumentation inst = getInstrumentation(); 96ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 97ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu // Generate data points 98ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu for (int i = 0; i < TOTAL_NUMBER_OF_SNAPSHOTS; i++) { 99ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); 100ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu sleep(SNAPSHOT_WAIT); 101ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu CameraActivity c = getActivity(); 102ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu if (c.getCaptureStartTime() > 0) { 103ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu captureTimes.add(c.getCaptureStartTime()); 104ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 105ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 106ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 107ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu // Calculate latencies 108ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu for (int j = 1; j < captureTimes.size(); j++) { 109ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu latencyTimes.add(captureTimes.get(j) - captureTimes.get(j - 1)); 110ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 111ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 112ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu // Crunch numbers 113ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu for (long dataPoint : latencyTimes) { 114ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu mean += (double) dataPoint; 115ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 116ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu mean /= latencyTimes.size(); 117ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 118ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu for (long dataPoint : latencyTimes) { 119ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu sigmaOfDiffFromMeanSquared += (dataPoint - mean) * (dataPoint - mean); 120ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 121ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu standardDeviation = Math.sqrt(sigmaOfDiffFromMeanSquared / latencyTimes.size()); 122ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu 123ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu // Report statistics 124ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu File outFile = new File(CAMERA_TEST_OUTPUT_FILE); 125ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu BufferedWriter output = null; 126ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu try { 127ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu output = new BufferedWriter(new FileWriter(outFile, true)); 128ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu output.write("Shot to shot latency - mean: " + mean + "\n"); 129ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu output.write("Shot to shot latency - standard deviation: " + standardDeviation + "\n"); 130ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu cleanupLatencyImages(); 131ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } catch (IOException e) { 132ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Log.e(TAG, "testShotToShotLatency IOException writing to log " + e.toString()); 133ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } finally { 134ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu try { 135ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu if (output != null) { 136ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu output.close(); 137ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 138ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } catch (IOException e) { 139ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu Log.e(TAG, "Error closing file: " + e.toString()); 140ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 141ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 142ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu } 143ffa6237aed496373cd578ccdb9d2a47cde90e25dDoris Liu} 144