1 /* 2 * Copyright (C) 2010 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.dumprendertree2; 18 19 import android.util.Log; 20 21 import com.android.dumprendertree2.forwarder.ForwarderManager; 22 23 import org.apache.http.HttpEntity; 24 import org.apache.http.HttpResponse; 25 import org.apache.http.HttpStatus; 26 import org.apache.http.client.HttpClient; 27 import org.apache.http.client.ResponseHandler; 28 import org.apache.http.client.methods.HttpGet; 29 import org.apache.http.conn.ClientConnectionManager; 30 import org.apache.http.conn.scheme.PlainSocketFactory; 31 import org.apache.http.conn.scheme.Scheme; 32 import org.apache.http.conn.scheme.SchemeRegistry; 33 import org.apache.http.conn.ssl.SSLSocketFactory; 34 import org.apache.http.impl.client.DefaultHttpClient; 35 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 36 import org.apache.http.params.BasicHttpParams; 37 import org.apache.http.params.HttpConnectionParams; 38 import org.apache.http.params.HttpParams; 39 import org.apache.http.util.EntityUtils; 40 41 import java.io.BufferedReader; 42 import java.io.BufferedWriter; 43 import java.io.File; 44 import java.io.FileInputStream; 45 import java.io.FileOutputStream; 46 import java.io.FileReader; 47 import java.io.FileWriter; 48 import java.io.IOException; 49 import java.io.InputStream; 50 import java.io.InputStreamReader; 51 import java.io.OutputStream; 52 import java.net.MalformedURLException; 53 import java.net.SocketTimeoutException; 54 import java.net.URL; 55 import java.util.ArrayList; 56 import java.util.LinkedList; 57 import java.util.List; 58 59 /** 60 * 61 */ 62 public class FsUtils { 63 public static final String LOG_TAG = "FsUtils"; 64 65 private static final String SCRIPT_URL = ForwarderManager.getHostSchemePort(false) + 66 "Tools/DumpRenderTree/android/get_layout_tests_dir_contents.php"; 67 68 private static final int HTTP_TIMEOUT_MS = 5000; 69 70 private static HttpClient sHttpClient; 71 72 private static HttpClient getHttpClient() { 73 if (sHttpClient == null) { 74 HttpParams params = new BasicHttpParams(); 75 76 SchemeRegistry schemeRegistry = new SchemeRegistry(); 77 schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 78 ForwarderManager.HTTP_PORT)); 79 schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 80 ForwarderManager.HTTPS_PORT)); 81 82 ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(params, 83 schemeRegistry); 84 sHttpClient = new DefaultHttpClient(connectionManager, params); 85 HttpConnectionParams.setSoTimeout(sHttpClient.getParams(), HTTP_TIMEOUT_MS); 86 HttpConnectionParams.setConnectionTimeout(sHttpClient.getParams(), HTTP_TIMEOUT_MS); 87 } 88 return sHttpClient; 89 } 90 91 public static void writeDataToStorage(File file, byte[] bytes, boolean append) { 92 Log.d(LOG_TAG, "writeDataToStorage(): " + file.getAbsolutePath()); 93 try { 94 OutputStream outputStream = null; 95 try { 96 file.getParentFile().mkdirs(); 97 file.createNewFile(); 98 Log.d(LOG_TAG, "writeDataToStorage(): File created: " + file.getAbsolutePath()); 99 outputStream = new FileOutputStream(file, append); 100 outputStream.write(bytes); 101 } finally { 102 if (outputStream != null) { 103 outputStream.close(); 104 } 105 } 106 } catch (IOException e) { 107 Log.e(LOG_TAG, "file.getAbsolutePath=" + file.getAbsolutePath() + " append=" + append, 108 e); 109 } 110 } 111 112 public static byte[] readDataFromStorage(File file) { 113 if (!file.exists()) { 114 Log.d(LOG_TAG, "readDataFromStorage(): File does not exist: " 115 + file.getAbsolutePath()); 116 return null; 117 } 118 119 byte[] bytes = null; 120 try { 121 FileInputStream fis = null; 122 try { 123 fis = new FileInputStream(file); 124 bytes = new byte[(int)file.length()]; 125 fis.read(bytes); 126 } finally { 127 if (fis != null) { 128 fis.close(); 129 } 130 } 131 } catch (IOException e) { 132 Log.e(LOG_TAG, "file.getAbsolutePath=" + file.getAbsolutePath(), e); 133 } 134 135 return bytes; 136 } 137 138 static class UrlDataGetter extends Thread { 139 private URL mUrl; 140 private byte[] mBytes; 141 private boolean mGetComplete; 142 public UrlDataGetter(URL url) { 143 mUrl = url; 144 } 145 public byte[] get() { 146 start(); 147 synchronized(this) { 148 while (!mGetComplete) { 149 try{ 150 wait(); 151 } catch(InterruptedException e) { 152 } 153 } 154 } 155 return mBytes; 156 } 157 public synchronized void run() { 158 mGetComplete = false; 159 HttpGet httpRequest = new HttpGet(mUrl.toString()); 160 ResponseHandler<byte[]> handler = new ResponseHandler<byte[]>() { 161 @Override 162 public byte[] handleResponse(HttpResponse response) throws IOException { 163 if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { 164 return null; 165 } 166 HttpEntity entity = response.getEntity(); 167 return (entity == null ? null : EntityUtils.toByteArray(entity)); 168 } 169 }; 170 171 mBytes = null; 172 try { 173 /** 174 * TODO: Not exactly sure why some requests hang indefinitely, but adding this 175 * timeout (in static getter for http client) in loop helps. 176 */ 177 boolean timedOut; 178 do { 179 timedOut = false; 180 try { 181 mBytes = getHttpClient().execute(httpRequest, handler); 182 } catch (SocketTimeoutException e) { 183 timedOut = true; 184 Log.w(LOG_TAG, "Expected SocketTimeoutException: " + mUrl, e); 185 } 186 } while (timedOut); 187 } catch (IOException e) { 188 Log.e(LOG_TAG, "url=" + mUrl, e); 189 } 190 191 mGetComplete = true; 192 notify(); 193 } 194 } 195 196 public static byte[] readDataFromUrl(URL url) { 197 if (url == null) { 198 Log.w(LOG_TAG, "readDataFromUrl(): url is null!"); 199 return null; 200 } 201 202 UrlDataGetter getter = new UrlDataGetter(url); 203 return getter.get(); 204 } 205 206 public static List<String> getLayoutTestsDirContents(String dirRelativePath, boolean recurse, 207 boolean mode) { 208 String modeString = (mode ? "folders" : "files"); 209 210 URL url = null; 211 try { 212 url = new URL(SCRIPT_URL + 213 "?path=" + dirRelativePath + 214 "&recurse=" + recurse + 215 "&mode=" + modeString); 216 } catch (MalformedURLException e) { 217 Log.e(LOG_TAG, "path=" + dirRelativePath + " recurse=" + recurse + " mode=" + 218 modeString, e); 219 return new LinkedList<String>(); 220 } 221 222 HttpGet httpRequest = new HttpGet(url.toString()); 223 ResponseHandler<LinkedList<String>> handler = new ResponseHandler<LinkedList<String>>() { 224 @Override 225 public LinkedList<String> handleResponse(HttpResponse response) 226 throws IOException { 227 LinkedList<String> lines = new LinkedList<String>(); 228 229 if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { 230 return lines; 231 } 232 HttpEntity entity = response.getEntity(); 233 if (entity == null) { 234 return lines; 235 } 236 237 BufferedReader reader = 238 new BufferedReader(new InputStreamReader(entity.getContent())); 239 String line; 240 try { 241 while ((line = reader.readLine()) != null) { 242 lines.add(line); 243 } 244 } finally { 245 if (reader != null) { 246 reader.close(); 247 } 248 } 249 250 return lines; 251 } 252 }; 253 254 try { 255 return getHttpClient().execute(httpRequest, handler); 256 } catch (IOException e) { 257 Log.e(LOG_TAG, "getLayoutTestsDirContents(): HTTP GET failed for URL " + url); 258 return null; 259 } 260 } 261 262 public static void closeInputStream(InputStream inputStream) { 263 try { 264 if (inputStream != null) { 265 inputStream.close(); 266 } 267 } catch (IOException e) { 268 Log.e(LOG_TAG, "Couldn't close stream!", e); 269 } 270 } 271 272 public static void closeOutputStream(OutputStream outputStream) { 273 try { 274 if (outputStream != null) { 275 outputStream.close(); 276 } 277 } catch (IOException e) { 278 Log.e(LOG_TAG, "Couldn't close stream!", e); 279 } 280 } 281 282 public static List<String> loadTestListFromStorage(String path) { 283 List<String> list = new ArrayList<String>(); 284 if (path != null && !path.isEmpty()) { 285 try { 286 File file = new File(path); 287 Log.d(LOG_TAG, "test list loaded from " + path); 288 BufferedReader reader = new BufferedReader(new FileReader(file)); 289 String line = null; 290 while ((line = reader.readLine()) != null) { 291 list.add(line); 292 } 293 reader.close(); 294 } catch (IOException ioe) { 295 Log.e(LOG_TAG, "failed to load test list", ioe); 296 } 297 } 298 return list; 299 } 300 301 public static void saveTestListToStorage(File file, int start, List<String> testList) { 302 try { 303 BufferedWriter writer = new BufferedWriter( 304 new FileWriter(file)); 305 for (String line : testList.subList(start, testList.size())) { 306 writer.write(line + '\n'); 307 } 308 writer.flush(); 309 writer.close(); 310 } catch (IOException e) { 311 Log.e(LOG_TAG, "failed to write test list", e); 312 } 313 } 314 } 315