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