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.tv; 18 19 import android.annotation.SuppressLint; 20 import android.content.Context; 21 import android.hardware.input.InputManager; 22 import android.util.Log; 23 import android.view.InputDevice; 24 import android.view.View; 25 import android.widget.Toast; 26 27 import com.android.cts.verifier.R; 28 29 import java.util.Arrays; 30 import java.util.HashMap; 31 import java.util.List; 32 33 /** 34 * Tests for verifying that all input devices report correct hasMicrophone() states. 35 */ 36 @SuppressLint("NewApi") 37 public class MicrophoneDeviceTestActivity extends TvAppVerifierActivity 38 implements View.OnClickListener { 39 private static final String TAG = "MicrophoneDeviceTestActivity"; 40 private static final boolean PASS = true; 41 42 private InputManager mInputManager; 43 private HashMap<View, List<Object>> mInputDeviceItems; 44 private View mPreparationYesItem; 45 private View mPreparationNoItem; 46 47 @Override onClick(View v)48 public void onClick(View v) { 49 final View postTarget = getPostTarget(); 50 51 if (containsButton(mPreparationYesItem, v)) { 52 setPassState(mPreparationYesItem, true); 53 setButtonEnabled(mPreparationNoItem, false); 54 createInputDeviceItems(); 55 return; 56 } else if (containsButton(mPreparationNoItem, v)) { 57 setPassState(mPreparationYesItem, false); 58 setButtonEnabled(mPreparationNoItem, false); 59 getPassButton().setEnabled(false); 60 return; 61 } else if (mInputDeviceItems == null) { 62 return; 63 } 64 65 for (View item : mInputDeviceItems.keySet()) { 66 if (containsButton(item, v)) { 67 final List<Object> triple = mInputDeviceItems.get(item); 68 final boolean userAnswer = (boolean) triple.get(0); 69 final boolean actualAnswer = (boolean) triple.get(1); 70 final View pairedItem = (View) triple.get(2); 71 72 if (userAnswer == actualAnswer) { 73 setPassState(userAnswer ? item : pairedItem, true); 74 setButtonEnabled(userAnswer ? pairedItem : item, false); 75 item.setTag(PASS); pairedItem.setTag(PASS); 76 if (checkAllPassed()) { 77 getPassButton().setEnabled(true); 78 } 79 return; 80 } 81 82 final int messageId = 83 actualAnswer ? R.string.tv_microphone_device_test_negative_mismatch : 84 R.string.tv_microphone_device_test_positive_mismatch; 85 Toast.makeText(this, messageId, Toast.LENGTH_LONG).show(); 86 setPassState(userAnswer ? item : pairedItem, false); 87 getPassButton().setEnabled(false); 88 return; 89 } 90 } 91 } 92 93 @Override createTestItems()94 protected void createTestItems() { 95 mPreparationYesItem = createAndAttachUserItem( 96 R.string.tv_microphone_device_test_prep_question, 97 R.string.tv_yes, this); 98 setButtonEnabled(mPreparationYesItem, true); 99 mPreparationNoItem = createAndAttachButtonItem(R.string.tv_no, this); 100 setButtonEnabled(mPreparationNoItem, true); 101 } 102 createInputDeviceItems()103 private void createInputDeviceItems() { 104 final Context context = MicrophoneDeviceTestActivity.this; 105 mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE); 106 107 final int[] inputDeviceIds = mInputManager.getInputDeviceIds(); 108 mInputDeviceItems = new HashMap<View, List<Object>>(); 109 110 for (int inputDeviceId : inputDeviceIds) { 111 final InputDevice inputDevice = mInputManager.getInputDevice(inputDeviceId); 112 final boolean hasMicrophone = inputDevice.hasMicrophone(); 113 Log.w(TAG, "name: " + inputDevice.getName() + ", mic: " + hasMicrophone + ", virtual: " 114 + inputDevice.isVirtual() + ", descriptor: " + inputDevice.getDescriptor()); 115 116 // Skip virtual input devices such as virtual keyboards. This does 117 // not, e.g., include com.google.android.tv.remote bluetooth connections. 118 if (inputDevice.isVirtual()) { 119 continue; 120 } 121 122 final CharSequence micQuestion = 123 getString(R.string.tv_microphone_device_test_mic_question, inputDevice.getName()); 124 125 final View inputDeviceYesItem = 126 createAndAttachUserItem(micQuestion, R.string.tv_yes, this); 127 setButtonEnabled(inputDeviceYesItem, true); 128 final View inputDeviceNoItem = createAndAttachButtonItem(R.string.tv_no, this); 129 setButtonEnabled(inputDeviceNoItem, true); 130 mInputDeviceItems.put( 131 inputDeviceYesItem, Arrays.asList(true, hasMicrophone, inputDeviceNoItem)); 132 mInputDeviceItems.put( 133 inputDeviceNoItem, Arrays.asList(false, hasMicrophone, inputDeviceYesItem)); 134 } 135 136 if (mInputDeviceItems.size() == 0) { 137 Toast.makeText(this, R.string.tv_microphone_device_test_no_input_devices, 138 Toast.LENGTH_LONG).show(); 139 getPassButton().setEnabled(true); 140 } 141 } 142 143 @Override setInfoResources()144 protected void setInfoResources() { 145 setInfoResources(R.string.tv_microphone_device_test, 146 R.string.tv_microphone_device_test_info, -1); 147 } 148 hasPassed(View item)149 private boolean hasPassed(View item) { 150 return (item.getTag() != null) && ((Boolean) item.getTag()) == PASS; 151 } 152 checkAllPassed()153 private boolean checkAllPassed() { 154 if (mInputDeviceItems != null && mInputDeviceItems.size() > 0) { 155 for (View item : mInputDeviceItems.keySet()) { 156 if (!hasPassed(item)) { 157 return false; 158 } 159 } 160 } 161 return true; 162 } 163 } 164