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