Skip to content

Commit

Permalink
Ensure that apps used during the boot process are compiled
Browse files Browse the repository at this point in the history
Android has (at least) five points in time where apps are compiled:
  1) Quite early when the PackageManagerService is started.
  2) Once the UI comes up ("Android is upgrading" screen).
  3) In a background service called "BackgroundDexOptService".
  4) When an app is installed.
  5) When the app is actually started.

Phase 1) is used for /system/framework and other non-app "libraries".
At this time, the system also scans the app directories and identifies
apps that need to be (re-)compiled. These apps are then handled in
phase 2). After that, all apps are usually compiled, with the exception
of builds with type "eng", where only recently used apps are compiled
immediately and the remaining ones are compiled in phases 3) or 5).
Phase 5) is usually not needed because the app has been compiled in one
of the previous phases.

Unfortunately, there is at least one category of apps that is needed
early during the boot process, the System Content Providers. They're
loaded between phase 1) and 2), but aren't compiled at that time yet,
which leads to errors. Actually that's not completely true: On most ROMs,
side-effects of other early package processing seem to compile them.
But even if not, phase 5) kicks in and should compile the app.

However, that doesn't work correctly. The phase assumes that it's only
needed for "eng" builds, when not all apps have been compiled in phase 2).
It quits early if it doesn't detect such a situation.

This patch hooks into the methods that triggers the compilation of the app
and pretends that the call came from phase 3) if it detects that phase 2)
hasn't run yet. This ensures that the System Content Providers are
compiled shortly before they're required.

Not sure why this doesn't seem to occur without Xposed - maybe the
circumstances are slightly different.

Fixes rovo89/Xposed#53.
  • Loading branch information
rovo89 committed Aug 16, 2015
1 parent a96971a commit 01c3244
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/de/robv/android/xposed/XposedBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,16 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
lpparam.appInfo = null;
lpparam.isFirstApplication = true;
XC_LoadPackage.callAll(lpparam);

// Force dex2oat while the system is still booting to ensure that system content providers work.
findAndHookMethod("com.android.server.pm.PackageManagerService", cl, "performDexOpt",
String.class, String.class, boolean.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (getObjectField(param.thisObject, "mDeferredDexOpt") != null)
param.args[2] = true;
}
});
}
});
}
Expand Down

0 comments on commit 01c3244

Please sign in to comment.