blob: 6270a5a8311fe23b34f2c98e0ff78a25b82b657b [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.verifier.audio;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;
import com.android.compatibility.common.util.CddTest;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R; // needed to access resource in CTSVerifier project namespace.
@CddTest(requirement = "7.8.2.2/H-2-1,H-3-1,H-4-2,H-4-3,H-4-4,H-4-5")
public class USBAudioPeripheralNotificationsTest extends PassFailButtons.Activity {
private static final String
TAG = USBAudioPeripheralNotificationsTest.class.getSimpleName();
private AudioManager mAudioManager;
private TextView mHeadsetInName;
private TextView mHeadsetOutName;
private TextView mUsbDeviceInName;
private TextView mUsbDeviceOutName;
// private TextView mHeadsetPlugText;
private TextView mHeadsetPlugMessage;
// Intents
private HeadsetPlugReceiver mHeadsetPlugReceiver;
private boolean mPlugIntentReceived;
// Device
private AudioDeviceInfo mUsbHeadsetInInfo;
private AudioDeviceInfo mUsbHeadsetOutInfo;
private AudioDeviceInfo mUsbDeviceInInfo;
private AudioDeviceInfo mUsbDeviceOutInfo;
private boolean mUsbHeadsetInReceived;
private boolean mUsbHeadsetOutReceived;
private boolean mUsbDeviceInReceived;
private boolean mUsbDeviceOutReceived;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.uap_notifications_layout);
mHeadsetInName = (TextView)findViewById(R.id.uap_messages_headset_in_name);
mHeadsetOutName = (TextView)findViewById(R.id.uap_messages_headset_out_name);
mUsbDeviceInName = (TextView)findViewById(R.id.uap_messages_usb_device_in_name);
mUsbDeviceOutName = (TextView)findViewById(R.id.uap_messages_usb_device__out_name);
mHeadsetPlugMessage = (TextView)findViewById(R.id.uap_messages_plug_message);
mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
mAudioManager.registerAudioDeviceCallback(new ConnectListener(), new Handler());
mHeadsetPlugReceiver = new HeadsetPlugReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
registerReceiver(mHeadsetPlugReceiver, filter);
setInfoResources(R.string.audio_uap_notifications_test, R.string.uapNotificationsTestInfo,
-1);
setPassFailButtonClickListeners();
getPassButton().setEnabled(false);
}
//
// UI
//
private void showConnectedDevices() {
if (mUsbHeadsetInInfo != null) {
mHeadsetInName.setText(
"Headset INPUT Connected " + mUsbHeadsetInInfo.getProductName());
} else {
mHeadsetInName.setText("");
}
if (mUsbHeadsetOutInfo != null) {
mHeadsetOutName.setText(
"Headset OUTPUT Connected " + mUsbHeadsetOutInfo.getProductName());
} else {
mHeadsetOutName.setText("");
}
if (mUsbDeviceInInfo != null) {
mUsbDeviceInName.setText(
"USB DEVICE INPUT Connected " + mUsbDeviceInInfo.getProductName());
} else {
mUsbDeviceInName.setText("");
}
if (mUsbDeviceOutInfo != null) {
mUsbDeviceOutName.setText(
"USB DEVICE OUTPUT Connected " + mUsbDeviceOutInfo.getProductName());
} else {
mUsbDeviceOutName.setText("");
}
}
private void reportPlugIntent(Intent intent) {
// [ 7.8 .2.2/H-2-1] MUST broadcast Intent ACTION_HEADSET_PLUG with "microphone" extra
// set to 0 when the USB audio terminal types 0x0302 is detected.
// [ 7.8 .2.2/H-3-1] MUST broadcast Intent ACTION_HEADSET_PLUG with "microphone" extra
// set to 1 when the USB audio terminal types 0x0402 is detected, they:
mPlugIntentReceived = true;
// state - 0 for unplugged, 1 for plugged.
// name - Headset type, human readable string
// microphone - 1 if headset has a microphone, 0 otherwise
int state = intent.getIntExtra("state", -1);
if (state != -1) {
StringBuilder sb = new StringBuilder();
sb.append("ACTION_HEADSET_PLUG received - " + (state == 0 ? "Unplugged" : "Plugged"));
String name = intent.getStringExtra("name");
if (name != null) {
sb.append(" - " + name);
}
int hasMic = intent.getIntExtra("microphone", 0);
if (hasMic == 1) {
sb.append(" [mic]");
}
mHeadsetPlugMessage.setText(sb.toString());
}
getReportLog().addValue(
"ACTION_HEADSET_PLUG Intent Received. State: ",
state,
ResultType.NEUTRAL,
ResultUnit.NONE);
getPassButton().setEnabled(calculatePass());
}
//
// Test Status
//
private boolean calculatePass() {
return isReportLogOkToPass()
&& mUsbHeadsetInReceived && mUsbHeadsetOutReceived
&& mUsbDeviceInReceived && mUsbDeviceOutReceived
&& mPlugIntentReceived;
}
//
// Devices
//
private void scanDevices(AudioDeviceInfo[] devices) {
mUsbHeadsetInInfo = mUsbHeadsetOutInfo =
mUsbDeviceInInfo = mUsbDeviceOutInfo = null;
for (AudioDeviceInfo devInfo : devices) {
if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) {
if (devInfo.isSource()) {
// [ 7.8 .2.2/H-4-3] MUST list a device of type AudioDeviceInfo.TYPE_USB_HEADSET
// and role isSource() if the USB audio terminal type field is 0x0402.
mUsbHeadsetInReceived = true;
mUsbHeadsetInInfo = devInfo;
getReportLog().addValue(
"USB Headset connected - INPUT",
0,
ResultType.NEUTRAL,
ResultUnit.NONE);
} else if (devInfo.isSink()) {
// [ 7.8 .2.2/H-4-2] MUST list a device of type AudioDeviceInfo.TYPE_USB_HEADSET
// and role isSink() if the USB audio terminal type field is 0x0402.
mUsbHeadsetOutReceived = true;
mUsbHeadsetOutInfo = devInfo;
getReportLog().addValue(
"USB Headset connected - OUTPUT",
0,
ResultType.NEUTRAL,
ResultUnit.NONE);
}
} else if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE) {
if (devInfo.isSource()) {
// [ 7.8 .2.2/H-4-5] MUST list a device of type AudioDeviceInfo.TYPE_USB_DEVICE
// and role isSource() if the USB audio terminal type field is 0x604.
mUsbDeviceInReceived = true;
mUsbDeviceInInfo = devInfo;
getReportLog().addValue(
"USB Device connected - INPUT",
0,
ResultType.NEUTRAL,
ResultUnit.NONE);
} else if (devInfo.isSink()) {
// [ 7.8 .2.2/H-4-4] MUST list a device of type AudioDeviceInfo.TYPE_USB_DEVICE
// and role isSink() if the USB audio terminal type field is 0x603.
mUsbDeviceOutReceived = true;
mUsbDeviceOutInfo = devInfo;
getReportLog().addValue(
"USB Headset connected - OUTPUT",
0,
ResultType.NEUTRAL,
ResultUnit.NONE);
}
}
if (mUsbHeadsetInInfo != null &&
mUsbHeadsetOutInfo != null &&
mUsbDeviceInInfo != null &&
mUsbDeviceOutInfo != null) {
break;
}
}
showConnectedDevices();
getPassButton().setEnabled(calculatePass());
}
private class ConnectListener extends AudioDeviceCallback {
/*package*/ ConnectListener() {}
//
// AudioDevicesManager.OnDeviceConnectionListener
//
@Override
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
Log.i(TAG, "onAudioDevicesAdded() num:" + addedDevices.length);
scanDevices(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
}
@Override
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
Log.i(TAG, "onAudioDevicesRemoved() num:" + removedDevices.length);
scanDevices(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
}
}
// Intents
private class HeadsetPlugReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
reportPlugIntent(intent);
}
}
}