/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.soloader; import java.util.List; import android.util.Log; /** * This is the base class for all the classes representing certain native library. * For loading native libraries we should always inherit from this class and provide relevant * information (libraries to load, code to test native call, dependencies?). * <p> * This instances should be singletons provided by DI. * <p> * This is a basic template but could be improved if we find the need. */ public abstract class NativeLibrary { private static final String TAG = NativeLibrary.class.getName(); private final Object mLock; private List<String> mLibraryNames; private Boolean mLoadLibraries; private boolean mLibrariesLoaded; private volatile UnsatisfiedLinkError mLinkError; protected NativeLibrary(List<String> libraryNames) { mLock = new Object(); mLoadLibraries = true; mLibrariesLoaded = false; mLinkError = null; mLibraryNames = libraryNames; } /** * safe loading of native libs * @return true if native libs loaded properly, false otherwise */ public boolean loadLibraries() { synchronized (mLock) { if (mLoadLibraries == false) { return mLibrariesLoaded; } try { for (String name: mLibraryNames) { SoLoader.loadLibrary(name); } initialNativeCheck(); mLibrariesLoaded = true; mLibraryNames = null; } catch (UnsatisfiedLinkError error) { Log.e(TAG, "Failed to load native lib: ", error); mLinkError = error; mLibrariesLoaded = false; } mLoadLibraries = false; return mLibrariesLoaded; } } /** * loads libraries (if not loaded yet), throws on failure * @throws UnsatisfiedLinkError */ public void ensureLoaded() throws UnsatisfiedLinkError { if (!loadLibraries()) { throw mLinkError; } } /** * Override this method to make some concrete (quick and harmless) native call. * This avoids lazy-loading some phones (LG) use when we call loadLibrary. If there's a problem * we'll face an UnsupportedLinkError when first using the feature instead of here. * This check force a check right when intended. * This way clients of this library can know if it's loaded for sure or not. * @throws UnsatisfiedLinkError if there was an error loading native library */ protected void initialNativeCheck() throws UnsatisfiedLinkError { } public UnsatisfiedLinkError getError() { return mLinkError; } }