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