Home | History | Annotate | Download | only in bandwidthenforcement
      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