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 17package com.android.server.location; 18 19import android.content.Context; 20import android.net.Proxy; 21import android.net.http.AndroidHttpClient; 22import android.util.Log; 23 24import org.apache.http.HttpEntity; 25import org.apache.http.HttpHost; 26import org.apache.http.HttpResponse; 27import org.apache.http.StatusLine; 28import org.apache.http.client.HttpClient; 29import org.apache.http.client.methods.HttpGet; 30import org.apache.http.client.methods.HttpUriRequest; 31import org.apache.http.conn.params.ConnRouteParams; 32 33import java.io.DataInputStream; 34import java.io.IOException; 35import java.util.Properties; 36import java.util.Random; 37 38/** 39 * A class for downloading GPS XTRA data. 40 * 41 * {@hide} 42 */ 43public 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