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.media.AudioDeviceCallback; 20 import android.media.AudioDeviceInfo; 21 import android.media.AudioManager; 22 import android.os.Bundle; 23 import android.os.Handler; 24 import android.util.Log; 25 import android.widget.TextView; 26 27 import com.android.cts.verifier.audio.peripheralprofile.PeripheralProfile; 28 import com.android.cts.verifier.audio.peripheralprofile.ProfileManager; 29 30 import com.android.cts.verifier.PassFailButtons; 31 import com.android.cts.verifier.R; // needed to access resource in CTSVerifier project namespace. 32 33 public abstract class USBAudioPeripheralActivity extends PassFailButtons.Activity { 34 private static final String TAG = "USBAudioPeripheralActivity"; 35 private static final boolean DEBUG = false; 36 37 // Profile 38 protected ProfileManager mProfileManager = new ProfileManager(); 39 protected PeripheralProfile mSelectedProfile; 40 41 // Peripheral 42 AudioManager mAudioManager; 43 protected boolean mIsPeripheralAttached; 44 protected AudioDeviceInfo mOutputDevInfo; 45 protected AudioDeviceInfo mInputDevInfo; 46 47 protected final boolean mIsMandatedRequired; 48 49 // This will be overriden... 50 protected int mSystemSampleRate = 48000; 51 52 // Widgets 53 private TextView mProfileNameTx; 54 private TextView mProfileDescriptionTx; 55 56 private TextView mPeripheralNameTx; 57 USBAudioPeripheralActivity(boolean mandatedRequired)58 public USBAudioPeripheralActivity(boolean mandatedRequired) { 59 super(); 60 61 // determine if to show "UNSUPPORTED" if the mandated peripheral is required. 62 mIsMandatedRequired = mandatedRequired; 63 64 mProfileManager.loadProfiles(); 65 } 66 67 @Override onCreate(Bundle savedInstanceState)68 protected void onCreate(Bundle savedInstanceState) { 69 super.onCreate(savedInstanceState); 70 71 mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE); 72 mAudioManager.registerAudioDeviceCallback(new ConnectListener(), new Handler()); 73 74 mSystemSampleRate = Integer.parseInt( 75 mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); 76 } 77 connectPeripheralStatusWidgets()78 protected void connectPeripheralStatusWidgets() { 79 mProfileNameTx = (TextView)findViewById(R.id.uap_profileNameTx); 80 mProfileDescriptionTx = 81 (TextView)findViewById(R.id.uap_profileDescriptionTx); 82 mPeripheralNameTx = (TextView)findViewById(R.id.uap_peripheralNameTx); 83 } 84 showProfileStatus()85 private void showProfileStatus() { 86 if (DEBUG) { 87 Log.d(TAG, "showProfileStatus()" + (mSelectedProfile != null)); 88 } 89 if (mSelectedProfile != null) { 90 mProfileNameTx.setText(mSelectedProfile.getName()); 91 mProfileDescriptionTx.setText(mSelectedProfile.getDescription()); 92 } else { 93 mProfileNameTx.setText(""); 94 mProfileDescriptionTx.setText(""); 95 } 96 } 97 showPeripheralStatus()98 private void showPeripheralStatus() { 99 if (mIsPeripheralAttached) { 100 String productName = ""; 101 if (mOutputDevInfo != null) { 102 productName = mOutputDevInfo.getProductName().toString(); 103 } else if (mInputDevInfo != null) { 104 productName = mInputDevInfo.getProductName().toString(); 105 } 106 String ctrlText; 107 if (mSelectedProfile == null && mIsMandatedRequired) { 108 ctrlText = productName + " - UNSUPPORTED"; 109 } else { 110 ctrlText = productName; 111 } 112 mPeripheralNameTx.setText(ctrlText); 113 } else { 114 mPeripheralNameTx.setText("Disconnected"); 115 } 116 } 117 scanPeripheralList(AudioDeviceInfo[] devices)118 private void scanPeripheralList(AudioDeviceInfo[] devices) { 119 // Can't just use the first record because then we will only get 120 // Source OR sink, not both even on devices that are both. 121 mOutputDevInfo = null; 122 mInputDevInfo = null; 123 124 // Any valid peripherals 125 for(AudioDeviceInfo devInfo : devices) { 126 if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE || 127 devInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) { 128 if (devInfo.isSink()) { 129 mOutputDevInfo = devInfo; 130 } 131 if (devInfo.isSource()) { 132 mInputDevInfo = devInfo; 133 } 134 } 135 } 136 mIsPeripheralAttached = mOutputDevInfo != null || mInputDevInfo != null; 137 if (DEBUG) { 138 Log.d(TAG, "mIsPeripheralAttached: " + mIsPeripheralAttached); 139 } 140 141 // any associated profiles? 142 if (mIsPeripheralAttached) { 143 if (mOutputDevInfo != null) { 144 mSelectedProfile = 145 mProfileManager.getProfile(mOutputDevInfo.getProductName().toString()); 146 } else if (mInputDevInfo != null) { 147 mSelectedProfile = 148 mProfileManager.getProfile(mInputDevInfo.getProductName().toString()); 149 } 150 } else { 151 mSelectedProfile = null; 152 } 153 154 } 155 156 private class ConnectListener extends AudioDeviceCallback { ConnectListener()157 /*package*/ ConnectListener() {} 158 159 // 160 // AudioDevicesManager.OnDeviceConnectionListener 161 // 162 @Override onAudioDevicesAdded(AudioDeviceInfo[] addedDevices)163 public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { 164 // Log.i(TAG, "onAudioDevicesAdded() num:" + addedDevices.length); 165 166 scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL)); 167 168 showProfileStatus(); 169 showPeripheralStatus(); 170 updateConnectStatus(); 171 } 172 173 @Override onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices)174 public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) { 175 // Log.i(TAG, "onAudioDevicesRemoved() num:" + removedDevices.length); 176 177 scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL)); 178 179 showProfileStatus(); 180 showPeripheralStatus(); 181 updateConnectStatus(); 182 } 183 } 184 updateConnectStatus()185 abstract public void updateConnectStatus(); 186 } 187 188