Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aaebc863 authored by Patrick Scott's avatar Patrick Scott
Browse files

Remove the network connection logic from RequestQueue.

This doesn't always work right and is causing some problems if the network comes
back up without sending the broadcast.
parent b9c107a3
Loading
Loading
Loading
Loading
+5 −11
Original line number Original line Diff line number Diff line
@@ -251,9 +251,7 @@ abstract class Connection {
                            pipe.addLast(req);
                            pipe.addLast(req);
                        }
                        }
                        exception = null;
                        exception = null;
                        state = (clearPipe(pipe) ||
                        state = clearPipe(pipe) ? DONE : SEND;
                                 !mConnectionManager.isNetworkConnected()) ?
                                DONE : SEND;
                        minPipe = maxPipe = 1;
                        minPipe = maxPipe = 1;
                        break;
                        break;
                    }
                    }
@@ -314,9 +312,7 @@ abstract class Connection {
                        mHttpContext.removeAttribute(HTTP_CONNECTION);
                        mHttpContext.removeAttribute(HTTP_CONNECTION);
                        clearPipe(pipe);
                        clearPipe(pipe);
                        minPipe = maxPipe = 1;
                        minPipe = maxPipe = 1;
                        /* If network active continue to service this queue */
                        state = SEND;
                        state = mConnectionManager.isNetworkConnected() ?
                                SEND : DONE;
                    }
                    }
                    break;
                    break;
                }
                }
@@ -408,8 +404,7 @@ abstract class Connection {
        if (error == EventHandler.OK) {
        if (error == EventHandler.OK) {
            return true;
            return true;
        } else {
        } else {
            if (mConnectionManager.isNetworkConnected() == false ||
            if (req.mFailCount < RETRY_REQUEST_LIMIT) {
                req.mFailCount < RETRY_REQUEST_LIMIT) {
                // requeue
                // requeue
                mRequestFeeder.requeueRequest(req);
                mRequestFeeder.requeueRequest(req);
                req.mFailCount++;
                req.mFailCount++;
@@ -432,14 +427,13 @@ abstract class Connection {
     */
     */
    private boolean httpFailure(Request req, int errorId, Exception e) {
    private boolean httpFailure(Request req, int errorId, Exception e) {
        boolean ret = true;
        boolean ret = true;
        boolean networkConnected = mConnectionManager.isNetworkConnected();


        // e.printStackTrace();
        // e.printStackTrace();
        if (HttpLog.LOGV) HttpLog.v(
        if (HttpLog.LOGV) HttpLog.v(
                "httpFailure() ******* " + e + " count " + req.mFailCount +
                "httpFailure() ******* " + e + " count " + req.mFailCount +
                " networkConnected " + networkConnected + " " + mHost + " " + req.getUri());
                " " + mHost + " " + req.getUri());


        if (networkConnected && ++req.mFailCount >= RETRY_REQUEST_LIMIT) {
        if (++req.mFailCount >= RETRY_REQUEST_LIMIT) {
            ret = false;
            ret = false;
            String error;
            String error;
            if (errorId < 0) {
            if (errorId < 0) {
+11 −171
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager;
import android.net.NetworkConnectivityListener;
import android.net.NetworkInfo;
import android.net.NetworkInfo;
import android.net.Proxy;
import android.net.Proxy;
import android.net.WebAddress;
import android.net.WebAddress;
@@ -50,150 +49,21 @@ import org.apache.http.HttpHost;
 */
 */
public class RequestQueue implements RequestFeeder {
public class RequestQueue implements RequestFeeder {


    private Context mContext;


    /**
    /**
     * Requests, indexed by HttpHost (scheme, host, port)
     * Requests, indexed by HttpHost (scheme, host, port)
     */
     */
    private LinkedHashMap<HttpHost, LinkedList<Request>> mPending;
    private final LinkedHashMap<HttpHost, LinkedList<Request>> mPending;

    private final Context mContext;
    /** true if connected */
    private final ActivePool mActivePool;
    boolean mNetworkConnected = true;
    private final ConnectivityManager mConnectivityManager;


    private HttpHost mProxyHost = null;
    private HttpHost mProxyHost = null;
    private BroadcastReceiver mProxyChangeReceiver;
    private BroadcastReceiver mProxyChangeReceiver;


    private ActivePool mActivePool;

    /* default simultaneous connection count */
    /* default simultaneous connection count */
    private static final int CONNECTION_COUNT = 4;
    private static final int CONNECTION_COUNT = 4;


    /**
     * This intent broadcast when http is paused or unpaused due to
     * net availability toggling
     */
    public final static String HTTP_NETWORK_STATE_CHANGED_INTENT =
            "android.net.http.NETWORK_STATE";
    public final static String HTTP_NETWORK_STATE_UP = "up";

    /**
     * Listen to platform network state.  On a change,
     * (1) kick stack on or off as appropriate
     * (2) send an intent to my host app telling
     *     it what I've done
     */
    private NetworkStateTracker mNetworkStateTracker;
    class NetworkStateTracker {

        final static int EVENT_DATA_STATE_CHANGED = 100;

        Context mContext;
        NetworkConnectivityListener mConnectivityListener;
        NetworkInfo.State mLastNetworkState = NetworkInfo.State.CONNECTED;
        int mCurrentNetworkType;

        NetworkStateTracker(Context context) {
            mContext = context;
        }

        /**
         * register for updates
         */
        protected void enable() {
            if (mConnectivityListener == null) {
                /*
                 * Initializing the network type is really unnecessary,
                 * since as soon as we register with the NCL, we'll
                 * get a CONNECTED event for the active network, and
                 * we'll configure the HTTP proxy accordingly. However,
                 * as a fallback in case that doesn't happen for some
                 * reason, initializing to type WIFI would mean that
                 * we'd start out without a proxy. This seems better
                 * than thinking we have a proxy (which is probably
                 * private to the carrier network and therefore
                 * unreachable outside of that network) when we really
                 * shouldn't.
                 */
                mCurrentNetworkType = ConnectivityManager.TYPE_WIFI;
                mConnectivityListener = new NetworkConnectivityListener();
                mConnectivityListener.registerHandler(mHandler, EVENT_DATA_STATE_CHANGED);
                mConnectivityListener.startListening(mContext);
            }
        }

        protected void disable() {
            if (mConnectivityListener != null) {
                mConnectivityListener.unregisterHandler(mHandler);
                mConnectivityListener.stopListening();
                mConnectivityListener = null;
            }
        }

        private Handler mHandler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case EVENT_DATA_STATE_CHANGED:
                        networkStateChanged();
                        break;
                }
            }
        };

        int getCurrentNetworkType() {
            return mCurrentNetworkType;
        }

        void networkStateChanged() {
            if (mConnectivityListener == null)
                return;

            
            NetworkConnectivityListener.State connectivityState = mConnectivityListener.getState();
            NetworkInfo info = mConnectivityListener.getNetworkInfo();
            if (info == null) {
                /**
                 * We've been seeing occasional NPEs here. I believe recent changes
                 * have made this impossible, but in the interest of being totally
                 * paranoid, check and log this here.
                 */
                HttpLog.v("NetworkStateTracker: connectivity broadcast"
                    + " has null network info - ignoring");
                return;
            }
            NetworkInfo.State state = info.getState();

            if (HttpLog.LOGV) {
                HttpLog.v("NetworkStateTracker " + info.getTypeName() +
                " state= " + state + " last= " + mLastNetworkState +
                " connectivityState= " + connectivityState.toString());
            }

            boolean newConnection =
                state != mLastNetworkState && state == NetworkInfo.State.CONNECTED;

            if (state == NetworkInfo.State.CONNECTED) {
                mCurrentNetworkType = info.getType();
                setProxyConfig();
            }

            mLastNetworkState = state;
            if (connectivityState == NetworkConnectivityListener.State.NOT_CONNECTED) {
                setNetworkState(false);
                broadcastState(false);
            } else if (newConnection) {
                setNetworkState(true);
                broadcastState(true);
            }

        }

        void broadcastState(boolean connected) {
            Intent intent = new Intent(HTTP_NETWORK_STATE_CHANGED_INTENT);
            intent.putExtra(HTTP_NETWORK_STATE_UP, connected);
            mContext.sendBroadcast(intent);
        }
    }

    /**
    /**
     * This class maintains active connection threads
     * This class maintains active connection threads
     */
     */
@@ -230,10 +100,6 @@ public class RequestQueue implements RequestFeeder {
            }
            }
        }
        }


        public boolean isNetworkConnected() {
            return mNetworkConnected;
        }

        void startConnectionThread() {
        void startConnectionThread() {
            synchronized (RequestQueue.this) {
            synchronized (RequestQueue.this) {
                RequestQueue.this.notify();
                RequestQueue.this.notify();
@@ -349,6 +215,9 @@ public class RequestQueue implements RequestFeeder {


        mActivePool = new ActivePool(connectionCount);
        mActivePool = new ActivePool(connectionCount);
        mActivePool.startup();
        mActivePool.startup();

        mConnectivityManager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
    }
    }


    /**
    /**
@@ -368,18 +237,6 @@ public class RequestQueue implements RequestFeeder {
            mContext.registerReceiver(mProxyChangeReceiver,
            mContext.registerReceiver(mProxyChangeReceiver,
                                      new IntentFilter(Proxy.PROXY_CHANGE_ACTION));
                                      new IntentFilter(Proxy.PROXY_CHANGE_ACTION));
        }
        }

        /* Network state notification is broken on the simulator
           don't register for notifications on SIM */
        String device = SystemProperties.get("ro.product.device");
        boolean simulation = TextUtils.isEmpty(device);

        if (!simulation) {
            if (mNetworkStateTracker == null) {
                mNetworkStateTracker = new NetworkStateTracker(mContext);
            }
            mNetworkStateTracker.enable();
        }
    }
    }


    /**
    /**
@@ -389,10 +246,6 @@ public class RequestQueue implements RequestFeeder {
    public synchronized void disablePlatformNotifications() {
    public synchronized void disablePlatformNotifications() {
        if (HttpLog.LOGV) HttpLog.v("RequestQueue.disablePlatformNotifications() network");
        if (HttpLog.LOGV) HttpLog.v("RequestQueue.disablePlatformNotifications() network");


        if (mNetworkStateTracker != null) {
            mNetworkStateTracker.disable();
        }

        if (mProxyChangeReceiver != null) {
        if (mProxyChangeReceiver != null) {
            mContext.unregisterReceiver(mProxyChangeReceiver);
            mContext.unregisterReceiver(mProxyChangeReceiver);
            mProxyChangeReceiver = null;
            mProxyChangeReceiver = null;
@@ -404,7 +257,8 @@ public class RequestQueue implements RequestFeeder {
     * synchronize setting the proxy
     * synchronize setting the proxy
     */
     */
    private synchronized void setProxyConfig() {
    private synchronized void setProxyConfig() {
        if (mNetworkStateTracker.getCurrentNetworkType() == ConnectivityManager.TYPE_WIFI) {
        NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
        if (info != null && info.getType() == ConnectivityManager.TYPE_WIFI) {
            mProxyHost = null;
            mProxyHost = null;
        } else {
        } else {
            String host = Proxy.getHost(mContext);
            String host = Proxy.getHost(mContext);
@@ -488,19 +342,6 @@ public class RequestQueue implements RequestFeeder {
                req);
                req);
    }
    }


    /**
     * Called by the NetworkStateTracker -- updates when network connectivity
     * is lost/restored.
     *
     * If isNetworkConnected is true, start processing requests
     */
    public void setNetworkState(boolean isNetworkConnected) {
        if (HttpLog.LOGV) HttpLog.v("RequestQueue.setNetworkState() " + isNetworkConnected);
        mNetworkConnected = isNetworkConnected;
        if (isNetworkConnected)
            mActivePool.startConnectionThread();
    }

    /**
    /**
     * @return true iff there are any non-active requests pending
     * @return true iff there are any non-active requests pending
     */
     */
@@ -546,7 +387,7 @@ public class RequestQueue implements RequestFeeder {
    public synchronized Request getRequest() {
    public synchronized Request getRequest() {
        Request ret = null;
        Request ret = null;


        if (mNetworkConnected && !mPending.isEmpty()) {
        if (!mPending.isEmpty()) {
            ret = removeFirst(mPending);
            ret = removeFirst(mPending);
        }
        }
        if (HttpLog.LOGV) HttpLog.v("RequestQueue.getRequest() => " + ret);
        if (HttpLog.LOGV) HttpLog.v("RequestQueue.getRequest() => " + ret);
@@ -559,7 +400,7 @@ public class RequestQueue implements RequestFeeder {
    public synchronized Request getRequest(HttpHost host) {
    public synchronized Request getRequest(HttpHost host) {
        Request ret = null;
        Request ret = null;


        if (mNetworkConnected && mPending.containsKey(host)) {
        if (mPending.containsKey(host)) {
            LinkedList<Request> reqList = mPending.get(host);
            LinkedList<Request> reqList = mPending.get(host);
            ret = reqList.removeFirst();
            ret = reqList.removeFirst();
            if (reqList.isEmpty()) {
            if (reqList.isEmpty()) {
@@ -635,7 +476,6 @@ public class RequestQueue implements RequestFeeder {
     * This interface is exposed to each connection
     * This interface is exposed to each connection
     */
     */
    interface ConnectionManager {
    interface ConnectionManager {
        boolean isNetworkConnected();
        HttpHost getProxyHost();
        HttpHost getProxyHost();
        Connection getConnection(Context context, HttpHost host);
        Connection getConnection(Context context, HttpHost host);
        boolean recycleConnection(HttpHost host, Connection connection);
        boolean recycleConnection(HttpHost host, Connection connection);