• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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