| Index: net/android/java/src/org/chromium/net/ProxyChangeListener.java | 
| diff --git a/net/android/java/src/org/chromium/net/ProxyChangeListener.java b/net/android/java/src/org/chromium/net/ProxyChangeListener.java | 
| index 1ccf7a597247dfef1e7c1e5daadbdeef7253f39e..503e2eaeb996a0c8459f10830a11f015c88a38f2 100644 | 
| --- a/net/android/java/src/org/chromium/net/ProxyChangeListener.java | 
| +++ b/net/android/java/src/org/chromium/net/ProxyChangeListener.java | 
| @@ -11,9 +11,12 @@ import android.content.IntentFilter; | 
| import android.net.Proxy; | 
| import android.net.Uri; | 
| import android.os.Build; | 
| +import android.os.Handler; | 
| +import android.os.Looper; | 
| import android.text.TextUtils; | 
| import android.util.Log; | 
|  | 
| +import org.chromium.base.BuildConfig; | 
| import org.chromium.base.ContextUtils; | 
| import org.chromium.base.annotations.CalledByNative; | 
| import org.chromium.base.annotations.JNINamespace; | 
| @@ -31,6 +34,9 @@ public class ProxyChangeListener { | 
| private static final String TAG = "ProxyChangeListener"; | 
| private static boolean sEnabled = true; | 
|  | 
| +    private final Looper mLooper; | 
| +    private final Handler mHandler; | 
| + | 
| private long mNativePtr; | 
| private ProxyReceiver mProxyReceiver; | 
| private Delegate mDelegate; | 
| @@ -55,7 +61,10 @@ public class ProxyChangeListener { | 
| public void proxySettingsChanged(); | 
| } | 
|  | 
| -    private ProxyChangeListener() {} | 
| +    private ProxyChangeListener() { | 
| +        mLooper = Looper.myLooper(); | 
| +        mHandler = new Handler(mLooper); | 
| +    } | 
|  | 
| public static void setEnabled(boolean enabled) { | 
| sEnabled = enabled; | 
| @@ -77,6 +86,7 @@ public class ProxyChangeListener { | 
|  | 
| @CalledByNative | 
| public void start(long nativePtr) { | 
| +        assertOnThread(); | 
| assert mNativePtr == 0; | 
| mNativePtr = nativePtr; | 
| registerReceiver(); | 
| @@ -84,15 +94,21 @@ public class ProxyChangeListener { | 
|  | 
| @CalledByNative | 
| public void stop() { | 
| +        assertOnThread(); | 
| mNativePtr = 0; | 
| unregisterReceiver(); | 
| } | 
|  | 
| private class ProxyReceiver extends BroadcastReceiver { | 
| @Override | 
| -        public void onReceive(Context context, Intent intent) { | 
| +        public void onReceive(Context context, final Intent intent) { | 
| if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { | 
| -                proxySettingsChanged(extractNewProxy(intent)); | 
| +                runOnThread(new Runnable() { | 
| +                    @Override | 
| +                    public void run() { | 
| +                        proxySettingsChanged(ProxyReceiver.this, extractNewProxy(intent)); | 
| +                    } | 
| +                }); | 
| } | 
| } | 
|  | 
| @@ -173,8 +189,12 @@ public class ProxyChangeListener { | 
| } | 
| } | 
|  | 
| -    private void proxySettingsChanged(ProxyConfig cfg) { | 
| -        if (!sEnabled) { | 
| +    private void proxySettingsChanged(ProxyReceiver proxyReceiver, ProxyConfig cfg) { | 
| +        if (!sEnabled | 
| +                // Once execution begins on the correct thread, make sure unregisterReceiver() | 
| +                // hasn't been called in the mean time. Ignore the changed signal if | 
| +                // unregisterReceiver() was called. | 
| +                || proxyReceiver != mProxyReceiver) { | 
| return; | 
| } | 
| if (mDelegate != null) { | 
| @@ -211,6 +231,24 @@ public class ProxyChangeListener { | 
| mProxyReceiver = null; | 
| } | 
|  | 
| +    private boolean onThread() { | 
| +        return mLooper == Looper.myLooper(); | 
| +    } | 
| + | 
| +    private void assertOnThread() { | 
| +        if (BuildConfig.DCHECK_IS_ON && !onThread()) { | 
| +            throw new IllegalStateException("Must be called on ProxyChangeListener thread."); | 
| +        } | 
| +    } | 
| + | 
| +    private void runOnThread(Runnable r) { | 
| +        if (onThread()) { | 
| +            r.run(); | 
| +        } else { | 
| +            mHandler.post(r); | 
| +        } | 
| +    } | 
| + | 
| /** | 
| * See net/proxy/proxy_config_service_android.cc | 
| */ | 
|  |