Skip to content

Commit

Permalink
Rename ApkSoSource to BackupSoSource
Browse files Browse the repository at this point in the history
Summary: As in the title. Rename to better show its purpose. Also, add more documentation around it. Part of a larger effort to unify all ApkSoSources into one abstraction that's easier to handle.

Reviewed By: simpleton

Differential Revision: D50302416

fbshipit-source-id: d359a0c1500cd70a2da49cda9db6a33160fc0bf6
  • Loading branch information
adicatana authored and facebook-github-bot committed Oct 17, 2023
1 parent 7bd11f3 commit 6b32012
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@
import java.io.IOException;
import java.util.zip.ZipEntry;

/** {@link SoSource} that extracts libraries from an APK to the filesystem. */
public class ApkSoSource extends ExtractFromZipSoSource {
/**
* {@link SoSource} that extracts zipped libraries from an APK to the filesystem. This is a
* workaround for a known OS bug where the unpacking of non-asset zipped libraries at install time
* results in corrupted libraries (e.g. bad elf magic, or truncated files).
*/
public class BackupSoSource extends ExtractFromZipSoSource {

private static final String TAG = "ApkSoSource";
private static final String TAG = "BackupSoSource";

/**
* If this flag is given, do not extract libraries that appear to be correctly extracted to the
Expand All @@ -40,11 +44,11 @@ public class ApkSoSource extends ExtractFromZipSoSource {

private final int mFlags;

public ApkSoSource(Context context, String name, int flags) {
public BackupSoSource(Context context, String name, int flags) {
this(context, new File(context.getApplicationInfo().sourceDir), name, flags);
}

public ApkSoSource(Context context, File apkPath, String name, int flags) {
public BackupSoSource(Context context, File apkPath, String name, int flags) {
super(
context,
name,
Expand All @@ -57,7 +61,7 @@ public ApkSoSource(Context context, File apkPath, String name, int flags) {

@Override
public String getName() {
return "ApkSoSource";
return "BackupSoSource";
}

public boolean hasZippedLibs() throws IOException {
Expand All @@ -81,7 +85,7 @@ protected class ApkUnpacker extends ZipUnpacker {
super(soSource);
mForceUnpacking = forceUnpacking;
mLibDir = new File(mContext.getApplicationInfo().nativeLibraryDir);
mFlags = ApkSoSource.this.mFlags;
mFlags = BackupSoSource.this.mFlags;
}

@Override
Expand Down
18 changes: 9 additions & 9 deletions java/com/facebook/soloader/SoLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ private static void initSoSources(Context context, int flags) throws IOException
addDirectApkSoSource(context, soSources);
}
addApplicationSoSource(soSources, getApplicationSoSourceFlags());
addBackupSoSource(context, soSources, ApkSoSource.PREFER_ANDROID_LIBS_DIRECTORY);
addBackupSoSource(context, soSources, BackupSoSource.PREFER_ANDROID_LIBS_DIRECTORY);
}
}

Expand Down Expand Up @@ -440,7 +440,7 @@ private static void addApplicationSoSource(ArrayList<SoSource> soSources, int fl

/** Add the SoSources for recovering the dso if the file is corrupted or missed */
private static void addBackupSoSource(
Context context, ArrayList<SoSource> soSources, int apkSoSourceFlags) throws IOException {
Context context, ArrayList<SoSource> soSources, int backupSoSourceFlags) throws IOException {
if ((sFlags & SOLOADER_DISABLE_BACKUP_SOSOURCE) != 0) {
// Clean up backups
final File backupDir = UnpackingSoSource.getSoStorePath(context, SO_STORE_NAME_MAIN);
Expand All @@ -454,30 +454,30 @@ private static void addBackupSoSource(

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

addBackupSoSourceFromSplitApk(context, apkSoSourceFlags, backupSources);
addBackupSoSourceFromSplitApk(context, backupSoSourceFlags, backupSources);

soSources.addAll(0, backupSources);
}

private static void addBackupSoSourceFromSplitApk(
Context context, int apkSoSourceFlags, ArrayList<UnpackingSoSource> backupSources)
Context context, int backupSoSourceFlags, ArrayList<UnpackingSoSource> backupSources)
throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& context.getApplicationInfo().splitSourceDirs != null) {
LogUtil.d(TAG, "adding backup sources from split apks");
int splitIndex = 0;
for (String splitApkDir : context.getApplicationInfo().splitSourceDirs) {
ApkSoSource splitApkSource =
new ApkSoSource(
BackupSoSource splitApkSource =
new BackupSoSource(
context,
new File(splitApkDir),
SO_STORE_NAME_SPLIT + (splitIndex++),
apkSoSourceFlags);
backupSoSourceFlags);
LogUtil.d(TAG, "adding backup source: " + splitApkSource.toString());
if (splitApkSource.hasZippedLibs()) {
backupSources.add(splitApkSource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public RecoveryStrategy get() {
// explicit SimpleRetry.
new WaitForAsyncInit(),
new DetectDataAppMove(mContext, mBaseApkPathHistory),
new ReunpackApkSoSources(),
new ReunpackNonApkSoSources(),
new ReunpackBackupSoSources(),
new ReunpackNonBackupSoSources(),
new WaitForAsyncInit(),
new CheckBaseApkExists(mContext, mBaseApkPathHistory));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.facebook.soloader.recovery;

import com.facebook.soloader.ApkSoSource;
import com.facebook.soloader.BackupSoSource;
import com.facebook.soloader.LogUtil;
import com.facebook.soloader.SoLoader;
import com.facebook.soloader.SoLoaderDSONotFoundError;
Expand All @@ -25,12 +25,12 @@

/**
* RecoveryStrategy that detects cases when SoLoader failed to load a corrupted library, case in
* which we try to re-unpack the libraries. Only for ApkSoSources
* which we try to re-unpack the libraries. Only for BackupSoSources
*
* <p>Guards against a known Android OS bug where the installer incorrectly unpacks libraries under
* /data/app
*/
public class ReunpackApkSoSources implements RecoveryStrategy {
public class ReunpackBackupSoSources implements RecoveryStrategy {

@Override
public boolean recover(UnsatisfiedLinkError error, SoSource[] soSources) {
Expand All @@ -54,27 +54,27 @@ public boolean recover(UnsatisfiedLinkError error, SoSource[] soSources) {
String soName = err.getSoName();
LogUtil.e(
SoLoader.TAG,
"Reunpacking ApkSoSources due to "
"Reunpacking BackupSoSources due to "
+ error
+ ((soName == null) ? "" : (", retrying for specific library " + soName)));

for (SoSource soSource : soSources) {
if (!(soSource instanceof ApkSoSource)) {
// NonApk SoSources get reunpacked in ReunpackNonApkSoSource recovery strategy
if (!(soSource instanceof BackupSoSource)) {
// NonApk SoSources get reunpacked in ReunpackNonBackupSoSource recovery strategy
continue;
}
ApkSoSource apkSource = (ApkSoSource) soSource;
BackupSoSource backupSoSource = (BackupSoSource) soSource;
try {
LogUtil.e(SoLoader.TAG, "Runpacking ApkSoSource " + apkSource.getName());
apkSource.prepareForceRefresh();
LogUtil.e(SoLoader.TAG, "Runpacking BackupSoSource " + backupSoSource.getName());
backupSoSource.prepareForceRefresh();
} catch (Exception e) {
// Catch a general error and log it, rather than failing during recovery and crashing the
// app
// in a different way.
LogUtil.e(
SoLoader.TAG,
"Encountered an exception while reunpacking ApkSoSource "
+ apkSource.getName()
"Encountered an exception while reunpacking BackupSoSource "
+ backupSoSource.getName()
+ " for library "
+ soName
+ ": ",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.facebook.soloader.recovery;

import com.facebook.soloader.ApkSoSource;
import com.facebook.soloader.BackupSoSource;
import com.facebook.soloader.LogUtil;
import com.facebook.soloader.SoLoader;
import com.facebook.soloader.SoLoaderDSONotFoundError;
Expand All @@ -28,7 +28,7 @@
* RecoveryStrategy that detects cases when SoLoader failed to load a corrupted library, case in
* which we try to re-unpack the libraries.
*/
public class ReunpackNonApkSoSources implements RecoveryStrategy {
public class ReunpackNonBackupSoSources implements RecoveryStrategy {

@Override
public boolean recover(UnsatisfiedLinkError error, SoSource[] soSources) {
Expand Down Expand Up @@ -56,8 +56,8 @@ public boolean recover(UnsatisfiedLinkError error, SoSource[] soSources) {
continue;
}
UnpackingSoSource uss = (UnpackingSoSource) soSource;
if (uss instanceof ApkSoSource) {
// Assume ReunpackApkSoSources has already attempted to reunpack ApkSoSources
if (uss instanceof BackupSoSource) {
// Assume ReunpackBackupSoSources has already attempted to reunpack BackupSoSources
continue;
}
try {
Expand Down

0 comments on commit 6b32012

Please sign in to comment.