Skip to content
Snippets Groups Projects
Commit 3f0400e2 authored by Pavel Grafov's avatar Pavel Grafov
Browse files

Delay instantiation of PacProcessor until unlocked

Webkit PAC processor cannot be created before the user is unlocked,
this is currently causing crashes during boot.
With this CL PacProcessor instantiation is delayed and will happen
only when the user is unlocked either when handling a request or
when PAC script is set.

Instantiation of PacProcessor can take substantial time, on order
of a second.

Bug: 200241231
Test: manual, set PAC proxy and reboot
Change-Id: Id42d857289a0b0f7df5b1c48f94d1b363d94235e
parent ae99d9ba
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,7 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.Log;
import android.webkit.PacProcessor;
......@@ -33,16 +34,44 @@ import java.net.URL;
public class PacService extends Service {
private static final String TAG = "PacService";
private Object mLock = new Object();
private final Object mLock = new Object();
// Webkit PacProcessor cannot be instantiated before the user is unlocked, so this field is
// initialized lazily.
@GuardedBy("mLock")
private final PacProcessor mPacProcessor = PacProcessor.getInstance();
private PacProcessor mPacProcessor;
// Stores PAC script when setPacFile is called before mPacProcessor is available. In case the
// script was already fed to the PacProcessor, it should be null.
@GuardedBy("mLock")
private String mPendingScript;
private ProxyServiceStub mStub = new ProxyServiceStub();
@Override
public void onCreate() {
super.onCreate();
synchronized (mLock) {
checkPacProcessorLocked();
}
}
/**
* Initializes PacProcessor if it hasn't been initialized yet and if the system user is
* unlocked, e.g. after the user has entered their PIN after a reboot.
* Returns whether PacProcessor is available.
*/
private boolean checkPacProcessorLocked() {
if (mPacProcessor != null) {
return true;
}
UserManager um = getSystemService(UserManager.class);
if (um.isUserUnlocked()) {
mPacProcessor = PacProcessor.getInstance();
return true;
}
return false;
}
@Override
......@@ -74,7 +103,20 @@ public class PacService extends Service {
}
synchronized (mLock) {
return mPacProcessor.findProxyForUrl(url);
if (checkPacProcessorLocked()) {
// Apply pending script in case it was set before processor was ready.
if (mPendingScript != null) {
if (!mPacProcessor.setProxyScript(mPendingScript)) {
Log.e(TAG, "Unable to parse proxy script.");
}
mPendingScript = null;
}
return mPacProcessor.findProxyForUrl(url);
} else {
Log.e(TAG, "PacProcessor isn't ready during early boot,"
+ " request will be direct");
return null;
}
}
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid URL was passed");
......@@ -88,8 +130,13 @@ public class PacService extends Service {
throw new SecurityException();
}
synchronized (mLock) {
if (!mPacProcessor.setProxyScript(script)) {
Log.e(TAG, "Unable to parse proxy script.");
if (checkPacProcessorLocked()) {
if (!mPacProcessor.setProxyScript(script)) {
Log.e(TAG, "Unable to parse proxy script.");
}
} else {
Log.d(TAG, "PAC processor isn't ready, saving script for later.");
mPendingScript = script;
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment