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 
36     // Profile
37     protected ProfileManager mProfileManager = new ProfileManager();
38     protected PeripheralProfile mSelectedProfile;
39 
40     // Peripheral
41     AudioManager mAudioManager;
42     protected boolean mIsPeripheralAttached;
43     protected AudioDeviceInfo mOutputDevInfo;
44     protected AudioDeviceInfo mInputDevInfo;
45 
46     // This will be overriden...
47     protected  int mSystemSampleRate = 48000;
48 
49     // Widgets
50     private TextView mProfileNameTx;
51     private TextView mProfileDescriptionTx;
52 
53     private TextView mPeripheralNameTx;
54 
USBAudioPeripheralActivity()55     public USBAudioPeripheralActivity() {
56         super();
57 
58         mProfileManager.loadProfiles();
59     }
60 
61     @Override
onCreate(Bundle savedInstanceState)62     protected void onCreate(Bundle savedInstanceState) {
63         super.onCreate(savedInstanceState);
64 
65         mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
66         mAudioManager.registerAudioDeviceCallback(new ConnectListener(), new Handler());
67 
68         mSystemSampleRate = Integer.parseInt(
69             mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
70     }
71 
connectPeripheralStatusWidgets()72     protected void connectPeripheralStatusWidgets() {
73         mProfileNameTx = (TextView)findViewById(R.id.uap_profileNameTx);
74         mProfileDescriptionTx =
75             (TextView)findViewById(R.id.uap_profileDescriptionTx);
76         mPeripheralNameTx = (TextView)findViewById(R.id.uap_peripheralNameTx);
77     }
78 
showProfileStatus()79     private void showProfileStatus() {
80         if (mSelectedProfile != null) {
81             mProfileNameTx.setText(mSelectedProfile.getName());
82             mProfileDescriptionTx.setText(mSelectedProfile.getDescription());
83         } else {
84             mProfileNameTx.setText("");
85             mProfileDescriptionTx.setText("");
86         }
87     }
88 
showPeripheralStatus()89     private void showPeripheralStatus() {
90         if (mIsPeripheralAttached) {
91             if (mOutputDevInfo != null) {
92                 mPeripheralNameTx.setText(mOutputDevInfo.getProductName().toString());
93             } else if (mInputDevInfo != null) {
94                 mPeripheralNameTx.setText(mInputDevInfo.getProductName().toString());
95             }
96         } else {
97             mPeripheralNameTx.setText("Disconnected");
98         }
99     }
100 
scanPeripheralList(AudioDeviceInfo[] devices)101     private void scanPeripheralList(AudioDeviceInfo[] devices) {
102         // Can't just use the first record because then we will only get
103         // Source OR sink, not both even on devices that are both.
104         mOutputDevInfo = null;
105         mInputDevInfo = null;
106 
107         // Any valid peripherals
108         for(AudioDeviceInfo devInfo : devices) {
109             if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE) {
110                 if (devInfo.isSink()) {
111                     mOutputDevInfo = devInfo;
112                 }
113                 if (devInfo.isSource()) {
114                     mInputDevInfo = devInfo;
115                 }
116             }
117         }
118         mIsPeripheralAttached = mOutputDevInfo != null || mInputDevInfo != null;
119         // Log.i(TAG, "mIsPeripheralAttached: " + mIsPeripheralAttached);
120 
121         // any associated profiles?
122         if (mIsPeripheralAttached) {
123             if (mOutputDevInfo != null) {
124                 mSelectedProfile =
125                     mProfileManager.getProfile(mOutputDevInfo.getProductName().toString());
126             } else if (mInputDevInfo != null) {
127                 mSelectedProfile =
128                     mProfileManager.getProfile(mInputDevInfo.getProductName().toString());
129             }
130         } else {
131             mSelectedProfile = null;
132         }
133 
134     }
135 
136     private class ConnectListener extends AudioDeviceCallback {
ConnectListener()137         /*package*/ ConnectListener() {}
138 
139         //
140         // AudioDevicesManager.OnDeviceConnectionListener
141         //
142         @Override
onAudioDevicesAdded(AudioDeviceInfo[] addedDevices)143         public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
144             // Log.i(TAG, "onAudioDevicesAdded() num:" + addedDevices.length);
145 
146             scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
147 
148             showProfileStatus();
149             showPeripheralStatus();
150             updateConnectStatus();
151         }
152 
153         @Override
onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices)154         public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
155             // Log.i(TAG, "onAudioDevicesRemoved() num:" + removedDevices.length);
156 
157             scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
158 
159             showProfileStatus();
160             showPeripheralStatus();
161             updateConnectStatus();
162         }
163     }
164 
updateConnectStatus()165     abstract public void updateConnectStatus();
166 }
167 
168