1 /* 2 * Copyright (C) 2011 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 package com.android.tests.bandwidthenforcement; 17 18 import android.app.IntentService; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.net.ConnectivityManager; 22 import android.net.Network; 23 import android.net.SntpClient; 24 import android.os.Environment; 25 import android.util.Log; 26 27 import java.io.BufferedWriter; 28 import java.io.ByteArrayOutputStream; 29 import java.io.File; 30 import java.io.FileWriter; 31 import java.io.IOException; 32 import java.io.InputStreamReader; 33 import java.net.DatagramPacket; 34 import java.net.DatagramSocket; 35 import java.net.HttpURLConnection; 36 import java.net.InetAddress; 37 import java.net.URL; 38 import java.util.Random; 39 40 import libcore.io.Streams; 41 42 /* 43 * Test Service that tries to connect to the web via different methods and outputs the results to 44 * the log and a output file. 45 */ 46 public class BandwidthEnforcementTestService extends IntentService { 47 private static final String TAG = "BandwidthEnforcementTestService"; 48 private static final String OUTPUT_FILE = "BandwidthEnforcementTestServiceOutputFile"; 49 50 public BandwidthEnforcementTestService() { 51 super(TAG); 52 } 53 54 @Override 55 protected void onHandleIntent(Intent intent) { 56 Log.d(TAG, "Trying to establish a connection."); 57 // Read output file path from intent. 58 String outputFile = intent.getStringExtra(OUTPUT_FILE); 59 dumpResult("testUrlConnection", testUrlConnection(), outputFile); 60 dumpResult("testUrlConnectionv6", testUrlConnectionv6(), outputFile); 61 dumpResult("testSntp", testSntp(getApplicationContext()), outputFile); 62 dumpResult("testDns", testDns(), outputFile); 63 } 64 65 public static void dumpResult(String tag, boolean result, String outputFile) { 66 Log.d(TAG, "Test output file: " + outputFile); 67 try { 68 if (outputFile != null){ 69 File extStorage = Environment.getExternalStorageDirectory(); 70 File outFile = new File(extStorage, outputFile); 71 FileWriter writer = new FileWriter(outFile, true); 72 BufferedWriter out = new BufferedWriter(writer); 73 if (result) { 74 out.append(tag + ":fail\n"); 75 } else { 76 out.append(tag + ":pass\n"); 77 } 78 out.close(); 79 } 80 if (result) { 81 Log.e(TAG, tag + " FAILURE ===================="); 82 Log.e(TAG, tag + " FAILURE was able to use data"); 83 Log.e(TAG, tag + " FAILURE ===================="); 84 } else { 85 Log.d(TAG, tag + " success; unable to use data"); 86 } 87 } catch (IOException e) { 88 Log.e(TAG, "Could not write file " + e.getMessage()); 89 } 90 } 91 92 /** 93 * Tests a normal http url connection. 94 * @return true if it was able to connect, false otherwise. 95 */ 96 public static boolean testUrlConnection() { 97 try { 98 final HttpURLConnection conn = (HttpURLConnection) new URL("http://www.google.com/") 99 .openConnection(); 100 try { 101 conn.connect(); 102 final String content = Streams.readFully( 103 new InputStreamReader(conn.getInputStream())); 104 if (content.contains("Google")) { 105 return true; 106 } 107 } finally { 108 conn.disconnect(); 109 } 110 } catch (IOException e) { 111 Log.d(TAG, "error: " + e); 112 } 113 return false; 114 } 115 116 /** 117 * Tests a ipv6 http url connection. 118 * @return true if it was able to connect, false otherwise. 119 */ 120 public static boolean testUrlConnectionv6() { 121 try { 122 final HttpURLConnection conn = (HttpURLConnection) new URL("http://ipv6.google.com/") 123 .openConnection(); 124 try { 125 conn.connect(); 126 final String content = Streams.readFully( 127 new InputStreamReader(conn.getInputStream())); 128 if (content.contains("Google")) { 129 return true; 130 } 131 } finally { 132 conn.disconnect(); 133 } 134 } catch (IOException e) { 135 Log.d(TAG, "error: " + e); 136 } 137 return false; 138 } 139 140 /** 141 * Tests to connect via sntp. 142 * @return true if it was able to connect, false otherwise. 143 */ 144 public static boolean testSntp(Context context) { 145 final SntpClient client = new SntpClient(); 146 final ConnectivityManager mCM = context.getSystemService(ConnectivityManager.class); 147 final Network network = mCM.getActiveNetwork(); 148 149 if (client.requestTime("0.pool.ntp.org", 10000, network)) { 150 return true; 151 } 152 return false; 153 } 154 155 /** 156 * Tests dns query. 157 * @return true if it was able to connect, false otherwise. 158 */ 159 public static boolean testDns() { 160 try { 161 final DatagramSocket socket = new DatagramSocket(); 162 try { 163 socket.setSoTimeout(10000); 164 165 final byte[] query = buildDnsQuery("www", "android", "com"); 166 final DatagramPacket queryPacket = new DatagramPacket( 167 query, query.length, InetAddress.parseNumericAddress("8.8.8.8"), 53); 168 socket.send(queryPacket); 169 170 final byte[] reply = new byte[query.length]; 171 final DatagramPacket replyPacket = new DatagramPacket(reply, reply.length); 172 socket.receive(replyPacket); 173 return true; 174 175 } finally { 176 socket.close(); 177 } 178 } catch (IOException e) { 179 Log.d(TAG, "error: " + e); 180 } 181 return false; 182 } 183 184 /** 185 * Helper method to build a dns query 186 * @param query the dns strings of the server 187 * @return the byte array of the dns query to send 188 * @throws IOException 189 */ 190 private static byte[] buildDnsQuery(String... query) throws IOException { 191 final Random random = new Random(); 192 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 193 194 final byte[] id = new byte[2]; 195 random.nextBytes(id); 196 197 out.write(id); 198 out.write(new byte[] { 0x01, 0x00 }); 199 out.write(new byte[] { 0x00, 0x01 }); 200 out.write(new byte[] { 0x00, 0x00 }); 201 out.write(new byte[] { 0x00, 0x00 }); 202 out.write(new byte[] { 0x00, 0x00 }); 203 204 for (String phrase : query) { 205 final byte[] bytes = phrase.getBytes("US-ASCII"); 206 out.write(bytes.length); 207 out.write(bytes); 208 } 209 out.write(0x00); 210 211 out.write(new byte[] { 0x00, 0x01 }); 212 out.write(new byte[] { 0x00, 0x01 }); 213 214 return out.toByteArray(); 215 } 216 } 217