• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.media.AudioDeviceCallback;
21 import android.media.AudioDeviceInfo;
22 import android.media.AudioManager;
23 import android.os.Bundle;
24 import android.os.Handler;
25 import android.util.Log;
26 import android.view.View;
27 import android.view.View.OnClickListener;
28 import android.widget.TextView;
29 
30 import com.android.compatibility.common.util.ResultType;
31 import com.android.compatibility.common.util.ResultUnit;
32 import com.android.cts.verifier.PassFailButtons;
33 import com.android.cts.verifier.R;
34 import com.android.cts.verifier.audio.peripheralprofile.PeripheralProfile;
35 import com.android.cts.verifier.audio.peripheralprofile.ProfileManager;
36 
37 public abstract class USBAudioPeripheralActivity extends PassFailButtons.Activity {
38     private static final String TAG = "USBAudioPeripheralActivity";
39     private static final boolean DEBUG = false;
40 
41     // Host Mode Support
42     protected boolean mHasHostMode;
43 
44     // Profile
45     protected ProfileManager mProfileManager = new ProfileManager();
46     protected PeripheralProfile mSelectedProfile;
47 
48     // Peripheral
49     AudioManager mAudioManager;
50     protected boolean mIsPeripheralAttached;
51     protected AudioDeviceInfo mOutputDevInfo;
52     protected AudioDeviceInfo mInputDevInfo;
53 
54     protected final boolean mIsMandatedRequired;
55 
56     // Widgets
57     private TextView mProfileNameTx;
58     private TextView mProfileDescriptionTx;
59 
60     private TextView mPeripheralNameTx;
61 
62     private OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
63 
64     // ReportLog Schema
65     private static final String KEY_CLAIMS_HOST = "claims_host_mode";
66 
67     //
68     // Common UI Handling
69     //
connectUSBPeripheralUI()70     protected void connectUSBPeripheralUI() {
71         findViewById(R.id.uap_tests_yes_btn).setOnClickListener(mBtnClickListener);
72         findViewById(R.id.uap_tests_no_btn).setOnClickListener(mBtnClickListener);
73         findViewById(R.id.uap_test_info_btn).setOnClickListener(mBtnClickListener);
74 
75         // Leave the default state in tact
76         // enableTestUI(false);
77     }
78 
showUAPInfoDialog()79     private void showUAPInfoDialog() {
80         new AlertDialog.Builder(this)
81                 .setTitle(R.string.uap_test_hostmode_info_caption)
82                 .setMessage(R.string.uap_test_hostmode_info_text)
83                 .setPositiveButton(R.string.audio_general_ok, null)
84                 .show();
85     }
86 
87     private class OnBtnClickListener implements OnClickListener {
88         @Override
onClick(View v)89         public void onClick(View v) {
90             int id = v.getId();
91             if (id == R.id.uap_tests_yes_btn) {
92                 mHasHostMode = true;
93                 setUsbAudioStatus(mHasHostMode);
94             } else if (id == R.id.uap_tests_no_btn) {
95                 mHasHostMode = false;
96                 setUsbAudioStatus(mHasHostMode);
97             } else if (id == R.id.uap_test_info_btn) {
98                 showUAPInfoDialog();
99             }
100         }
101     }
102 
103     @Override
requiresReportLog()104     public boolean requiresReportLog() {
105         return true;
106     }
107 
108     @Override
getReportFileName()109     public String getReportFileName() {
110         return PassFailButtons.AUDIO_TESTS_REPORT_LOG_NAME;
111     }
112 
recordUSBAudioStatus(boolean has)113     private void recordUSBAudioStatus(boolean has) {
114         getReportLog().addValue(
115                 KEY_CLAIMS_HOST,
116                 has,
117                 ResultType.NEUTRAL,
118                 ResultUnit.NONE);
119     }
120 
setUsbAudioStatus(boolean has)121     protected void setUsbAudioStatus(boolean has) {
122         // ReportLog
123         recordUSBAudioStatus(has);
124 
125         // UI & Pass/Fail status
126         getPassButton().setEnabled(!mHasHostMode);
127         findViewById(R.id.uap_tests_yes_btn).setEnabled(mHasHostMode);
128         findViewById(R.id.uap_tests_no_btn).setEnabled(!mHasHostMode);
129     }
130 
USBAudioPeripheralActivity(boolean mandatedRequired)131     public USBAudioPeripheralActivity(boolean mandatedRequired) {
132         // determine if to show "UNSUPPORTED" if the mandated peripheral is required.
133         mIsMandatedRequired = mandatedRequired;
134 
135         mProfileManager.loadProfiles();
136     }
137 
138     @Override
onCreate(Bundle savedInstanceState)139     protected void onCreate(Bundle savedInstanceState) {
140         super.onCreate(savedInstanceState);
141 
142         mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
143         mAudioManager.registerAudioDeviceCallback(new ConnectListener(), new Handler());
144     }
145 
connectPeripheralStatusWidgets()146     protected void connectPeripheralStatusWidgets() {
147         mProfileNameTx = (TextView)findViewById(R.id.uap_profileNameTx);
148         mProfileDescriptionTx =
149             (TextView)findViewById(R.id.uap_profileDescriptionTx);
150         mPeripheralNameTx = (TextView)findViewById(R.id.uap_peripheralNameTx);
151     }
152 
showProfileStatus()153     private void showProfileStatus() {
154         if (DEBUG) {
155             Log.d(TAG, "showProfileStatus()" + (mSelectedProfile != null));
156         }
157         if (mSelectedProfile != null) {
158             mProfileNameTx.setText(mSelectedProfile.getName());
159             mProfileDescriptionTx.setText(mSelectedProfile.getDescription());
160         } else {
161             mProfileNameTx.setText("");
162             mProfileDescriptionTx.setText("");
163         }
164     }
165 
showPeripheralStatus()166     private void showPeripheralStatus() {
167         if (mIsPeripheralAttached) {
168             String productName = "";
169             if (mOutputDevInfo != null) {
170                 productName = mOutputDevInfo.getProductName().toString();
171             } else if (mInputDevInfo != null) {
172                 productName = mInputDevInfo.getProductName().toString();
173             }
174             String ctrlText;
175             if (mSelectedProfile == null && mIsMandatedRequired) {
176                 ctrlText = productName + " - UNSUPPORTED";
177             } else {
178                 ctrlText = productName;
179             }
180             mPeripheralNameTx.setText(ctrlText);
181         } else {
182             mPeripheralNameTx.setText("Disconnected");
183         }
184     }
185 
scanPeripheralList(AudioDeviceInfo[] devices)186     private void scanPeripheralList(AudioDeviceInfo[] devices) {
187         // Can't just use the first record because then we will only get
188         // Source OR sink, not both even on devices that are both.
189         mOutputDevInfo = null;
190         mInputDevInfo = null;
191 
192         // Any valid peripherals
193         for(AudioDeviceInfo devInfo : devices) {
194             if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE ||
195                 devInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) {
196                 if (devInfo.isSink()) {
197                     mOutputDevInfo = devInfo;
198                 }
199                 if (devInfo.isSource()) {
200                     mInputDevInfo = devInfo;
201                 }
202             }
203         }
204         mIsPeripheralAttached = mOutputDevInfo != null || mInputDevInfo != null;
205         if (DEBUG) {
206             Log.d(TAG, "mIsPeripheralAttached: " + mIsPeripheralAttached);
207         }
208 
209         // any associated profiles?
210         if (mIsPeripheralAttached) {
211             if (mOutputDevInfo != null) {
212                 mSelectedProfile =
213                     mProfileManager.getProfile(mOutputDevInfo.getProductName().toString());
214             } else if (mInputDevInfo != null) {
215                 mSelectedProfile =
216                     mProfileManager.getProfile(mInputDevInfo.getProductName().toString());
217             }
218         } else {
219             mSelectedProfile = null;
220         }
221     }
222 
223     private class ConnectListener extends AudioDeviceCallback {
ConnectListener()224         /*package*/ ConnectListener() {}
225 
226         //
227         // AudioDevicesManager.OnDeviceConnectionListener
228         //
229         @Override
onAudioDevicesAdded(AudioDeviceInfo[] addedDevices)230         public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
231             // Log.i(TAG, "onAudioDevicesAdded() num:" + addedDevices.length);
232 
233             scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
234 
235             showProfileStatus();
236             showPeripheralStatus();
237             updateConnectStatus();
238         }
239 
240         @Override
onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices)241         public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
242             // Log.i(TAG, "onAudioDevicesRemoved() num:" + removedDevices.length);
243 
244             scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
245 
246             showProfileStatus();
247             showPeripheralStatus();
248             updateConnectStatus();
249         }
250     }
251 
updateConnectStatus()252     abstract public void updateConnectStatus();
253 }
254 
255