1/*
2 * Copyright (C) 2011 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.gallery3d.common;
18
19import android.content.Context;
20import android.content.pm.PackageInfo;
21import android.content.pm.PackageManager.NameNotFoundException;
22import android.os.Build;
23
24import org.apache.http.HttpVersion;
25import org.apache.http.client.HttpClient;
26import org.apache.http.conn.params.ConnManagerParams;
27import org.apache.http.params.CoreProtocolPNames;
28import org.apache.http.params.HttpParams;
29
30import java.lang.reflect.InvocationTargetException;
31import java.lang.reflect.Method;
32
33/**
34 * Constructs {@link HttpClient} instances and isolates client code from API
35 * level differences.
36 */
37public final class HttpClientFactory {
38    // TODO: migrate GDataClient to use this util method instead of apache's
39    // DefaultHttpClient.
40    /**
41     * Creates an HttpClient with the userAgent string constructed from the
42     * package name contained in the context.
43     * @return the client
44     */
45    public static HttpClient newHttpClient(Context context) {
46        return HttpClientFactory.newHttpClient(getUserAgent(context));
47    }
48
49    /**
50     * Creates an HttpClient with the specified userAgent string.
51     * @param userAgent the userAgent string
52     * @return the client
53     */
54    public static HttpClient newHttpClient(String userAgent) {
55        // AndroidHttpClient is available on all platform releases,
56        // but is hidden until API Level 8
57        try {
58            Class<?> clazz = Class.forName("android.net.http.AndroidHttpClient");
59            Method newInstance = clazz.getMethod("newInstance", String.class);
60            Object instance = newInstance.invoke(null, userAgent);
61
62            HttpClient client = (HttpClient) instance;
63
64            // ensure we default to HTTP 1.1
65            HttpParams params = client.getParams();
66            params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
67
68            // AndroidHttpClient sets these two parameters thusly by default:
69            // HttpConnectionParams.setSoTimeout(params, 60 * 1000);
70            // HttpConnectionParams.setConnectionTimeout(params, 60 * 1000);
71
72            // however it doesn't set this one...
73            ConnManagerParams.setTimeout(params, 60 * 1000);
74
75            return client;
76        } catch (InvocationTargetException e) {
77            throw new RuntimeException(e);
78        } catch (ClassNotFoundException e) {
79            throw new RuntimeException(e);
80        } catch (NoSuchMethodException e) {
81            throw new RuntimeException(e);
82        } catch (IllegalAccessException e) {
83            throw new RuntimeException(e);
84        }
85    }
86
87    /**
88     * Closes an HttpClient.
89     */
90    public static void close(HttpClient client) {
91        // AndroidHttpClient is available on all platform releases,
92        // but is hidden until API Level 8
93        try {
94            Class<?> clazz = client.getClass();
95            Method method = clazz.getMethod("close", (Class<?>[]) null);
96            method.invoke(client, (Object[]) null);
97        } catch (InvocationTargetException e) {
98            throw new RuntimeException(e);
99        } catch (NoSuchMethodException e) {
100            throw new RuntimeException(e);
101        } catch (IllegalAccessException e) {
102            throw new RuntimeException(e);
103        }
104    }
105
106    private static String sUserAgent = null;
107
108    private static String getUserAgent(Context context) {
109        if (sUserAgent == null) {
110            PackageInfo pi;
111            try {
112                pi = context.getPackageManager().getPackageInfo(
113                        context.getPackageName(), 0);
114            } catch (NameNotFoundException e) {
115                throw new IllegalStateException("getPackageInfo failed");
116            }
117            sUserAgent = String.format("%s/%s; %s/%s/%s/%s; %s/%s/%s",
118                    pi.packageName,
119                    pi.versionName,
120                    Build.BRAND,
121                    Build.DEVICE,
122                    Build.MODEL,
123                    Build.ID,
124                    Build.VERSION.SDK_INT,
125                    Build.VERSION.RELEASE,
126                    Build.VERSION.INCREMENTAL);
127        }
128        return sUserAgent;
129    }
130
131    private HttpClientFactory() {
132    }
133}
134