From c998deb9376eea9289d81ac03b41e01722c8a761 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 5 Aug 2016 15:25:03 -0700 Subject: DO NOT MERGE: Clean up when recycling a pid with a pending launch Fix for accidental launch of a broadcast receiver in an incorrect app instance. Bug: 30202481 Change-Id: I8ec8f19c633f3aec8da084dab5fd5b312443336f (cherry picked from commit d1eeb5b7b489d47994a71510f1ed5b97b8e32a7a) --- .../android/server/am/ActivityManagerService.java | 21 +++++++++++++++++---- .../java/com/android/server/am/BroadcastQueue.java | 5 +++++ 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 50d74a2..701cb84 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3425,6 +3425,15 @@ public final class ActivityManagerService extends ActivityManagerNative app.killedByAm = false; checkTime(startTime, "startProcess: starting to update pids map"); synchronized (mPidsSelfLocked) { + ProcessRecord oldApp; + // If there is already an app occupying that pid that hasn't been cleaned up + if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) { + // Clean up anything relating to this pid first + Slog.w(TAG, "Reusing pid " + startResult.pid + + " while app is still mapped to it"); + cleanUpApplicationRecordLocked(oldApp, false, false, -1, + true /*replacingPid*/); + } this.mPidsSelfLocked.put(startResult.pid, app); if (isActivityProcess) { Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); @@ -4565,7 +4574,8 @@ public final class ActivityManagerService extends ActivityManagerNative private final void handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart) { int pid = app.pid; - boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); + boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1, + false /*replacingPid*/); if (!kept && !restarting) { removeLruProcessLocked(app); if (pid > 0) { @@ -15507,7 +15517,8 @@ public final class ActivityManagerService extends ActivityManagerNative * app that was passed in must remain on the process lists. */ private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, - boolean restarting, boolean allowRestart, int index) { + boolean restarting, boolean allowRestart, int index, boolean replacingPid) { + Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid); if (index >= 0) { removeLruProcessLocked(app); ProcessList.remove(app.pid); @@ -15637,7 +15648,9 @@ public final class ActivityManagerService extends ActivityManagerNative if (!app.persistent || app.isolated) { if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Removing non-persistent process during cleanup: " + app); - removeProcessNameLocked(app.processName, app.uid); + if (!replacingPid) { + removeProcessNameLocked(app.processName, app.uid); + } if (mHeavyWeightProcess == app) { mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, mHeavyWeightProcess.userId, 0)); @@ -19489,7 +19502,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Ignore exceptions. } } - cleanUpApplicationRecordLocked(app, false, true, -1); + cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); mRemovedProcesses.remove(i); if (app.persistent) { diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 6de8579..089c33b 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -292,6 +292,11 @@ public final class BroadcastQueue { boolean didSomething = false; final BroadcastRecord br = mPendingBroadcast; if (br != null && br.curApp.pid == app.pid) { + if (br.curApp != app) { + Slog.e(TAG, "App mismatch when sending pending broadcast to " + + app.processName + ", intended target is " + br.curApp.processName); + return false; + } try { mPendingBroadcast = null; processCurBroadcastLocked(br, app); -- cgit v1.1 From 1d6c0efc202a21942321ffa3b83b7c9309e66c9a Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Wed, 10 Aug 2016 15:43:17 -0700 Subject: Fix vulnerability in LockSettings service Fixes bug 30003944 Change-Id: I8700d4424c6186c8d5e71d2fdede0223ad86904d (cherry picked from commit 2d71384a139ae27cbc7b57f06662bf6ee2010f2b) --- services/core/java/com/android/server/LockSettingsService.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'services') diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 55682c2..6cb2875 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -519,6 +519,9 @@ public class LockSettingsService extends ILockSettings.Stub { private VerifyCredentialResponse doVerifyPattern(String pattern, boolean hasChallenge, long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); + if (TextUtils.isEmpty(pattern)) { + throw new IllegalArgumentException("Pattern can't be null or empty"); + } CredentialHash storedHash = mStorage.readPatternHash(userId); boolean shouldReEnrollBaseZero = storedHash != null && storedHash.isBaseZeroPattern; @@ -575,6 +578,9 @@ public class LockSettingsService extends ILockSettings.Stub { private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge, long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); + if (TextUtils.isEmpty(password)) { + throw new IllegalArgumentException("Password can't be null or empty"); + } CredentialHash storedHash = mStorage.readPasswordHash(userId); return verifyCredential(userId, storedHash, password, hasChallenge, challenge, new CredentialUtil() { -- cgit v1.1 From ca692c228dfef0b0d7f51597e726180d3f70c66c Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Thu, 18 Aug 2016 20:22:33 -0700 Subject: Bind fingerprint when we start authentication - DO NOT MERGE This fixes a bug where it was possible to authenticate the wrong user. We now bind the userId when we start authentication and confirm it when authentication completes. Fixes bug 30744668 Change-Id: I346d92c301414ed81e11fa9c171584c7ae4341c2 (cherry picked from commit b6f4b48df273d210d13631b4c2426482feb40c97) --- .../server/fingerprint/FingerprintService.java | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index 103ed0a..84aa2d7 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -127,6 +127,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private IFingerprintDaemon mDaemon; private final PowerManager mPowerManager; private final AlarmManager mAlarmManager; + private int mCurrentUserId = UserHandle.USER_NULL; private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() { @Override @@ -337,7 +338,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return; } stopPendingOperations(true); - mEnrollClient = new ClientMonitor(token, receiver, groupId, restricted, token.toString()); + mEnrollClient = new ClientMonitor(token, receiver, mCurrentUserId, groupId, restricted, + token.toString()); final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC); try { final int result = daemon.enroll(cryptoToken, groupId, timeout); @@ -425,7 +427,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return; } stopPendingOperations(true); - mAuthClient = new ClientMonitor(token, receiver, groupId, restricted, opPackageName); + mAuthClient = new ClientMonitor(token, receiver, mCurrentUserId, groupId, restricted, + opPackageName); if (inLockoutMode()) { Slog.v(TAG, "In lockout mode; disallowing authentication"); if (!mAuthClient.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) { @@ -482,7 +485,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } stopPendingOperations(true); - mRemoveClient = new ClientMonitor(token, receiver, userId, restricted, token.toString()); + mRemoveClient = new ClientMonitor(token, receiver, mCurrentUserId, userId, restricted, + token.toString()); // The fingerprint template ids will be removed when we get confirmation from the HAL try { final int result = daemon.remove(fingerId, userId); @@ -605,15 +609,17 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private class ClientMonitor implements IBinder.DeathRecipient { IBinder token; IFingerprintServiceReceiver receiver; - int userId; + int userId; // userId of the caller + int currentUserId; // current user id when this was created boolean restricted; // True if client does not have MANAGE_FINGERPRINT permission String owner; - public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, int userId, - boolean restricted, String owner) { + public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, + int currentUserId, int userId, boolean restricted, String owner) { this.token = token; this.receiver = receiver; this.userId = userId; + this.currentUserId = currentUserId; this.restricted = restricted; this.owner = owner; // name of the client that owns this - for debugging try { @@ -702,9 +708,9 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe Slog.v(TAG, "onAuthenticated(owner=" + mAuthClient.owner + ", id=" + fpId + ", gp=" + groupId + ")"); } - Fingerprint fp = !restricted ? - new Fingerprint("" /* TODO */, groupId, fpId, mHalDeviceId) : null; - receiver.onAuthenticationSucceeded(mHalDeviceId, fp); + Fingerprint fp = !restricted ? new Fingerprint("" /* TODO */, groupId, fpId, + mHalDeviceId) : null; + receiver.onAuthenticationSucceeded(mHalDeviceId, fp, currentUserId); } } catch (RemoteException e) { Slog.w(TAG, "Failed to notify Authenticated:", e); @@ -1129,6 +1135,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe Slog.e(TAG, "Failed to setActiveGroup():", e); } } + mCurrentUserId = userId; } private void listenForUserSwitches() { -- cgit v1.1 From f1e317003659e9097f760a4b680dd595abed2e3e Mon Sep 17 00:00:00 2001 From: David Christie Date: Tue, 23 Aug 2016 16:19:51 -0700 Subject: DO NOT MERGE: Fix vulnerability where large GPS XTRA data can be injected. -Can potentially crash system with OOM. Bug: 29555864 Change-Id: I7157f48dddf148a9bcab029cf12e26a58d8054f4 (cherry picked from commit 5439aabb165b5a760d1e580016bf1d6fd963cb65) --- .../android/server/location/GpsXtraDownloader.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java index 3585049..6310361 100644 --- a/services/core/java/com/android/server/location/GpsXtraDownloader.java +++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java @@ -21,8 +21,11 @@ import android.util.Log; import java.net.HttpURLConnection; import java.net.URL; -import libcore.io.Streams; +import libcore.io.IoUtils; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.io.IOException; import java.util.Properties; import java.util.Random; @@ -36,6 +39,7 @@ public class GpsXtraDownloader { private static final String TAG = "GpsXtraDownloader"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000; // 1MB. private static final String DEFAULT_USER_AGENT = "Android"; private final String[] mXtraServers; @@ -121,7 +125,19 @@ public class GpsXtraDownloader { return null; } - return Streams.readFully(connection.getInputStream()); + try (InputStream in = connection.getInputStream()) { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int count; + while ((count = in.read(buffer)) != -1) { + bytes.write(buffer, 0, count); + if (bytes.size() > MAXIMUM_CONTENT_LENGTH_BYTES) { + if (DEBUG) Log.d(TAG, "XTRA file too large"); + return null; + } + } + return bytes.toByteArray(); + } } catch (IOException ioe) { if (DEBUG) Log.d(TAG, "Error downloading gps XTRA: ", ioe); } finally { @@ -133,3 +149,4 @@ public class GpsXtraDownloader { } } + -- cgit v1.1 From 115baf8f0fb54fa86db6afc489ab8413ff714e46 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 14 Sep 2016 14:37:14 -0700 Subject: DO NOT MERGE: Fix deadlock in AcitivityManagerService. Don't hold mPidsSelfLocked lock when calling cleanUpApplicationRecordLocked. Bug: 31463143 Change-Id: I421962cbfd7c466662edcef805c3e27321dc5a98 (cherry picked from commit b59e73613bbaf252e2ee5892d7a95cbbd7d40b26) --- .../android/server/am/ActivityManagerService.java | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 701cb84..16620cd 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3424,16 +3424,19 @@ public final class ActivityManagerService extends ActivityManagerNative app.killed = false; app.killedByAm = false; checkTime(startTime, "startProcess: starting to update pids map"); + ProcessRecord oldApp; + synchronized (mPidsSelfLocked) { + oldApp = mPidsSelfLocked.get(startResult.pid); + } + // If there is already an app occupying that pid that hasn't been cleaned up + if (oldApp != null && !app.isolated) { + // Clean up anything relating to this pid first + Slog.w(TAG, "Reusing pid " + startResult.pid + + " while app is still mapped to it"); + cleanUpApplicationRecordLocked(oldApp, false, false, -1, + true /*replacingPid*/); + } synchronized (mPidsSelfLocked) { - ProcessRecord oldApp; - // If there is already an app occupying that pid that hasn't been cleaned up - if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) { - // Clean up anything relating to this pid first - Slog.w(TAG, "Reusing pid " + startResult.pid - + " while app is still mapped to it"); - cleanUpApplicationRecordLocked(oldApp, false, false, -1, - true /*replacingPid*/); - } this.mPidsSelfLocked.put(startResult.pid, app); if (isActivityProcess) { Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); -- cgit v1.1 From 9e812be46b6f7be61524e14652ba380c02518262 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 16 Sep 2016 12:12:14 +0900 Subject: DO NOT MERGE: Catch all exceptions when parsing IME meta data Bug: 30568284 Change-Id: I0b613f8ce0f014320c5ac1bf445699ea2702a0a2 (manually cherry picked from 9b2997d22e6ce2a15065d8e7608dd77b316c2065) (cherry picked from commit 7bb4c825585d5a6afbb59484ec7db5f5dec1bdaf) --- .../core/java/com/android/server/InputMethodManagerService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 6d07a57..f2058a5 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -2949,10 +2949,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Slog.d(TAG, "Found an input method " + p); } - } catch (XmlPullParserException e) { - Slog.w(TAG, "Unable to load input method " + compName, e); - } catch (IOException e) { - Slog.w(TAG, "Unable to load input method " + compName, e); + } catch (Exception e) { + Slog.wtf(TAG, "Unable to load input method " + compName, e); } } -- cgit v1.1 From 4f0dec2e62ee47dec1e29a6c97e13af2c86a33e9 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Mon, 19 Sep 2016 08:53:20 -0400 Subject: Fix build break due to automerge of 7d2198b5 Bug: 30100884 Change-Id: I8fa379a74b5d9467b5b9498bd18de2a043963c6f (cherry picked from commit baae57ab24db7d3b0bf7f84c05954173f1ee15fe) --- services/core/java/com/android/server/connectivity/PacManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'services') diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java index 7d1da01..fa6bac8 100644 --- a/services/core/java/com/android/server/connectivity/PacManager.java +++ b/services/core/java/com/android/server/connectivity/PacManager.java @@ -267,7 +267,7 @@ public class PacManager { intent.setClassName(PAC_PACKAGE, PAC_SERVICE); if ((mProxyConnection != null) && (mConnection != null)) { // Already bound no need to bind again, just download the new file. - IoThread.getHandler().post(mPacDownloader); + mNetThreadHandler.post(mPacDownloader); return; } mConnection = new ServiceConnection() { -- cgit v1.1 From 4c95059c31584cbd5651183a4605301563cf2e8e Mon Sep 17 00:00:00 2001 From: Jaewan Kim Date: Mon, 19 Sep 2016 21:19:55 +0900 Subject: DO NOT MERGE Check caller for sending media key to global priority session Prevent sending media key events from the non-system app to the global priority session through the MediaSessionManager.dispatchMediaKeyEvent(). Note that any app can use the API indirectly with the public API AudioManager.dispatchMediaKeyEvent(). Bug: 29833954 Tested: Installed malicious apps and confirmed that they don't work. Tested: Run CtsTelecomTestCases and CtsMediaTestCases Change-Id: I2a9e78196ba7455324e485f098f095d03b47ee15 (cherry picked from commit c282c4f106bea5c5375fdb6062ffd4fdcf8563a7) --- .../core/java/com/android/server/media/MediaSessionService.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'services') diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 7028fa6..22f9f72 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -47,6 +47,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -760,6 +761,13 @@ public class MediaSessionService extends SystemService implements Monitor { + "setup is in progress."); return; } + if (isGlobalPriorityActive() && uid != Process.SYSTEM_UID) { + // Prevent dispatching key event through reflection while the global priority + // session is active. + Slog.i(TAG, "Only the system can dispatch media key event " + + "to the global priority session."); + return; + } synchronized (mLock) { // If we don't have a media button receiver to fall back on -- cgit v1.1 From ef525e8d721a69310044eca14993df8b13ac1b14 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Mon, 19 Sep 2016 11:37:54 +0000 Subject: Avoid crashing when downloading MitM'd PAC that is too big am: 7d2198b586 am: 9c1cb7a273 am: 6634e90ad7 am: 66ee2296a9 Change-Id: Ib0023b44e521b936ab2f9450ad367b1feda64492 --- .../android/server/connectivity/PacManager.java | 34 +++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java index fa6bac8..58c76ec 100644 --- a/services/core/java/com/android/server/connectivity/PacManager.java +++ b/services/core/java/com/android/server/connectivity/PacManager.java @@ -27,6 +27,7 @@ import android.content.ServiceConnection; import android.net.ProxyInfo; import android.net.Uri; import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -39,10 +40,10 @@ import com.android.internal.annotations.GuardedBy; import com.android.net.IProxyCallback; import com.android.net.IProxyPortListener; import com.android.net.IProxyService; -import com.android.server.IoThread; import libcore.io.Streams; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; import java.net.URLConnection; @@ -66,6 +67,7 @@ public class PacManager { private static final int DELAY_1 = 0; private static final int DELAY_4 = 3; private static final int DELAY_LONG = 4; + private static final long MAX_PAC_SIZE = 20 * 1000 * 1000; /** Keep these values up-to-date with ProxyService.java */ public static final String KEY_PROXY = "keyProxy"; @@ -123,15 +125,21 @@ public class PacManager { } }; + private final HandlerThread mNetThread = new HandlerThread("android.pacmanager", + android.os.Process.THREAD_PRIORITY_DEFAULT); + private final Handler mNetThreadHandler; + class PacRefreshIntentReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { - IoThread.getHandler().post(mPacDownloader); + mNetThreadHandler.post(mPacDownloader); } } public PacManager(Context context, Handler handler, int proxyMessage) { mContext = context; mLastPort = -1; + mNetThread.start(); + mNetThreadHandler = new Handler(mNetThread.getLooper()); mPacRefreshIntent = PendingIntent.getBroadcast( context, 0, new Intent(ACTION_PAC_REFRESH), 0); @@ -199,7 +207,25 @@ public class PacManager { private static String get(Uri pacUri) throws IOException { URL url = new URL(pacUri.toString()); URLConnection urlConnection = url.openConnection(java.net.Proxy.NO_PROXY); - return new String(Streams.readFully(urlConnection.getInputStream())); + long contentLength = -1; + try { + contentLength = Long.parseLong(urlConnection.getHeaderField("Content-Length")); + } catch (NumberFormatException e) { + // Ignore + } + if (contentLength > MAX_PAC_SIZE) { + throw new IOException("PAC too big: " + contentLength + " bytes"); + } + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int count; + while ((count = urlConnection.getInputStream().read(buffer)) != -1) { + bytes.write(buffer, 0, count); + if (bytes.size() > MAX_PAC_SIZE) { + throw new IOException("PAC too big"); + } + } + return bytes.toString(); } private int getNextDelay(int currentDelay) { @@ -297,7 +323,7 @@ public class PacManager { } catch (RemoteException e) { Log.e(TAG, "Unable to reach ProxyService - PAC will not be started", e); } - IoThread.getHandler().post(mPacDownloader); + mNetThreadHandler.post(mPacDownloader); } } } -- cgit v1.1