From e9905f6b6d5dc8c74541aacb3d54ef0a22cefa1b Mon Sep 17 00:00:00 2001 From: Rory Shu Date: Fri, 19 Apr 2024 08:44:22 -0700 Subject: [PATCH] add flag for DSONotFound error recovery for backup so source Summary: Add flag for enabling DSONotFound error. The flag will be used for running QE experiment to understand the performance impact of recovering from DSONotFound error. The flag is initially set to false. Reviewed By: adicatana Differential Revision: D56141106 fbshipit-source-id: cda9816f448f83890787e9843fb624384f1eff2e --- java/com/facebook/soloader/SoLoader.java | 18 ++++++++++++--- .../DefaultRecoveryStrategyFactory.java | 6 +++-- .../soloader/recovery/RecoveryStrategy.java | 3 +++ .../recovery/ReunpackBackupSoSources.java | 23 ++++++++++++++++--- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/java/com/facebook/soloader/SoLoader.java b/java/com/facebook/soloader/SoLoader.java index bb9382e..22c80e1 100644 --- a/java/com/facebook/soloader/SoLoader.java +++ b/java/com/facebook/soloader/SoLoader.java @@ -204,6 +204,9 @@ public class SoLoader { /** Experiment ONLY: skip custom SoSources for base.apk and rely on System.loadLibrary calls. */ public static final int SOLOADER_ENABLE_BASE_APK_SPLIT_SOURCE = (1 << 10); + /** Experiment ONLY: skip DSONotFound error recovery for back up so source */ + public static final int SOLOADER_ENABLE_BACKUP_SOSOURCE_DSONOTFOUND_ERROR_RECOVERY = (1 << 11); + @GuardedBy("sSoSourcesLock") private static int sFlags; @@ -269,7 +272,7 @@ public static void init(Context context, int flags, @Nullable SoFileLoader soFil flags |= SOLOADER_DISABLE_BACKUP_SOSOURCE; } - initSoLoader(context, soFileLoader); + initSoLoader(context, soFileLoader, flags); initSoSources(context, flags); LogUtil.v(TAG, "Init SoLoader delegate"); NativeLoader.initIfUninitialized(new NativeLoaderToSoLoaderDelegate()); @@ -522,8 +525,16 @@ private static int makePrepareFlags() { } } + private static int makeRecoveryFlags(int flags) { + int recoveryFlags = 0; + if ((flags & SOLOADER_ENABLE_BACKUP_SOSOURCE_DSONOTFOUND_ERROR_RECOVERY) != 0) { + recoveryFlags |= RecoveryStrategy.FLAG_ENABLE_DSONOTFOUND_ERROR_RECOVERY_FOR_BACKUP_SO_SOURCE; + } + return recoveryFlags; + } + private static synchronized void initSoLoader( - @Nullable Context context, @Nullable SoFileLoader soFileLoader) { + @Nullable Context context, @Nullable SoFileLoader soFileLoader, int flags) { if (context != null) { Context applicationContext = context.getApplicationContext(); @@ -537,7 +548,8 @@ private static synchronized void initSoLoader( } sApplicationContext = applicationContext; - sRecoveryStrategyFactory = new DefaultRecoveryStrategyFactory(applicationContext); + sRecoveryStrategyFactory = + new DefaultRecoveryStrategyFactory(applicationContext, makeRecoveryFlags(flags)); } if (soFileLoader == null && sSoFileLoader != null) { diff --git a/java/com/facebook/soloader/recovery/DefaultRecoveryStrategyFactory.java b/java/com/facebook/soloader/recovery/DefaultRecoveryStrategyFactory.java index d0281ef..5fb2b64 100644 --- a/java/com/facebook/soloader/recovery/DefaultRecoveryStrategyFactory.java +++ b/java/com/facebook/soloader/recovery/DefaultRecoveryStrategyFactory.java @@ -21,9 +21,11 @@ public class DefaultRecoveryStrategyFactory implements RecoveryStrategyFactory { private final Context mContext; private final BaseApkPathHistory mBaseApkPathHistory; + private final int mRecoveryFlags; - public DefaultRecoveryStrategyFactory(Context context) { + public DefaultRecoveryStrategyFactory(Context context, int recoveryFlags) { mContext = context; + mRecoveryFlags = recoveryFlags; mBaseApkPathHistory = new BaseApkPathHistory(5); mBaseApkPathHistory.recordPathIfNew(context.getApplicationInfo().sourceDir); } @@ -34,7 +36,7 @@ public RecoveryStrategy get() { new DetectDataAppMove(mContext, mBaseApkPathHistory), new CheckBaseApkExists(mContext, mBaseApkPathHistory), new WaitForAsyncInit(), - new ReunpackBackupSoSources(), + new ReunpackBackupSoSources(mRecoveryFlags), new ReunpackNonBackupSoSources(), new WaitForAsyncInit()); } diff --git a/java/com/facebook/soloader/recovery/RecoveryStrategy.java b/java/com/facebook/soloader/recovery/RecoveryStrategy.java index 6df79ba..c6b735f 100644 --- a/java/com/facebook/soloader/recovery/RecoveryStrategy.java +++ b/java/com/facebook/soloader/recovery/RecoveryStrategy.java @@ -20,5 +20,8 @@ // Abstract interface for algorithms attempting to recover SoLoader from a corrupted state. public interface RecoveryStrategy { + + public static final int FLAG_ENABLE_DSONOTFOUND_ERROR_RECOVERY_FOR_BACKUP_SO_SOURCE = 1; + boolean recover(UnsatisfiedLinkError e, SoSource[] soSources); } diff --git a/java/com/facebook/soloader/recovery/ReunpackBackupSoSources.java b/java/com/facebook/soloader/recovery/ReunpackBackupSoSources.java index 3dbcea4..11cee7f 100644 --- a/java/com/facebook/soloader/recovery/ReunpackBackupSoSources.java +++ b/java/com/facebook/soloader/recovery/ReunpackBackupSoSources.java @@ -33,6 +33,16 @@ */ public class ReunpackBackupSoSources implements RecoveryStrategy { + private int mRecoveryFlags; + + public ReunpackBackupSoSources() { + this(0); + } + + public ReunpackBackupSoSources(int recoveryFlags) { + mRecoveryFlags = recoveryFlags; + } + @Override public boolean recover(UnsatisfiedLinkError error, SoSource[] soSources) { if (!(error instanceof SoLoaderULError)) { @@ -49,10 +59,17 @@ public boolean recover(UnsatisfiedLinkError error, SoSource[] soSources) { } if (err instanceof SoLoaderDSONotFoundError) { - // Recover if DSO is not found - logRecovery(err, soName); + if ((mRecoveryFlags + & RecoveryStrategy.FLAG_ENABLE_DSONOTFOUND_ERROR_RECOVERY_FOR_BACKUP_SO_SOURCE) + != 0) { + + // Recover if DSO is not found + logRecovery(err, soName); - return recoverDSONotFoundError(soSources, soName, 0); + return recoverDSONotFoundError(soSources, soName, 0); + } else { + return false; + } } else if (message == null || (!message.contains("/app/") && !message.contains("/mnt/"))) { // Don't recover if the DSO wasn't in the data/app directory