Commit 845daaaf authored by Clark DuVall's avatar Clark DuVall Committed by Chromium LUCI CQ

[WebLayer] Compile dex if necessary to avoid OMR1 bug

This is a simplified version of the fix for Chrome in crbug.com/1159608.
This is not as big of an issue in WebLayer because it looks like the bug
doesn't apply if the framework detects the split is used by another app
(which should be the case in WebLayer). We still want the fix just in
case, since there are still some situations we can get invalid dex, for
example if a user opens a WebView app (not WebLayer), then bg-dexopt
runs.

Bug: 1105096
Change-Id: I72d105fd7de0a9a32331d1b394dec05f4bc35b0c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2623118Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842542}
parent 19832f5f
...@@ -29,6 +29,8 @@ import android.webkit.WebViewFactory; ...@@ -29,6 +29,8 @@ import android.webkit.WebViewFactory;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import dalvik.system.DexFile;
import org.chromium.base.BuildInfo; import org.chromium.base.BuildInfo;
import org.chromium.base.BundleUtils; import org.chromium.base.BundleUtils;
import org.chromium.base.CommandLine; import org.chromium.base.CommandLine;
...@@ -42,10 +44,13 @@ import org.chromium.base.TraceEvent; ...@@ -42,10 +44,13 @@ import org.chromium.base.TraceEvent;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.compat.ApiHelperForO;
import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.NativeLibraryPreloader; import org.chromium.base.library_loader.NativeLibraryPreloader;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.PostTask;
import org.chromium.base.task.TaskTraits;
import org.chromium.components.browser_ui.contacts_picker.ContactsPickerDialog; import org.chromium.components.browser_ui.contacts_picker.ContactsPickerDialog;
import org.chromium.components.browser_ui.photo_picker.DecoderServiceHost; import org.chromium.components.browser_ui.photo_picker.DecoderServiceHost;
import org.chromium.components.browser_ui.photo_picker.ImageDecoder; import org.chromium.components.browser_ui.photo_picker.ImageDecoder;
...@@ -88,6 +93,7 @@ import org.chromium.weblayer_private.metrics.UmaUtils; ...@@ -88,6 +93,7 @@ import org.chromium.weblayer_private.metrics.UmaUtils;
import org.chromium.weblayer_private.settings.SettingsFragmentImpl; import org.chromium.weblayer_private.settings.SettingsFragmentImpl;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -317,6 +323,8 @@ public final class WebLayerImpl extends IWebLayer.Stub { ...@@ -317,6 +323,8 @@ public final class WebLayerImpl extends IWebLayer.Stub {
} }
}); });
performDexFixIfNecessary(packageInfo);
TraceEvent.end("WebLayer init"); TraceEvent.end("WebLayer init");
} }
...@@ -916,6 +924,40 @@ public final class WebLayerImpl extends IWebLayer.Stub { ...@@ -916,6 +924,40 @@ public final class WebLayerImpl extends IWebLayer.Stub {
return getClientApplicationName(); return getClientApplicationName();
} }
/*
* Android O MR1 has a bug where bg-dexopt-job will break optimized dex files for isolated
* splits. This leads to *very* slow startup on those devices. To mitigate this, we attempt
* to force a dex compile if necessary.
*/
private static void performDexFixIfNecessary(PackageInfo packageInfo) {
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
return;
}
PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> {
ApplicationInfo appInfo = packageInfo.applicationInfo;
String[] splitNames = ApiHelperForO.getSplitNames(appInfo);
for (int i = 0; i < splitNames.length; i++) {
String splitName = splitNames[i];
// WebLayer depends on the "weblayer" split and "chrome" split (if running in
// Monochrome).
if (!splitName.equals("chrome") && !splitName.equals("weblayer")) {
continue;
}
String splitDir = appInfo.splitSourceDirs[i];
try {
if (DexFile.isDexOptNeeded(splitDir)) {
String cmd = String.format("cmd package compile -r shared --split %s %s",
new File(splitDir).getName(), packageInfo.packageName);
Runtime.getRuntime().exec(cmd);
}
} catch (IOException e) {
Log.e(TAG, "Error fixing dex files.", e);
}
}
});
}
@NativeMethods @NativeMethods
interface Natives { interface Natives {
void setRemoteDebuggingEnabled(boolean enabled); void setRemoteDebuggingEnabled(boolean enabled);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment