Home | History | Annotate | Download | only in location
      1 /*
      2  * Copyright (C) 2008 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.server.location;
     18 
     19 import android.content.Context;
     20 import android.net.Proxy;
     21 import android.net.http.AndroidHttpClient;
     22 import android.util.Log;
     23 
     24 import org.apache.http.HttpEntity;
     25 import org.apache.http.HttpHost;
     26 import org.apache.http.HttpResponse;
     27 import org.apache.http.StatusLine;
     28 import org.apache.http.client.HttpClient;
     29 import org.apache.http.client.methods.HttpGet;
     30 import org.apache.http.client.methods.HttpUriRequest;
     31 import org.apache.http.conn.params.ConnRouteParams;
     32 
     33 import java.io.DataInputStream;
     34 import java.io.IOException;
     35 import java.util.Properties;
     36 import java.util.Random;
     37 
     38 /**
     39  * A class for downloading GPS XTRA data.
     40  *
     41  * {@hide}
     42  */
     43 public class GpsXtraDownloader {
     44 
     45     private static final String TAG = "GpsXtraDownloader";
     46     static final boolean DEBUG = false;
     47 
     48     private Context mContext;
     49     private String[] mXtraServers;
     50     // to load balance our server requests
     51     private int mNextServerIndex;
     52 
     53     GpsXtraDownloader(Context context, Properties properties) {
     54         mContext = context;
     55 
     56         // read XTRA servers from the Properties object
     57         int count = 0;
     58         String server1 = properties.getProperty("XTRA_SERVER_1");
     59         String server2 = properties.getProperty("XTRA_SERVER_2");
     60         String server3 = properties.getProperty("XTRA_SERVER_3");
     61         if (server1 != null) count++;
     62         if (server2 != null) count++;
     63         if (server3 != null) count++;
     64 
     65         if (count == 0) {
     66             Log.e(TAG, "No XTRA servers were specified in the GPS configuration");
     67             return;
     68         } else {
     69             mXtraServers = new String[count];
     70             count = 0;
     71             if (server1 != null) mXtraServers[count++] = server1;
     72             if (server2 != null) mXtraServers[count++] = server2;
     73             if (server3 != null) mXtraServers[count++] = server3;
     74 
     75             // randomize first server
     76             Random random = new Random();
     77             mNextServerIndex = random.nextInt(count);
     78         }
     79     }
     80 
     81     byte[] downloadXtraData() {
     82         String proxyHost = Proxy.getHost(mContext);
     83         int proxyPort = Proxy.getPort(mContext);
     84         boolean useProxy = (proxyHost != null && proxyPort != -1);
     85         byte[] result = null;
     86         int startIndex = mNextServerIndex;
     87 
     88         if (mXtraServers == null) {
     89             return null;
     90         }
     91 
     92         // load balance our requests among the available servers
     93         while (result == null) {
     94             result = doDownload(mXtraServers[mNextServerIndex], useProxy, proxyHost, proxyPort);
     95 
     96             // increment mNextServerIndex and wrap around if necessary
     97             mNextServerIndex++;
     98             if (mNextServerIndex == mXtraServers.length) {
     99                 mNextServerIndex = 0;
    100             }
    101             // break if we have tried all the servers
    102             if (mNextServerIndex == startIndex) break;
    103         }
    104 
    105         return result;
    106     }
    107 
    108     protected static byte[] doDownload(String url, boolean isProxySet,
    109             String proxyHost, int proxyPort) {
    110         if (DEBUG) Log.d(TAG, "Downloading XTRA data from " + url);
    111 
    112         AndroidHttpClient client = null;
    113         try {
    114             client = AndroidHttpClient.newInstance("Android");
    115             HttpUriRequest req = new HttpGet(url);
    116 
    117             if (isProxySet) {
    118                 HttpHost proxy = new HttpHost(proxyHost, proxyPort);
    119                 ConnRouteParams.setDefaultProxy(req.getParams(), proxy);
    120             }
    121 
    122             req.addHeader(
    123                     "Accept",
    124                     "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
    125 
    126             req.addHeader(
    127                     "x-wap-profile",
    128                     "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
    129 
    130             HttpResponse response = client.execute(req);
    131             StatusLine status = response.getStatusLine();
    132             if (status.getStatusCode() != 200) { // HTTP 200 is success.
    133                 if (DEBUG) Log.d(TAG, "HTTP error: " + status.getReasonPhrase());
    134                 return null;
    135             }
    136 
    137             HttpEntity entity = response.getEntity();
    138             byte[] body = null;
    139             if (entity != null) {
    140                 try {
    141                     if (entity.getContentLength() > 0) {
    142                         body = new byte[(int) entity.getContentLength()];
    143                         DataInputStream dis = new DataInputStream(entity.getContent());
    144                         try {
    145                             dis.readFully(body);
    146                         } finally {
    147                             try {
    148                                 dis.close();
    149                             } catch (IOException e) {
    150                                 Log.e(TAG, "Unexpected IOException.", e);
    151                             }
    152                         }
    153                     }
    154                 } finally {
    155                     if (entity != null) {
    156                         entity.consumeContent();
    157                     }
    158                 }
    159             }
    160             return body;
    161         } catch (Exception e) {
    162             if (DEBUG) Log.d(TAG, "error " + e);
    163         } finally {
    164             if (client != null) {
    165                 client.close();
    166             }
    167         }
    168         return null;
    169     }
    170 
    171 }
    172