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.text.TextUtils; 20 import android.util.Log; 21 22 import java.io.IOException; 23 import java.net.HttpURLConnection; 24 import java.net.URL; 25 26 import java.io.ByteArrayOutputStream; 27 import java.io.InputStream; 28 import java.io.IOException; 29 import java.util.Properties; 30 import java.util.Random; 31 import java.util.concurrent.TimeUnit; 32 33 import libcore.io.Streams; 34 35 /** 36 * A class for downloading GPS XTRA data. 37 * 38 * {@hide} 39 */ 40 public class GpsXtraDownloader { 41 42 private static final String TAG = "GpsXtraDownloader"; 43 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 44 private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000; // 1MB. 45 private static final String DEFAULT_USER_AGENT = "Android"; 46 private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30); 47 48 private final String[] mXtraServers; 49 // to load balance our server requests 50 private int mNextServerIndex; 51 private final String mUserAgent; 52 53 GpsXtraDownloader(Properties properties) { 54 // read XTRA servers from the Properties object 55 int count = 0; 56 String server1 = properties.getProperty("XTRA_SERVER_1"); 57 String server2 = properties.getProperty("XTRA_SERVER_2"); 58 String server3 = properties.getProperty("XTRA_SERVER_3"); 59 if (server1 != null) count++; 60 if (server2 != null) count++; 61 if (server3 != null) count++; 62 63 // Set User Agent from properties, if possible. 64 String agent = properties.getProperty("XTRA_USER_AGENT"); 65 if (TextUtils.isEmpty(agent)) { 66 mUserAgent = DEFAULT_USER_AGENT; 67 } else { 68 mUserAgent = agent; 69 } 70 71 if (count == 0) { 72 Log.e(TAG, "No XTRA servers were specified in the GPS configuration"); 73 mXtraServers = null; 74 } else { 75 mXtraServers = new String[count]; 76 count = 0; 77 if (server1 != null) mXtraServers[count++] = server1; 78 if (server2 != null) mXtraServers[count++] = server2; 79 if (server3 != null) mXtraServers[count++] = server3; 80 81 // randomize first server 82 Random random = new Random(); 83 mNextServerIndex = random.nextInt(count); 84 } 85 } 86 87 byte[] downloadXtraData() { 88 byte[] result = null; 89 int startIndex = mNextServerIndex; 90 91 if (mXtraServers == null) { 92 return null; 93 } 94 95 // load balance our requests among the available servers 96 while (result == null) { 97 result = doDownload(mXtraServers[mNextServerIndex]); 98 99 // increment mNextServerIndex and wrap around if necessary 100 mNextServerIndex++; 101 if (mNextServerIndex == mXtraServers.length) { 102 mNextServerIndex = 0; 103 } 104 // break if we have tried all the servers 105 if (mNextServerIndex == startIndex) break; 106 } 107 108 return result; 109 } 110 111 protected byte[] doDownload(String url) { 112 if (DEBUG) Log.d(TAG, "Downloading XTRA data from " + url); 113 114 HttpURLConnection connection = null; 115 try { 116 connection = (HttpURLConnection) (new URL(url)).openConnection(); 117 connection.setRequestProperty( 118 "Accept", 119 "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic"); 120 connection.setRequestProperty( 121 "x-wap-profile", 122 "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#"); 123 connection.setConnectTimeout(CONNECTION_TIMEOUT_MS); 124 125 connection.connect(); 126 int statusCode = connection.getResponseCode(); 127 if (statusCode != HttpURLConnection.HTTP_OK) { 128 if (DEBUG) Log.d(TAG, "HTTP error downloading gps XTRA: " + statusCode); 129 return null; 130 } 131 132 try (InputStream in = connection.getInputStream()) { 133 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 134 byte[] buffer = new byte[1024]; 135 int count; 136 while ((count = in.read(buffer)) != -1) { 137 bytes.write(buffer, 0, count); 138 if (bytes.size() > MAXIMUM_CONTENT_LENGTH_BYTES) { 139 if (DEBUG) Log.d(TAG, "XTRA file too large"); 140 return null; 141 } 142 } 143 return bytes.toByteArray(); 144 } 145 } catch (IOException ioe) { 146 if (DEBUG) Log.d(TAG, "Error downloading gps XTRA: ", ioe); 147 } finally { 148 if (connection != null) { 149 connection.disconnect(); 150 } 151 } 152 return null; 153 } 154 155 } 156 157