1 /* 2 * Copyright (C) 2018 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.net.cts; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertNotEquals; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assume.assumeTrue; 24 25 import android.content.Context; 26 import android.net.ConnectivityManager; 27 import android.platform.test.annotations.AppModeFull; 28 import android.os.FileUtils; 29 import android.os.ParcelFileDescriptor; 30 31 import androidx.test.InstrumentationRegistry; 32 import androidx.test.filters.SmallTest; 33 import androidx.test.runner.AndroidJUnit4; 34 35 import com.android.compatibility.common.util.ApiLevelUtil; 36 import com.android.compatibility.common.util.SystemUtil; 37 38 import org.junit.After; 39 import org.junit.Assert; 40 import org.junit.Before; 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 44 import java.io.FileOutputStream; 45 import java.io.IOException; 46 import java.io.InputStream; 47 import java.util.Formatter; 48 49 @SmallTest 50 @RunWith(AndroidJUnit4.class) 51 public class NetworkWatchlistTest { 52 53 private static final String TEST_WATCHLIST_XML = "assets/network_watchlist_config_for_test.xml"; 54 private static final String TEST_EMPTY_WATCHLIST_XML = 55 "assets/network_watchlist_config_empty_for_test.xml"; 56 private static final String TMP_CONFIG_PATH = 57 "/data/local/tmp/network_watchlist_config_for_test.xml"; 58 // Generated from sha256sum network_watchlist_config_for_test.xml 59 private static final String TEST_WATCHLIST_CONFIG_HASH = 60 "B5FC4636994180D54E1E912F78178AB1D8BD2BE71D90CA9F5BBC3284E4D04ED4"; 61 62 private ConnectivityManager mConnectivityManager; 63 private boolean mHasFeature; 64 65 @Before setUp()66 public void setUp() throws Exception { 67 mHasFeature = isAtLeastP(); 68 mConnectivityManager = 69 (ConnectivityManager) InstrumentationRegistry.getContext().getSystemService( 70 Context.CONNECTIVITY_SERVICE); 71 assumeTrue(mHasFeature); 72 // Set empty watchlist test config before testing 73 setWatchlistConfig(TEST_EMPTY_WATCHLIST_XML); 74 // Verify test watchlist config is not set before testing 75 byte[] result = mConnectivityManager.getNetworkWatchlistConfigHash(); 76 assertNotNull("Watchlist config does not exist", result); 77 assertNotEquals(TEST_WATCHLIST_CONFIG_HASH, byteArrayToHexString(result)); 78 } 79 80 @After tearDown()81 public void tearDown() throws Exception { 82 if (mHasFeature) { 83 // Set empty watchlist test config after testing 84 setWatchlistConfig(TEST_EMPTY_WATCHLIST_XML); 85 } 86 } 87 cleanup()88 private void cleanup() throws IOException { 89 runCommand("rm " + TMP_CONFIG_PATH); 90 } 91 isAtLeastP()92 private boolean isAtLeastP() throws Exception { 93 // TODO: replace with ApiLevelUtil.isAtLeast(Build.VERSION_CODES.P) when the P API level 94 // constant is defined. 95 return ApiLevelUtil.getCodename().compareToIgnoreCase("P") >= 0; 96 } 97 98 /** 99 * Test if ConnectivityManager.getNetworkWatchlistConfigHash() correctly 100 * returns the hash of config we set. 101 */ 102 @Test 103 @AppModeFull(reason = "Cannot access resource file in instant app mode") testGetWatchlistConfigHash()104 public void testGetWatchlistConfigHash() throws Exception { 105 // Set watchlist config file for test 106 setWatchlistConfig(TEST_WATCHLIST_XML); 107 // Test if watchlist config hash value is correct 108 byte[] result = mConnectivityManager.getNetworkWatchlistConfigHash(); 109 Assert.assertEquals(TEST_WATCHLIST_CONFIG_HASH, byteArrayToHexString(result)); 110 } 111 byteArrayToHexString(byte[] bytes)112 private static String byteArrayToHexString(byte[] bytes) { 113 Formatter formatter = new Formatter(); 114 for (byte b : bytes) { 115 formatter.format("%02X", b); 116 } 117 return formatter.toString(); 118 } 119 saveResourceToFile(String res, String filePath)120 private void saveResourceToFile(String res, String filePath) throws IOException { 121 // App can't access /data/local/tmp directly, so we pipe resource to file through stdin. 122 ParcelFileDescriptor stdin = pipeFromStdin(filePath); 123 pipeResourceToFileDescriptor(res, stdin); 124 } 125 126 /* Pipe stdin to a file in filePath. Returns PFD for stdin. */ pipeFromStdin(String filePath)127 private ParcelFileDescriptor pipeFromStdin(String filePath) { 128 // Not all devices have symlink for /dev/stdin, so use /proc/self/fd/0 directly. 129 // /dev/stdin maps to /proc/self/fd/0. 130 return runRwCommand("cp /proc/self/fd/0 " + filePath)[1]; 131 } 132 pipeResourceToFileDescriptor(String res, ParcelFileDescriptor pfd)133 private void pipeResourceToFileDescriptor(String res, ParcelFileDescriptor pfd) 134 throws IOException { 135 InputStream resStream = getClass().getClassLoader().getResourceAsStream(res); 136 FileOutputStream fdStream = new ParcelFileDescriptor.AutoCloseOutputStream(pfd); 137 138 FileUtils.copy(resStream, fdStream); 139 140 try { 141 fdStream.close(); 142 } catch (IOException e) { 143 } 144 } 145 runCommand(String command)146 private static String runCommand(String command) throws IOException { 147 return SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command); 148 } 149 runRwCommand(String command)150 private static ParcelFileDescriptor[] runRwCommand(String command) { 151 return InstrumentationRegistry.getInstrumentation() 152 .getUiAutomation().executeShellCommandRw(command); 153 } 154 setWatchlistConfig(String watchlistConfigFile)155 private void setWatchlistConfig(String watchlistConfigFile) throws Exception { 156 cleanup(); 157 saveResourceToFile(watchlistConfigFile, TMP_CONFIG_PATH); 158 final String cmdResult = runCommand( 159 "cmd network_watchlist set-test-config " + TMP_CONFIG_PATH).trim(); 160 assertThat(cmdResult).contains("Success"); 161 cleanup(); 162 } 163 } 164