• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.audioquality;
18 
19 import com.android.cts.verifier.PassFailButtons;
20 import com.android.cts.verifier.R;
21 
22 import android.content.BroadcastReceiver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.graphics.Color;
27 import android.graphics.Typeface;
28 import android.media.AudioFormat;
29 import android.media.AudioManager;
30 import android.os.Bundle;
31 import android.util.Log;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.view.ViewGroup;
35 import android.widget.AdapterView;
36 import android.widget.ArrayAdapter;
37 import android.widget.Button;
38 import android.widget.ListView;
39 import android.widget.ProgressBar;
40 import android.widget.TextView;
41 import android.widget.AdapterView.OnItemClickListener;
42 
43 import java.util.ArrayList;
44 
45 /**
46  * Main UI for the Android Audio Quality Verifier.
47  */
48 public class AudioQualityVerifierActivity extends PassFailButtons.Activity
49         implements View.OnClickListener, OnItemClickListener {
50     public static final String TAG = "AudioQualityVerifier";
51 
52     public static final int SAMPLE_RATE = 16000;
53     public static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
54     public static final int BYTES_PER_SAMPLE = 2;
55     public static final int PLAYBACK_STREAM = AudioManager.STREAM_MUSIC;
56 
57     // Intent Extra definitions, which must match those in
58     // com.google.android.voicesearch.speechservice.RecognitionController
59     public static final String EXTRA_RAW_AUDIO =
60             "android.speech.extras.RAW_AUDIO";
61 
62     // Communication with ExperimentService
63     public static final String ACTION_EXP_STARTED =
64             "com.android.cts.verifier.audioquality.EXP_STARTED";
65     public static final String ACTION_EXP_FINISHED =
66             "com.android.cts.verifier.audioquality.EXP_FINISHED";
67     public static final String EXTRA_ABORTED =
68             "com.android.cts.verifier.audioquality.ABORTED";
69     public static final String EXTRA_EXP_ID =
70             "com.android.cts.verifier.audioquality.EXP_ID";
71     public static final String EXTRA_RUN_ALL =
72             "com.android.cts.verifier.audioquality.RUN_ALL";
73 
74     // Communication with ViewResultsActivity
75     public static final String EXTRA_RESULTS =
76             "com.android.cts.verifier.audioquality.RESULTS";
77 
78     private Button mCalibrateButton;
79     private Button mRunAllButton;
80     private Button mStopButton;
81     private Button mViewResultsButton;
82     private Button mClearButton;
83 
84     private ListView mList;
85     private TwoColumnAdapter mAdapter;
86 
87     private ProgressBar mProgress;
88 
89     private ArrayList<Experiment> mExperiments;
90 
91     private boolean mRunningExperiment;
92 
93     private BroadcastReceiver mReceiver;
94 
95     @Override
onCreate(Bundle savedInstanceState)96     public void onCreate(Bundle savedInstanceState) {
97         super.onCreate(savedInstanceState);
98         setContentView(R.layout.aq_verifier_activity);
99         setPassFailButtonClickListeners();
100         setInfoResources(R.string.aq_verifier, R.string.aq_verifier_info, -1);
101 
102         mCalibrateButton = (Button) findViewById(R.id.calibrateButton);
103         mRunAllButton = (Button) findViewById(R.id.runAllButton);
104         mStopButton = (Button) findViewById(R.id.stopButton);
105         mViewResultsButton = (Button) findViewById(R.id.viewResultsButton);
106         mClearButton = (Button) findViewById(R.id.clearButton);
107 
108         mCalibrateButton.setOnClickListener(this);
109         mRunAllButton.setOnClickListener(this);
110         mStopButton.setOnClickListener(this);
111         mViewResultsButton.setOnClickListener(this);
112         mClearButton.setOnClickListener(this);
113 
114         mStopButton.setEnabled(false);
115 
116         mProgress = (ProgressBar) findViewById(R.id.progress);
117 
118         mList = (ListView) findViewById(R.id.list);
119         mAdapter = new TwoColumnAdapter(this);
120 
121         mExperiments = VerifierExperiments.getExperiments(this);
122 
123         mReceiver = new BroadcastReceiver() {
124             @Override
125             public void onReceive(Context context, Intent intent) {
126                 experimentReplied(intent);
127             }
128         };
129         IntentFilter filter = new IntentFilter();
130         filter.addAction(ACTION_EXP_STARTED);
131         filter.addAction(ACTION_EXP_FINISHED);
132         registerReceiver(mReceiver, filter);
133 
134         fillAdapter();
135         mList.setAdapter(mAdapter);
136         mList.setOnItemClickListener(this);
137         checkNotSilent();
138     }
139 
140     @Override
onResume()141     public void onResume() {
142         super.onResume();
143         mAdapter.notifyDataSetChanged(); // Update List UI
144         setVolumeControlStream(AudioManager.STREAM_MUSIC);
145         checkNotSilent();
146     }
147 
checkNotSilent()148     private void checkNotSilent() {
149         AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
150         mgr.setStreamMute(PLAYBACK_STREAM, false);
151         int volume = mgr.getStreamVolume(PLAYBACK_STREAM);
152         int max = mgr.getStreamMaxVolume(PLAYBACK_STREAM);
153         Log.i(TAG, "Volume " + volume + ", max " + max);
154         if (volume <= max / 10) {
155             // Volume level is silent or very quiet; increase to two-thirds
156             mgr.setStreamVolume(PLAYBACK_STREAM, (max * 2) / 3, AudioManager.FLAG_SHOW_UI);
157         }
158     }
159 
160     // Called when an experiment has completed
experimentReplied(Intent intent)161     private void experimentReplied(Intent intent) {
162         String action = intent.getAction();
163         if (ACTION_EXP_STARTED.equals(action)) {
164             mStopButton.setEnabled(true);
165             mRunAllButton.setEnabled(false);
166         } else if (ACTION_EXP_FINISHED.equals(action)) {
167             boolean mRunAll = intent.getBooleanExtra(EXTRA_RUN_ALL, false);
168             boolean aborted = intent.getBooleanExtra(EXTRA_ABORTED, true);
169             int expID = intent.getIntExtra(EXTRA_EXP_ID, -1);
170             if (mRunAll && !aborted) {
171                 while (expID < mExperiments.size() - 1) {
172                     if (runExperiment(++expID, true)) {
173                         // OK, experiment is running
174                         mAdapter.notifyDataSetChanged();
175                         return;
176                     }
177                     // Otherwise, loop back and try the next experiment
178                 }
179             }
180             mStopButton.setEnabled(false);
181             mRunAllButton.setEnabled(true);
182             mRunningExperiment = false;
183             mProgress.setVisibility(ProgressBar.INVISIBLE);
184         }
185         mAdapter.notifyDataSetChanged();
186     }
187 
188     // Implements AdapterView.OnItemClickListener
onItemClick(AdapterView<?> parent, View view, int position, long id)189     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
190         if (mRunningExperiment) return;
191         runExperiment(position, false);
192     }
193 
194     // Begin an experiment. Returns false if the experiment is not enabled.
runExperiment(int which, boolean all)195     private boolean runExperiment(int which, boolean all) {
196         Experiment exp = mExperiments.get(which);
197         if (!exp.isEnabled()) return false;
198         Intent intent = new Intent(this, ExperimentService.class);
199         intent.putExtra(EXTRA_EXP_ID, which);
200         intent.putExtra(EXTRA_RUN_ALL, all);
201         startService(intent);
202         mRunningExperiment = true;
203         mAdapter.notifyDataSetChanged();
204         mProgress.setVisibility(ProgressBar.VISIBLE);
205         return true;
206     }
207 
208     // Implements View.OnClickListener:
onClick(View v)209     public void onClick(View v) {
210         if (v == mCalibrateButton) {
211             Intent intent = new Intent(this, CalibrateVolumeActivity.class);
212             startActivity(intent);
213         } else if (v == mRunAllButton) {
214             if (mRunningExperiment) return;
215             int expID = -1;
216             while (expID < mExperiments.size() - 1) {
217                 if (runExperiment(++expID, true)) break;
218             }
219         } else if (v == mStopButton) {
220             Intent intent = new Intent(this, ExperimentService.class);
221             stopService(intent);
222         } else if (v == mViewResultsButton) {
223             Intent intent = new Intent(this, ViewResultsActivity.class);
224             intent.putExtra(EXTRA_RESULTS, genReport());
225             startActivity(intent);
226         } else if (v == mClearButton) {
227             clear();
228         }
229     }
230 
fillAdapter()231     private void fillAdapter() {
232         mAdapter.clear();
233         for (Experiment exp : mExperiments) {
234             mAdapter.add(exp.getName());
235         }
236     }
237 
238     class TwoColumnAdapter extends ArrayAdapter<String> {
TwoColumnAdapter(Context context)239         TwoColumnAdapter(Context context) {
240             super(context, R.layout.aq_row);
241         }
242 
243         @Override
getView(int position, View convertView, ViewGroup parent)244         public View getView(int position, View convertView, ViewGroup parent) {
245             LayoutInflater inflater = getLayoutInflater();
246             View row = inflater.inflate(R.layout.aq_row, parent, false);
247             TextView nameField = (TextView) row.findViewById(R.id.testName);
248             TextView scoreField = (TextView) row.findViewById(R.id.testScore);
249             Experiment exp = mExperiments.get(position);
250             nameField.setText(exp.getName());
251             scoreField.setText(exp.getScore());
252             if (exp.isRunning()) {
253                 Typeface tf = nameField.getTypeface();
254                 nameField.setTypeface(tf, 1);
255             }
256             if (!exp.isEnabled()) {
257                 nameField.setTextColor(Color.GRAY);
258             }
259             return row;
260         }
261     }
262 
genReport()263     private String genReport() {
264         StringBuilder sb = new StringBuilder();
265         for (Experiment exp : mExperiments) {
266             exp.getReport(sb);
267         }
268         return sb.toString();
269     }
270 
clear()271     private void clear() {
272         if (mRunningExperiment) {
273             Intent intent = new Intent(this, ExperimentService.class);
274             stopService(intent);
275         }
276         for (Experiment exp : mExperiments) {
277             exp.reset();
278         }
279         mAdapter.notifyDataSetChanged();
280     }
281 
282     @Override
getTestDetails()283     public String getTestDetails() {
284         return genReport();
285     }
286 
287     @Override
onDestroy()288     protected void onDestroy() {
289         super.onDestroy();
290         unregisterReceiver(mReceiver);
291     }
292 }
293