Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for app bundle #26

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions java/com/facebook/soloader/ApkSoSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ public class ApkSoSource extends ExtractFromZipSoSource {

private final int mFlags;

public ApkSoSource(Context context, String name, int flags) {
public ApkSoSource(Context context, String apkPath, String name, int flags) {
super(
context,
name,
new File(context.getApplicationInfo().sourceDir),
new File(apkPath),
// The regular expression matches libraries that would ordinarily be unpacked
// during installation.
"^lib/([^/]+)/([^/]+\\.so)$");
Expand Down
47 changes: 36 additions & 11 deletions java/com/facebook/soloader/SoLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ public class SoLoader {

private static int sSoSourcesVersion = 0;

/** A backup SoSource to try if a lib file is corrupted */
/** A backup SoSources to try if a lib file is corrupted */
@GuardedBy("sSoSourcesLock")
@Nullable
private static UnpackingSoSource sBackupSoSource;
private static UnpackingSoSource[] sBackupSoSources;

/**
* A SoSource for the Context.ApplicationInfo.nativeLibsDir that can be updated if the application
Expand All @@ -121,9 +121,12 @@ public class SoLoader {
/** Wrapper for System.loadLlibrary. */
@Nullable private static SystemLoadLibraryWrapper sSystemLoadLibraryWrapper = null;

/** Name of the directory we use for extracted DSOs from built-in SO sources (APK, exopackage) */
/** Name of the directory we use for extracted DSOs from built-in SO sources (main APK, exopackage) */
private static final String SO_STORE_NAME_MAIN = "lib-main";

/** Name of the directory we use for extracted DSOs from splitted apks */
private static final String SO_STORE_NAME_SPLITTED = "lib-";

/** Enable the exopackage SoSource. */
public static final int SOLOADER_ENABLE_EXOPACKAGE = (1 << 0);

Expand Down Expand Up @@ -230,7 +233,7 @@ private static void initSoSources(Context context, int flags, @Nullable SoFileLo
//

if ((flags & SOLOADER_ENABLE_EXOPACKAGE) != 0) {
sBackupSoSource = null;
sBackupSoSources = null;
Log.d(TAG, "adding exo package source: " + SO_STORE_NAME_MAIN);
soSources.add(0, new ExoSoSource(context, SO_STORE_NAME_MAIN));
} else {
Expand Down Expand Up @@ -260,11 +263,27 @@ private static void initSoSources(Context context, int flags, @Nullable SoFileLo
}

if ((sFlags & SOLOADER_DISABLE_BACKUP_SOSOURCE) != 0) {
sBackupSoSource = null;
sBackupSoSources = null;
} else {
sBackupSoSource = new ApkSoSource(context, SO_STORE_NAME_MAIN, apkSoSourceFlags);
Log.d(TAG, "adding backup source: " + sBackupSoSource.toString());
soSources.add(0, sBackupSoSource);

String mainApkDir = context.getApplicationInfo().sourceDir;
ArrayList<UnpackingSoSource> backupSources = new ArrayList<>();
ApkSoSource mainApkSource = new ApkSoSource(context, mainApkDir, SO_STORE_NAME_MAIN, apkSoSourceFlags);
backupSources.add(mainApkSource);
Log.d(TAG, "adding backup source from : " + mainApkSource.toString());

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && context.getApplicationInfo().splitSourceDirs != null) {
Log.d(TAG, "adding backup sources from split apks");
int splitIndex = 0;
for (String splitApkDir : context.getApplicationInfo().splitSourceDirs) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

splitSourceDirs may be null in some cases so I suggest to add a necessary check here.
So does aosp in its sources. e.g https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/LoadedApk.java#L955

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Fixed

ApkSoSource splittedApkSource = new ApkSoSource(context, splitApkDir, SO_STORE_NAME_SPLITTED + (splitIndex++), apkSoSourceFlags);
Log.d(TAG, "adding backup source: " + splittedApkSource.toString());
backupSources.add(splittedApkSource);
}
}

sBackupSoSources = backupSources.toArray(new UnpackingSoSource[backupSources.size()]);
soSources.addAll(0, backupSources);
}
}
}
Expand Down Expand Up @@ -647,11 +666,17 @@ private static void doLoadLibraryBySoName(
for (int i = 0; result == SoSource.LOAD_RESULT_NOT_FOUND && i < sSoSources.length; ++i) {
SoSource currentSource = sSoSources[i];
result = currentSource.loadLibrary(soName, loadFlags, oldPolicy);
if (result == SoSource.LOAD_RESULT_CORRUPTED_LIB_FILE && sBackupSoSource != null) {
if (result == SoSource.LOAD_RESULT_CORRUPTED_LIB_FILE && sBackupSoSources != null) {
// Let's try from the backup source
Log.d(TAG, "Trying backup SoSource for " + soName);
sBackupSoSource.prepare(soName);
result = sBackupSoSource.loadLibrary(soName, loadFlags, oldPolicy);
for (UnpackingSoSource backupSoSource: sBackupSoSources) {
backupSoSource.prepare(soName);
int resultFromBackup = backupSoSource.loadLibrary(soName, loadFlags, oldPolicy);
if (resultFromBackup == SoSource.LOAD_RESULT_LOADED) {
result = resultFromBackup;
break;
}
}
break;
}
}
Expand Down