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.cts.verifier.camera.its; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.res.Configuration; 24 import android.hardware.camera2.CameraAccessException; 25 import android.hardware.camera2.CameraCharacteristics; 26 import android.hardware.camera2.CameraManager; 27 import android.os.Bundle; 28 import android.util.Log; 29 import android.view.WindowManager; 30 import android.widget.Toast; 31 32 import java.util.ArrayList; 33 import java.util.HashSet; 34 import java.util.HashMap; 35 import java.util.Arrays; 36 import java.util.List; 37 import java.io.BufferedReader; 38 import java.io.FileReader; 39 import java.io.FileNotFoundException; 40 import java.io.IOException; 41 42 import com.android.compatibility.common.util.ResultType; 43 import com.android.compatibility.common.util.ResultUnit; 44 import com.android.cts.verifier.PassFailButtons; 45 import com.android.cts.verifier.R; 46 47 48 /** 49 * Test for Camera features that require that the camera be aimed at a specific test scene. 50 * This test activity requires a USB connection to a computer, and a corresponding host-side run of 51 * the python scripts found in the CameraITS directory. 52 */ 53 public class ItsTestActivity extends PassFailButtons.Activity { 54 private static final String TAG = "ItsTestActivity"; 55 private static final String EXTRA_CAMERA_ID = "camera.its.extra.CAMERA_ID"; 56 private static final String EXTRA_SUCCESS = "camera.its.extra.SUCCESS"; 57 private static final String EXTRA_SUMMARY = "camera.its.extra.SUMMARY"; 58 private static final String ACTION_ITS_RESULT = 59 "com.android.cts.verifier.camera.its.ACTION_ITS_RESULT"; 60 61 class SuccessReceiver extends BroadcastReceiver { 62 @Override onReceive(Context context, Intent intent)63 public void onReceive(Context context, Intent intent) { 64 Log.i(TAG, "Received result for Camera ITS tests"); 65 if (ACTION_ITS_RESULT.equals(intent.getAction())) { 66 String cameraId = intent.getStringExtra(EXTRA_CAMERA_ID); 67 String result = intent.getStringExtra(EXTRA_SUCCESS); 68 String summaryPath = intent.getStringExtra(EXTRA_SUMMARY); 69 if (!mNonLegacyCameraIds.contains(cameraId)) { 70 Log.e(TAG, "Unknown camera id " + cameraId + " reported to ITS"); 71 return; 72 } 73 74 Log.i(TAG, "ITS summary path is: " + summaryPath); 75 mSummaryMap.put(cameraId, summaryPath); 76 // Create summary report 77 if (mSummaryMap.keySet().containsAll(mNonLegacyCameraIds)) { 78 StringBuilder summary = new StringBuilder(); 79 for (String id : mNonLegacyCameraIds) { 80 String path = mSummaryMap.get(id); 81 appendFileContentToSummary(summary, path); 82 } 83 ItsTestActivity.this.getReportLog().setSummary( 84 summary.toString(), 1.0, ResultType.NEUTRAL, ResultUnit.NONE); 85 } 86 boolean pass = result.equals("True"); 87 if(pass) { 88 Log.i(TAG, "Received Camera " + cameraId + " ITS SUCCESS from host."); 89 mITSPassedCameraIds.add(cameraId); 90 if (mNonLegacyCameraIds != null && mNonLegacyCameraIds.size() != 0 && 91 mITSPassedCameraIds.containsAll(mNonLegacyCameraIds)) { 92 ItsTestActivity.this.showToast(R.string.its_test_passed); 93 ItsTestActivity.this.getPassButton().setEnabled(true); 94 } 95 } else { 96 Log.i(TAG, "Received Camera " + cameraId + " ITS FAILURE from host."); 97 ItsTestActivity.this.showToast(R.string.its_test_failed); 98 } 99 } 100 } 101 appendFileContentToSummary(StringBuilder summary, String path)102 private void appendFileContentToSummary(StringBuilder summary, String path) { 103 BufferedReader reader = null; 104 try { 105 reader = new BufferedReader(new FileReader(path)); 106 String line = null; 107 do { 108 line = reader.readLine(); 109 if (line != null) { 110 summary.append(line); 111 } 112 } while (line != null); 113 } catch (FileNotFoundException e) { 114 Log.e(TAG, "Cannot find ITS summary file at " + path); 115 summary.append("Cannot find ITS summary file at " + path); 116 } catch (IOException e) { 117 Log.e(TAG, "IO exception when trying to read " + path); 118 summary.append("IO exception when trying to read " + path); 119 } finally { 120 if (reader != null) { 121 try { 122 reader.close(); 123 } catch (IOException e) { 124 } 125 } 126 } 127 } 128 } 129 130 private final SuccessReceiver mSuccessReceiver = new SuccessReceiver(); 131 private final HashSet<String> mITSPassedCameraIds = new HashSet<>(); 132 // map camera id to ITS summary report path 133 private final HashMap<String, String> mSummaryMap = new HashMap<>(); 134 ArrayList<String> mNonLegacyCameraIds = null; 135 136 @Override onCreate(Bundle savedInstanceState)137 protected void onCreate(Bundle savedInstanceState) { 138 super.onCreate(savedInstanceState); 139 setContentView(R.layout.its_main); 140 setInfoResources(R.string.camera_its_test, R.string.camera_its_test_info, -1); 141 setPassFailButtonClickListeners(); 142 143 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 144 145 // Hide the test if all camera devices are legacy 146 CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE); 147 try { 148 String[] cameraIds = manager.getCameraIdList(); 149 mNonLegacyCameraIds = new ArrayList<String>(); 150 boolean allCamerasAreLegacy = true; 151 for (String id : cameraIds) { 152 CameraCharacteristics characteristics = manager.getCameraCharacteristics(id); 153 if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) 154 != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) { 155 mNonLegacyCameraIds.add(id); 156 allCamerasAreLegacy = false; 157 } 158 } 159 if (allCamerasAreLegacy) { 160 showToast(R.string.all_legacy_devices); 161 ItsTestActivity.this.getReportLog().setSummary( 162 "PASS: all cameras on this device are LEGACY" 163 , 1.0, ResultType.NEUTRAL, ResultUnit.NONE); 164 setTestResultAndFinish(true); 165 } 166 } catch (CameraAccessException e) { 167 Toast.makeText(ItsTestActivity.this, 168 "Received error from camera service while checking device capabilities: " 169 + e, Toast.LENGTH_SHORT).show(); 170 } 171 getPassButton().setEnabled(false); 172 } 173 174 @Override onResume()175 protected void onResume() { 176 super.onResume(); 177 CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE); 178 if (manager == null) { 179 showToast(R.string.no_camera_manager); 180 } else { 181 Log.d(TAG, "register ITS result receiver"); 182 IntentFilter filter = new IntentFilter(ACTION_ITS_RESULT); 183 registerReceiver(mSuccessReceiver, filter); 184 } 185 } 186 187 @Override onPause()188 protected void onPause() { 189 super.onPause(); 190 Log.d(TAG, "unregister ITS result receiver"); 191 unregisterReceiver(mSuccessReceiver); 192 } 193 194 @Override onConfigurationChanged(Configuration newConfig)195 public void onConfigurationChanged(Configuration newConfig) { 196 super.onConfigurationChanged(newConfig); 197 setContentView(R.layout.its_main); 198 setInfoResources(R.string.camera_its_test, R.string.camera_its_test_info, -1); 199 setPassFailButtonClickListeners(); 200 } 201 showToast(int messageId)202 private void showToast(int messageId) { 203 Toast.makeText(ItsTestActivity.this, messageId, Toast.LENGTH_SHORT).show(); 204 } 205 206 } 207