1 /* 2 * Copyright (C) 2015 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.audio; 18 19 import android.app.AlertDialog; 20 import android.content.Context; 21 import android.media.AudioDeviceCallback; 22 import android.media.AudioDeviceInfo; 23 import android.media.AudioManager; 24 import android.os.Bundle; 25 import android.util.Log; 26 import android.view.View; 27 import android.view.View.OnClickListener; 28 import android.view.ViewGroup; 29 import android.widget.LinearLayout; 30 31 import com.android.compatibility.common.util.ResultType; 32 import com.android.compatibility.common.util.ResultUnit; 33 import com.android.cts.verifier.PassFailButtons; 34 import com.android.cts.verifier.R; 35 36 /** 37 * Audio Frequency Test base activity 38 */ 39 public class AudioFrequencyActivity extends PassFailButtons.Activity { 40 private static final String TAG = "AudioFrequencyActivity"; 41 private static final boolean DEBUG = true; 42 43 protected Context mContext; 44 protected AudioManager mAudioManager; 45 46 private ConnectListener mConnectListener; 47 48 protected AudioDeviceInfo mOutputDevInfo; 49 protected AudioDeviceInfo mInputDevInfo; 50 51 public int mMaxLevel = 0; 52 53 // 54 // TODO - These should be refactored into a RefMicActivity class 55 // i.e. AudioFrequencyActivity <- RefMicActivity 56 private OnBtnClickListener mBtnClickListener = new OnBtnClickListener(); 57 58 @Override onCreate(Bundle savedInstanceState)59 protected void onCreate(Bundle savedInstanceState) { 60 super.onCreate(savedInstanceState); 61 62 mContext = this; 63 64 mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE); 65 mConnectListener = new ConnectListener(); 66 } 67 68 @Override onStart()69 public void onStart() { 70 super.onStart(); 71 mAudioManager.registerAudioDeviceCallback(mConnectListener, null); 72 } 73 74 @Override onStop()75 public void onStop() { 76 mAudioManager.unregisterAudioDeviceCallback(mConnectListener); 77 super.onStop(); 78 } 79 80 // 81 // Common UI Handling connectRefMicUI()82 protected void connectRefMicUI() { 83 findViewById(R.id.refmic_tests_yes_btn).setOnClickListener(mBtnClickListener); 84 findViewById(R.id.refmic_tests_no_btn).setOnClickListener(mBtnClickListener); 85 findViewById(R.id.refmic_test_info_btn).setOnClickListener(mBtnClickListener); 86 87 enableTestUI(false); 88 } 89 showRefMicInfoDialog()90 private void showRefMicInfoDialog() { 91 new AlertDialog.Builder(this) 92 .setTitle(R.string.ref_mic_dlg_caption) 93 .setMessage(R.string.ref_mic_dlg_text) 94 .setPositiveButton(R.string.audio_general_ok, null) 95 .show(); 96 } 97 98 private class OnBtnClickListener implements OnClickListener { 99 @Override onClick(View v)100 public void onClick(View v) { 101 int id = v.getId(); 102 if (id == R.id.refmic_tests_yes_btn) { 103 recordRefMicStatus(true); 104 enableTestUI(true); 105 // disable test button so that they will now run the test(s) 106 getPassButton().setEnabled(false); 107 } else if (id == R.id.refmic_tests_no_btn) { 108 recordRefMicStatus(false); 109 enableTestUI(false); 110 // Allow the user to "pass" the test. 111 getPassButton().setEnabled(true); 112 } else if (id == R.id.refmic_test_info_btn) { 113 showRefMicInfoDialog(); 114 } 115 } 116 } 117 118 private static final String KEY_USER_REPORTED_REF_MIC = "user_reported_ref_mic"; 119 private static final String KEY_USER_REPORTED_HEADSET_PORT = "user_reported_headset_port"; 120 protected static final String KEY_LEVEL = "level"; 121 protected static final String KEY_POINTS_IN_BOUND = "points_in_bound"; 122 protected static final String KEY_POINTS_TOTAL = "points_total"; 123 protected static final String KEY_MAGNITUDE_SPECTRUM_LOG = "magnitude_spectrum_log"; 124 protected static final String KEY_BANDS = "bands"; 125 126 protected static final String LOG_ERROR_STR = "Could not log metric."; 127 recordRefMicStatus(boolean has)128 private void recordRefMicStatus(boolean has) { 129 getReportLog().addValue( 130 KEY_USER_REPORTED_REF_MIC, 131 has, 132 ResultType.NEUTRAL, 133 ResultUnit.NONE); 134 } 135 recordHeadsetPortFound(boolean found)136 protected void recordHeadsetPortFound(boolean found) { 137 getReportLog().addValue( 138 KEY_USER_REPORTED_HEADSET_PORT, 139 found, 140 ResultType.NEUTRAL, 141 ResultUnit.NONE); 142 } 143 144 // 145 // Overrides 146 // enableTestUI(boolean enable)147 void enableTestUI(boolean enable) { 148 149 } 150 151 @Override requiresReportLog()152 public boolean requiresReportLog() { 153 return true; 154 } 155 156 @Override getReportFileName()157 public String getReportFileName() { 158 return PassFailButtons.AUDIO_TESTS_REPORT_LOG_NAME; 159 } 160 enableLayout(int layoutId, boolean enable)161 void enableLayout(int layoutId, boolean enable) { 162 ViewGroup group = (ViewGroup)findViewById(layoutId); 163 for (int i = 0; i < group.getChildCount(); i++) { 164 group.getChildAt(i).setEnabled(enable); 165 } 166 } 167 setMaxLevel()168 public void setMaxLevel() { 169 mMaxLevel = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 170 mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(mMaxLevel), 0); 171 } 172 setMinLevel()173 public void setMinLevel() { 174 mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0); 175 } 176 testMaxLevel()177 public void testMaxLevel() { 178 int currentLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 179 Log.i(TAG, String.format("Max level: %d curLevel: %d", mMaxLevel, currentLevel)); 180 if (currentLevel != mMaxLevel) { 181 new AlertDialog.Builder(this) 182 .setTitle(R.string.audio_general_warning) 183 .setMessage(R.string.audio_general_level_not_max) 184 .setPositiveButton(R.string.audio_general_ok, null) 185 .show(); 186 } 187 } 188 getMaxLevelForStream(int streamType)189 public int getMaxLevelForStream(int streamType) { 190 return mAudioManager.getStreamMaxVolume(streamType); 191 } 192 setLevelForStream(int streamType, int level)193 public void setLevelForStream(int streamType, int level) { 194 try { 195 mAudioManager.setStreamVolume(streamType, level, 0); 196 } catch (Exception e) { 197 Log.e(TAG, "Error setting stream volume: ", e); 198 } 199 } 200 getLevelForStream(int streamType)201 public int getLevelForStream(int streamType) { 202 return mAudioManager.getStreamVolume(streamType); 203 } 204 enableUILayout(LinearLayout layout, boolean enable)205 public void enableUILayout(LinearLayout layout, boolean enable) { 206 for (int i = 0; i < layout.getChildCount(); i++) { 207 View view = layout.getChildAt(i); 208 view.setEnabled(enable); 209 } 210 } 211 scanPeripheralList(AudioDeviceInfo[] devices)212 private void scanPeripheralList(AudioDeviceInfo[] devices) { 213 // Can't just use the first record because then we will only get 214 // Source OR sink, not both even on devices that are both. 215 mOutputDevInfo = null; 216 mInputDevInfo = null; 217 218 // Any valid peripherals 219 for(AudioDeviceInfo devInfo : devices) { 220 if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE || 221 devInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) { 222 if (devInfo.isSink()) { 223 mOutputDevInfo = devInfo; 224 } 225 if (devInfo.isSource()) { 226 mInputDevInfo = devInfo; 227 } 228 } 229 } 230 231 } 232 233 private class ConnectListener extends AudioDeviceCallback { ConnectListener()234 /*package*/ ConnectListener() {} 235 236 // 237 // AudioDevicesManager.OnDeviceConnectionListener 238 // 239 @Override onAudioDevicesAdded(AudioDeviceInfo[] addedDevices)240 public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { 241 // Log.i(TAG, "onAudioDevicesAdded() num:" + addedDevices.length); 242 243 scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL)); 244 } 245 246 @Override onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices)247 public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) { 248 // Log.i(TAG, "onAudioDevicesRemoved() num:" + removedDevices.length); 249 250 scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL)); 251 } 252 } 253 254 // abstract public void updateConnectStatus(); 255 } 256