Merge "Delay instantiation of PacProcessor until unlocked" am: f1d0976115 am: d64e6a1802

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1853047

Change-Id: I59186992c04ef51507036a656b71dc9514e20ed7
This commit is contained in:
Pavel Grafov
2021-10-13 16:31:32 +00:00
committed by Automerger Merge Worker

View File

@@ -21,6 +21,7 @@ import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.Process; import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserManager;
import android.util.Log; import android.util.Log;
import android.webkit.PacProcessor; import android.webkit.PacProcessor;
@@ -33,16 +34,44 @@ import java.net.URL;
public class PacService extends Service { public class PacService extends Service {
private static final String TAG = "PacService"; 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") @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(); private ProxyServiceStub mStub = new ProxyServiceStub();
@Override @Override
public void onCreate() { public void onCreate() {
super.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 @Override
@@ -74,7 +103,20 @@ public class PacService extends Service {
} }
synchronized (mLock) { 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) { } catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid URL was passed"); throw new IllegalArgumentException("Invalid URL was passed");
@@ -88,8 +130,13 @@ public class PacService extends Service {
throw new SecurityException(); throw new SecurityException();
} }
synchronized (mLock) { synchronized (mLock) {
if (!mPacProcessor.setProxyScript(script)) { if (checkPacProcessorLocked()) {
Log.e(TAG, "Unable to parse proxy script."); 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;
} }
} }
} }