1 /*
2  * Copyright (C) 2015 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 android.media.audio.cts;
18 
19 import android.content.Context;
20 import android.content.pm.PackageManager;
21 import android.media.AudioDeviceCallback;
22 import android.media.AudioDeviceInfo;
23 import android.media.AudioManager;
24 import android.media.cts.DeviceUtils;
25 import android.os.Handler;
26 import android.os.Looper;
27 import android.platform.test.annotations.AppModeSdkSandbox;
28 import android.test.AndroidTestCase;
29 import android.util.Log;
30 
31 import com.android.compatibility.common.util.NonMainlineTest;
32 
33 /**
34  * TODO: Insert description here. (generated by pmclean)
35  */
36 @NonMainlineTest
37 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
38 public class EnumDevicesTest extends AndroidTestCase {
39     private static final String TAG = "EnumDevicesTest";
40 
41     private AudioManager mAudioManager;
42 
43     boolean mAddCallbackCalled = false;
44     boolean mRemoveCallbackCalled = false;
45 
46     @Override
setUp()47     protected void setUp() throws Exception {
48         super.setUp();
49 
50         // get the AudioManager
51         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
52         assertNotNull(mAudioManager);
53     }
54 
test_getDevices()55     public void test_getDevices() {
56         AudioDeviceInfo[] deviceList;
57 
58         // test an empty flags set
59         deviceList = mAudioManager.getDevices(0);
60         assertTrue(deviceList != null);
61         assertTrue(deviceList.length == 0);
62 
63         PackageManager pkgMgr = mContext.getPackageManager();
64 
65         boolean isTvDevice = DeviceUtils.isTVDevice(mContext);
66 
67         int numOutputDevices = 0;
68         if (pkgMgr.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
69             // test OUTPUTS
70             deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
71             assertTrue(deviceList != null);
72 
73             numOutputDevices = deviceList.length;
74             if (numOutputDevices == 0) {
75                 boolean isHDMIConnected = DeviceUtils.isHDMIConnected(mContext);
76                 if (isTvDevice && !isHDMIConnected) {
77                     Log.w(TAG, "getDevices test: failure due to missing reported output " +
78                                "or the test is run on a TV device with no HDMI connected");
79                 }
80                 assertTrue("getDevices test: failure due to missing HDMI connection " +
81                            "or missing output", false);
82             }
83 
84             // any reported output devices should be "sinks"
85             for(int index = 0; index < numOutputDevices; index++) {
86                 assertTrue(deviceList[index].isSink());
87             }
88         }
89 
90         int numInputDevices = 0;
91         if (pkgMgr.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
92             // test INPUTS
93             deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
94             assertTrue(deviceList != null);
95 
96             numInputDevices = deviceList.length;
97             assertTrue(numInputDevices != 0);
98 
99             // all should be "sources"
100             for(int index = 0; index < numInputDevices; index++) {
101                 assertTrue(deviceList[index].isSource());
102             }
103         }
104 
105         // INPUTS & OUTPUTS
106         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT) &&
107                 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
108             deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL);
109             assertTrue(deviceList != null);
110             assertTrue(deviceList.length == (numOutputDevices + numInputDevices));
111         }
112     }
113 
test_devicesInfoFields()114     public void test_devicesInfoFields() {
115         AudioDeviceInfo[] deviceList;
116         deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL);
117         for (int index = 0; index < deviceList.length; index++) {
118             AudioDeviceInfo deviceInfo = deviceList[index];
119 
120             // we don't say anything about the returned value.
121             int id = deviceInfo.getId();
122 
123             // Product Name
124             CharSequence productName = deviceInfo.getProductName();
125             assertNotNull(productName);
126             assertTrue(productName.length() != 0);
127 
128             // Address
129             String address = deviceInfo.getAddress();
130             assertNotNull(address);
131             // address may be empty
132 
133             // isSource() XOR isSink()
134             assertTrue(deviceInfo.isSource() != deviceInfo.isSink());
135 
136             // Sample Rates
137             int[] sampleRates = deviceInfo.getSampleRates();
138             assertNotNull(sampleRates);
139             // Note: an empty array indicates that the device supports arbitrary sample rates.
140 
141             // Channel Masks
142             int[] channelMasks = deviceInfo.getChannelMasks();
143             assertNotNull(channelMasks);
144             // Note: an empty array indicates that the device supports arbitrary channel masks.
145 
146             // Channel Index Masks
147             int[] indexMasks = deviceInfo.getChannelIndexMasks();
148             assertNotNull(indexMasks);
149             // Note: an empty array indicates that the device supports arbitrary channel index
150             // masks.
151 
152             // Channel Counts
153             int[] channelCounts = deviceInfo.getChannelCounts();
154             assertNotNull(channelCounts);
155             // Note: an empty array indicates that the device supports arbitrary channel counts.
156 
157             // Encodings
158             int[] encodings = deviceInfo.getEncodings();
159             assertNotNull(encodings);
160             // Note: an empty array indicates that the device supports arbitrary encodings.
161 
162             // Encapsulation Modes
163             int[] encapsulationModes = deviceInfo.getEncapsulationModes();
164             assertNotNull(encapsulationModes);
165 
166             // EncapsulationMetadataTypes
167             int[] encapsulationMetadataTypes = deviceInfo.getEncapsulationMetadataTypes();
168             assertNotNull(encapsulationMetadataTypes);
169 
170             int type = deviceInfo.getType();
171             assertTrue(type != AudioDeviceInfo.TYPE_UNKNOWN);
172         }
173     }
174 
175     private class EmptyDeviceCallback extends AudioDeviceCallback {
onAudioDevicesAdded(AudioDeviceInfo[] addedDevices)176         public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
177             mAddCallbackCalled = true;
178         }
179 
onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices)180         public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
181             mRemoveCallbackCalled = true;
182         }
183     }
184 
185     /*
186      * tests if the Looper for the current thread has been prepared,
187      * If not, it makes one, prepares it and returns it.
188      * If this returns non-null, the caller is reponsible for calling quit()
189      * on the returned Looper.
190      */
prepareIfNeededLooper()191     private Looper prepareIfNeededLooper() {
192         // non-null Handler
193         Looper myLooper = null;
194         if (Looper.myLooper() == null) {
195             Looper.prepare();
196             myLooper = Looper.myLooper();
197             assertNotNull(myLooper);
198         }
199         return myLooper;
200     }
201 
test_deviceCallback()202     public void test_deviceCallback() {
203         // null callback?
204         mAudioManager.registerAudioDeviceCallback(null,null);
205 
206         AudioDeviceCallback callback =  new EmptyDeviceCallback();
207         AudioDeviceCallback someOtherCallback =  new EmptyDeviceCallback();
208         // null Handler
209         mAudioManager.registerAudioDeviceCallback(callback, null);
210 
211         // unregister null callback
212         mAudioManager.unregisterAudioDeviceCallback(null);
213         // unregister callback not registered
214         mAudioManager.unregisterAudioDeviceCallback(someOtherCallback);
215         // nominal case
216         mAudioManager.unregisterAudioDeviceCallback(callback);
217         // remove twice
218         mAudioManager.unregisterAudioDeviceCallback(callback);
219 
220         Looper myLooper = prepareIfNeededLooper();
221 
222         mAudioManager.registerAudioDeviceCallback(callback, new Handler());
223         // unregister null callback
224         mAudioManager.unregisterAudioDeviceCallback(null);
225         // unregister callback not registered
226         mAudioManager.unregisterAudioDeviceCallback(someOtherCallback);
227         // nominal case
228         mAudioManager.unregisterAudioDeviceCallback(callback);
229         // remove twice
230         mAudioManager.unregisterAudioDeviceCallback(callback);
231 
232         if (myLooper != null) {
233             myLooper.quit();
234         }
235     }
236 
237     //TODO - Need tests for device connect/disconnect callbacks
238 }
239