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