Skip to content

Commit

Permalink
Added abi compatibility check
Browse files Browse the repository at this point in the history
Summary:
The goal of this diff is detect when the native libraries of the app do not match the device supported ABIs. Main changes:

 - Added mechanism in SoLoader SoSources to provide the supported ABIs in that SoSource
 - Added a function in SoLoader.areSoSourcesAbisSupported() to check the SoSource ABIs are supported by the device
 - Updated FbLoader for showing a notification (and crashing the app explicitly) when the the SoSource ABIs are not supported. That notification opens an activity showing information about the problem

Reviewed By: dcolascione

Differential Revision: D3185087

fbshipit-source-id: 4f14805810268d8be6e67125ff99a81ceebdce77
  • Loading branch information
Angel Gallego Vargas authored and Pascal Hartig committed Jan 9, 2018
1 parent 60e01b0 commit 7e69d71
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 7 deletions.
6 changes: 3 additions & 3 deletions java/com/facebook/soloader/ApkSoSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ public ApkSoSource(Context context, String name, int flags) {

@Override
protected Unpacker makeUnpacker() throws IOException {
return new ApkUnpacker();
return new ApkUnpacker(this);
}

protected class ApkUnpacker extends ZipUnpacker {

private File mLibDir;
private final int mFlags;

ApkUnpacker() throws IOException {
super();
ApkUnpacker(ExtractFromZipSoSource soSource) throws IOException {
super(soSource);
mLibDir = new File(mContext.getApplicationInfo().nativeLibraryDir);
mFlags = ApkSoSource.this.mFlags;
}
Expand Down
11 changes: 9 additions & 2 deletions java/com/facebook/soloader/ExoSoSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.io.IOException;
import android.content.Context;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;

Expand Down Expand Up @@ -49,14 +51,14 @@ public ExoSoSource(Context context, String name) {

@Override
protected Unpacker makeUnpacker() throws IOException {
return new ExoUnpacker();
return new ExoUnpacker(this);
}

private final class ExoUnpacker extends Unpacker {

private final FileDso[] mDsos;

ExoUnpacker() throws IOException {
ExoUnpacker(final UnpackingSoSource soSource) throws IOException {
Context context = mContext;
File exoDir = new File(
"/data/local/tmp/exopackage/"
Expand All @@ -65,12 +67,16 @@ private final class ExoUnpacker extends Unpacker {

ArrayList<FileDso> providedLibraries = new ArrayList<>();

Set<String> librariesAbiSet = new LinkedHashSet<>();

for (String abi : SysUtil.getSupportedAbis()) {
File abiDir = new File(exoDir, abi);
if (!abiDir.isDirectory()) {
continue;
}

librariesAbiSet.add(abi);

File metadataFileName = new File(abiDir, "metadata.txt");
if (!metadataFileName.isFile()) {
continue;
Expand Down Expand Up @@ -113,6 +119,7 @@ private final class ExoUnpacker extends Unpacker {
}
}

soSource.setSoSourceAbis(librariesAbiSet.toArray(new String[librariesAbiSet.size()]));
mDsos = providedLibraries.toArray(new FileDso[providedLibraries.size()]);
}

Expand Down
13 changes: 11 additions & 2 deletions java/com/facebook/soloader/ExtractFromZipSoSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import java.io.File;
import java.io.IOException;
import android.content.Context;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -45,20 +48,23 @@ public ExtractFromZipSoSource(

@Override
protected Unpacker makeUnpacker() throws IOException {
return new ZipUnpacker();
return new ZipUnpacker(this);
}

protected class ZipUnpacker extends Unpacker {

private ZipDso[] mDsos;
private final ZipFile mZipFile;
private final UnpackingSoSource mSoSource;

ZipUnpacker() throws IOException {
ZipUnpacker(final UnpackingSoSource soSource) throws IOException {
mZipFile = new ZipFile(mZipFileName);
mSoSource = soSource;
}

final ZipDso[] ensureDsos() {
if (mDsos == null) {
Set<String> librariesAbiSet = new LinkedHashSet<>();
HashMap<String, ZipDso> providedLibraries = new HashMap<>();
Pattern zipSearchPattern = Pattern.compile(mZipSearchPattern);
String[] supportedAbis = SysUtil.getSupportedAbis();
Expand All @@ -71,6 +77,7 @@ final ZipDso[] ensureDsos() {
String soName = m.group(2);
int abiScore = SysUtil.findAbiScore(supportedAbis, libraryAbi);
if (abiScore >= 0) {
librariesAbiSet.add(libraryAbi);
ZipDso so = providedLibraries.get(soName);
if (so == null || abiScore < so.abiScore) {
providedLibraries.put(soName, new ZipDso(soName, entry, abiScore));
Expand All @@ -79,6 +86,8 @@ final ZipDso[] ensureDsos() {
}
}

mSoSource.setSoSourceAbis(librariesAbiSet.toArray(new String[librariesAbiSet.size()]));

ZipDso[] dsos = providedLibraries.values().toArray(new ZipDso[providedLibraries.size()]);
Arrays.sort(dsos);
int nrFilteredDsos = 0;
Expand Down
28 changes: 28 additions & 0 deletions java/com/facebook/soloader/SoLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,32 @@ public static synchronized String makeLdLibraryPath() {
}
return TextUtils.join(":", pathElements);
}

/**
* This function ensure that every SoSources Abi is supported for at least one
* abi in SysUtil.getSupportedAbis
* @return true if all SoSources have their Abis supported
*/
public static boolean areSoSourcesAbisSupported() {
SoSource[] soSources = sSoSources;
if (soSources == null) {
return false;
}

String supportedAbis[] = SysUtil.getSupportedAbis();
for (int i = 0; i < soSources.length; ++i) {
String[] soSourceAbis = soSources[i].getSoSourceAbis();
for (int j = 0; j < soSourceAbis.length; ++j) {
boolean soSourceSupported = false;
for (int k = 0; k < supportedAbis.length && !soSourceSupported; ++k) {
soSourceSupported = soSourceAbis[j].equals(supportedAbis[k]);
}
if (!soSourceSupported) {
return false;
}
}
}

return true;
}
}
10 changes: 10 additions & 0 deletions java/com/facebook/soloader/SoSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,14 @@ protected void prepare(int flags) throws IOException {
public void addToLdLibraryPath(Collection<String> paths) {
/* By default, do nothing */
}

/**
* Return an array of ABIs handled by this SoSource.
*
* @return ABIs supported by this SoSource
*/
public String[] getSoSourceAbis() {
/* By default, the same as the device */
return SysUtil.getSupportedAbis();
}
}
14 changes: 14 additions & 0 deletions java/com/facebook/soloader/UnpackingSoSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public abstract class UnpackingSoSource extends DirectorySoSource {
private static final byte MANIFEST_VERSION = 1;

protected final Context mContext;
private String[] mAbis;

protected UnpackingSoSource(Context context, String name) {
super(getSoStorePath(context, name), RESOLVE_DEPENDENCIES);
Expand All @@ -47,6 +48,19 @@ public static File getSoStorePath(Context context, String name) {

protected abstract Unpacker makeUnpacker() throws IOException;

@Override
public String[] getSoSourceAbis() {
if (mAbis == null) {
return super.getSoSourceAbis();
}

return mAbis;
}

public void setSoSourceAbis(final String []abis) {
mAbis = abis;
}

public static class Dso {
public final String name;
public final String hash;
Expand Down

0 comments on commit 7e69d71

Please sign in to comment.