diff --git a/java/com/facebook/soloader/InstrumentedSoFileLoader.java b/java/com/facebook/soloader/InstrumentedSoFileLoader.java new file mode 100644 index 0000000..cb43383 --- /dev/null +++ b/java/com/facebook/soloader/InstrumentedSoFileLoader.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.facebook.soloader; + +import android.annotation.SuppressLint; +import com.facebook.soloader.observer.ObserverHolder; +import javax.annotation.Nullable; + +public class InstrumentedSoFileLoader implements SoFileLoader { + private final SoFileLoader mDelegate; + + public InstrumentedSoFileLoader(SoFileLoader delegate) { + mDelegate = delegate; + } + + @Override + @SuppressLint({"CatchGeneralException", "EmptyCatchBlock"}) + public void load(String pathToSoFile, int loadFlags) { + @Nullable Throwable failure = null; + ObserverHolder.onSoFileLoaderLoadStart(mDelegate, "load", loadFlags); + try { + mDelegate.load(pathToSoFile, loadFlags); + } catch (Throwable t) { + failure = t; + throw t; + } finally { + ObserverHolder.onSoFileLoaderLoadEnd(failure); + } + } + + @Override + @SuppressLint({"CatchGeneralException", "EmptyCatchBlock"}) + public void loadBytes(String pathName, ElfByteChannel bytes, int loadFlags) { + @Nullable Throwable failure = null; + ObserverHolder.onSoFileLoaderLoadStart(mDelegate, "loadBytes", loadFlags); + try { + mDelegate.loadBytes(pathName, bytes, loadFlags); + } catch (Throwable t) { + failure = t; + throw t; + } finally { + ObserverHolder.onSoFileLoaderLoadEnd(failure); + } + } +} diff --git a/java/com/facebook/soloader/SoLoader.java b/java/com/facebook/soloader/SoLoader.java index 0038392..c6756ba 100644 --- a/java/com/facebook/soloader/SoLoader.java +++ b/java/com/facebook/soloader/SoLoader.java @@ -549,7 +549,7 @@ private static synchronized void initSoLoader( return; } - sSoFileLoader = new SoFileLoaderImpl(); + sSoFileLoader = new InstrumentedSoFileLoader(new SoFileLoaderImpl()); } private static int getAppType(Context context) { diff --git a/java/com/facebook/soloader/observer/Observer.java b/java/com/facebook/soloader/observer/Observer.java index 2368743..0579664 100644 --- a/java/com/facebook/soloader/observer/Observer.java +++ b/java/com/facebook/soloader/observer/Observer.java @@ -16,6 +16,7 @@ package com.facebook.soloader.observer; +import com.facebook.soloader.SoFileLoader; import com.facebook.soloader.SoSource; import com.facebook.soloader.recovery.RecoveryStrategy; import javax.annotation.Nullable; @@ -40,4 +41,8 @@ public interface Observer { void onGetDependenciesStart(); void onGetDependenciesEnd(@Nullable Throwable t); + + void onSoFileLoaderLoadStart(SoFileLoader soFileLoader, String method, int flags); + + void onSoFileLoaderLoadEnd(@Nullable Throwable t); } diff --git a/java/com/facebook/soloader/observer/ObserverHolder.java b/java/com/facebook/soloader/observer/ObserverHolder.java index 7bb0e0d..02bf113 100644 --- a/java/com/facebook/soloader/observer/ObserverHolder.java +++ b/java/com/facebook/soloader/observer/ObserverHolder.java @@ -16,6 +16,7 @@ package com.facebook.soloader.observer; +import com.facebook.soloader.SoFileLoader; import com.facebook.soloader.SoSource; import com.facebook.soloader.recovery.RecoveryStrategy; import java.util.concurrent.atomic.AtomicReference; @@ -133,4 +134,22 @@ public static void onGetDependenciesEnd(@Nullable Throwable t) { } } } + + public static void onSoFileLoaderLoadStart(SoFileLoader soFileLoader, String method, int flags) { + Observer[] observers = sObservers.get(); + if (observers != null) { + for (Observer observer : observers) { + observer.onSoFileLoaderLoadStart(soFileLoader, method, flags); + } + } + } + + public static void onSoFileLoaderLoadEnd(@Nullable Throwable t) { + Observer[] observers = sObservers.get(); + if (observers != null) { + for (Observer observer : observers) { + observer.onSoFileLoaderLoadEnd(t); + } + } + } }