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