1 /* 2 * Copyright (C) 2016 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.tv; 18 19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 20 import com.android.ddmlib.Log.LogLevel; 21 import com.android.tradefed.build.IBuildInfo; 22 import com.android.tradefed.device.DeviceNotAvailableException; 23 import com.android.tradefed.device.ITestDevice; 24 import com.android.tradefed.log.LogUtil.CLog; 25 import com.android.tradefed.testtype.DeviceTestCase; 26 import com.android.tradefed.testtype.IAbi; 27 import com.android.tradefed.testtype.IAbiReceiver; 28 import com.android.tradefed.testtype.IBuildReceiver; 29 30 import java.io.FileNotFoundException; 31 import java.util.HashSet; 32 import java.util.Map; 33 import java.util.Scanner; 34 35 public class TvInputManagerHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver { 36 private static final String TEST_APK = "CtsHostsideTvInputApp.apk"; 37 private static final String TEST_APK2 = "CtsHostsideTvInputMonitor.apk"; 38 private static final String TEST_PKG = "com.android.cts.tv.hostside"; 39 private static final String TEST_PKG2 = "com.android.cts.tv.hostside.app2"; 40 private static final String CLASS = "TvViewMonitorActivity"; 41 private static final String INPUT_UPDATED_STRING = "HOST_SIDE_TEST_TV_INTPUT_IS_UPDATED"; 42 private static final String START_COMMAND = String.format( 43 "am start -W -a android.intent.action.MAIN -n %s/%s.%s", TEST_PKG2, TEST_PKG2, CLASS); 44 private static final String FEATURE_LIVE_TV = "android.software.live_tv"; 45 46 private boolean mHasFeatureLiveTv; 47 private IAbi mAbi; 48 private IBuildInfo mCtsBuildInfo; 49 private HashSet<String> mAvailableFeatures; 50 installPackage(String apk)51 private void installPackage(String apk) throws FileNotFoundException, 52 DeviceNotAvailableException { 53 CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuildInfo); 54 assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), true)); 55 } 56 uninstallPackage(String packageName, boolean shouldSucceed)57 private void uninstallPackage(String packageName, boolean shouldSucceed) 58 throws DeviceNotAvailableException { 59 final String result = getDevice().uninstallPackage(packageName); 60 if (shouldSucceed) { 61 assertNull("uninstallPackage(" + packageName + ") failed: " + result, result); 62 } 63 } 64 65 @Override setAbi(IAbi abi)66 public void setAbi(IAbi abi) { 67 mAbi = abi; 68 } 69 70 @Override setBuild(IBuildInfo buildInfo)71 public void setBuild(IBuildInfo buildInfo) { 72 mCtsBuildInfo = buildInfo; 73 } 74 75 @Override setUp()76 protected void setUp() throws Exception { 77 super.setUp(); 78 79 assertNotNull(mAbi); 80 assertNotNull(mCtsBuildInfo); 81 mHasFeatureLiveTv = hasDeviceFeature(FEATURE_LIVE_TV); 82 if (mHasFeatureLiveTv) { 83 uninstallPackage(TEST_PKG, false); 84 uninstallPackage(TEST_PKG2, false); 85 installPackage(TEST_APK); 86 installPackage(TEST_APK2); 87 } 88 } 89 90 @Override tearDown()91 protected void tearDown() throws Exception { 92 super.tearDown(); 93 if (mHasFeatureLiveTv) { 94 uninstallPackage(TEST_PKG, true); 95 uninstallPackage(TEST_PKG2, true); 96 } 97 } 98 testInputUpdated()99 public void testInputUpdated() throws Exception { 100 if (!mHasFeatureLiveTv) { 101 return; 102 } 103 ITestDevice device = getDevice(); 104 device.executeAdbCommand("logcat", "-c"); 105 device.executeShellCommand(START_COMMAND); 106 // Re-install the input app so the monitoring app can get the onInputUpdated callback. 107 installPackage(TEST_APK); 108 String testString = ""; 109 for (int i = 0; i < 5; ++i) { 110 // Try 5 times as this sometimes fails. 111 String logs = device.executeAdbCommand( 112 "logcat", "-v", "brief", "-d", CLASS + ":I", "*:S"); 113 Scanner in = new Scanner(logs); 114 while (in.hasNextLine()) { 115 String line = in.nextLine(); 116 if (line.contains(INPUT_UPDATED_STRING)) { 117 testString = line.split(":")[1].trim(); 118 } 119 } 120 in.close(); 121 if (!testString.isEmpty()) { 122 break; 123 } 124 // Wait for the system service to handle the installation. 125 Thread.currentThread().sleep(100); 126 } 127 assertEquals("Incorrect test string", INPUT_UPDATED_STRING, testString); 128 } 129 hasDeviceFeature(String requiredFeature)130 private boolean hasDeviceFeature(String requiredFeature) throws DeviceNotAvailableException { 131 if (mAvailableFeatures == null) { 132 // TODO: Move this logic to ITestDevice. 133 String command = "pm list features"; 134 String commandOutput = getDevice().executeShellCommand(command); 135 CLog.i("Output for command " + command + ": " + commandOutput); 136 137 // Extract the id of the new user. 138 mAvailableFeatures = new HashSet<>(); 139 for (String feature: commandOutput.split("\\s+")) { 140 // Each line in the output of the command has the format "feature:{FEATURE_VALUE}". 141 String[] tokens = feature.split(":"); 142 assertTrue("\"" + feature + "\" expected to have format feature:{FEATURE_VALUE}", 143 tokens.length > 1); 144 assertEquals(feature, "feature", tokens[0]); 145 mAvailableFeatures.add(tokens[1]); 146 } 147 } 148 boolean result = mAvailableFeatures.contains(requiredFeature); 149 if (!result) { 150 CLog.logAndDisplay(LogLevel.INFO, "Device doesn't have required feature " 151 + requiredFeature + ". Test won't run."); 152 } 153 return result; 154 } 155 } 156