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