Showing posts with label NDK. Show all posts
Showing posts with label NDK. Show all posts

Tuesday, March 21, 2017

Introducing Android Native Development Kit r14


Posted by Dan Albert, Android NDK Tech Lead





Android NDK r14





The latest version of the Android Native Development Kit (NDK), Android NDK r14,
is now available for download. It
is also available in the SDK manager via Android Studio.



So what's new in r14? The full changelog can be seen here, but the
highlights include the following:



  • Updated all the platform headers to unified headers (covered in detail
    below)

  • LTO with Clang now works on Darwin and Linux

  • libc++ has been updated. You can now use thread_local for statics with
    non-trivial destructors (Clang only)

  • RenderScript is back!








Unified Headers


We've completely redone how we ship platform header files in the NDK. Rather
than having one set of headers for every target API level, there's now a single
set of headers. The availability of APIs for each Android platform is guarded in
these headers by #if __ANDROID_API__ >= __ANDROID_API_FOO__ preprocessor
directives.




The prior approach relied on periodically-captured snapshots of the platform
headers. This meant that any time we fixed a header-only bug, the fix was only
available in the latest version aside from the occasional backport. Now bugfixes
are available regardless of your NDK API level.




Aside from bugfixes, this also means you'll have access to modern Linux UAPI
headers at every target version. This will mostly be important for people
porting existing Linux code (especially low-level things). Something important
to keep in mind: just because you have the headers doesn't mean you're running
on a device with a kernel new enough to support every syscall. As always with
syscalls, ENOSYS is a possibility.




Beyond the Linux headers, you'll also have modern headers for OpenGL, OpenSLES,
etc. This should make it easier to conditionally use new APIs when you have an
older target API level. The GLES3 headers are now accessible on Ice Cream
Sandwich even though that library wasn't available until KitKat. You will still
need to use all the API calls via dlopen/dlsym, but you'll at least have
access to all the constants and #defines that you would need for invoking
those functions.


Note that we'll be removing the old headers from the NDK with r16, so the sooner
you file bugs, the smoother the transition will go.






Caveats


The API #ifdef guards do not exist in third-party headers like those found in
OpenGL. In those cases you'll receive a link time error (undefined reference)
rather than a compile time error if you use an API that is not available in your
targeted API level.




Standalone toolchains using GCC are not supported out of the box (nor will they
be). To use GCC, pass -D__ANDROID_API__=$API when compiling.






Enabling Unified Headers in Your Build


To ease the transition from the legacy headers to the unified headers, we
haven't enabled the new headers by default, though we'll be doing this in r15.
How you opt-in to unified headers will depend on your build system.





ndk-build




In your Application.mk:




    APP_UNIFIED_HEADERS := true

You can also set this property from the command-line like this:




    $ ndk-build APP_UNIFIED_HEADERS=true



If you're using ndk-build via Gradle with externalNativeBuild, specify the
following configuration settings in build.gradle:




    android {
...
defaultConfig {
...
externalNativeBuild {
ndkBuild {
...
arguments "APP_UNIFIED_HEADERS=true"
}
}
}
}



CMake


When configuring your build, set ANDROID_UNIFIED_HEADERS=ON. This will usually
take the form of invoking CMake with cmake -DANDROID_UNIFIED_HEADERS=ON
$OTHER_ARGS
.




If you're using CMake via Gradle with externalNativeBuild, you can use:




    android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
...
arguments "-DANDROID_UNIFIED_HEADERS=ON"
}
}
}
}



Standalone Toolchains


When creating your standalone toolchain, pass --unified-headers. Note that
this option is not currently available in the legacy script, make-standalone-toolchain.sh, but only in make_standalone_toolchain.py.






Experimental Gradle Plugin


Coming soon! Follow along here.






Custom Build System?


We've got you covered. Instructions on adding support for unified headers to
your build system can be found here.



For additional information about unified headers, see our docs and the tracking bug. If you're looking ahead to future releases, the most up-to-date version of the
documentation is in the master branch.

Tuesday, November 22, 2016

Calling European game developers, enter the Indie Games Contest by December 31

Originally posted on Google Developers blog


Posted by Matteo Vallone, Google Play Games Business Development



To build awareness of the awesome innovation and art that indie game developers
are bringing to users on Google Play, we have invested heavily over the past
year in programs like href="https://play.google.com/store/info/topic?id=topic_b000054_games_indie_corner_tp&e=-EnableAppDetailsPageRedesign">Indie
Corner, as well as events like the Google Play Indie Games Festivalshref="https://events.withgoogle.com/google-play-indie-game-festival/"> in
North
America
and href="https://events.withgoogle.com/google-play-indie-games-fes/">Korea.



As part of that sustained effort, we also want to celebrate the passion and
innovation of indie game developers with the introduction of the first-ever
href="https://events.withgoogle.com/indie-games-contest-europe/">Google Play
Indie Games Contest
in Europe. The contest will recognize the best
indie talent in several countries and offer prizes that will help you get your
game noticed by industry experts and gamers worldwide.




Prizes for the finalists and winners:


  • An open showcase held at the Saatchi Gallery in London
  • YouTube influencer campaigns worth up to 100,000 EUR
  • Premium placements on Google Play
  • Tickets to Google I/O 2017 and other top industry events
  • Promotions on our channels
  • Special prizes for the best Unity game
  • And href="https://events.withgoogle.com/indie-games-contest-europe/prizes/">more!


Entering the contest:



If you're based in Czech Republic, Denmark, Finland, France (coming soon),
Germany, Iceland, Israel, Netherlands, Norway, Poland (coming soon), Romania,
Spain, Sweden, Turkey, or UK (excl. Northern Ireland), have 15 or less full time
employees, and published a new game on Google Play after 1 January 2016, you may
now be eligible to href="https://events.withgoogle.com/indie-games-contest-europe/">enter the
contest. If you're planning on publishing a new game soon, you can also
enter by submitting a private beta. Check out all the details in the href="https://events.withgoogle.com/indie-games-contest-europe/terms/">terms and
conditions. Submissions close on 31 December 2016.




The process:



Up to 20 finalists will get to showcase their games at an open event at the
Saatchi Gallery in London on the 16th February 2017. At the event, the top 10
will be selected by the event attendees and the Google Play team. The top 10
will then get the opportunity to pitch to a jury of industry experts, from which
the final winner and runners up will be selected.



Even if someone is NOT entering the contest:



Even if you're not eligible to enter the contest, you can still register to
attend the final showcase event in London on 16 February 2017, check out some
great indie games, and have fun with various industry experts and indie
developers. We will also be hosting a workshop for all indie games developers
from across EMEA in the new Google office in Kings Cross the next day, so this
will be a packed week.



Get started:



href="https://events.withgoogle.com/indie-games-contest-europe/">Enter the Indie
Games Contest now
and visit the href="https://events.withgoogle.com/indie-games-contest-europe/">contest
site to find out more about the contest, the event, and the workshop.


Monday, November 7, 2016

CMake and ndk-build support in Android Studio 2.2

Posted by Kathryn Shih, Android Product Manager


In addition to supporting the experimental Gradle plugin, href="http://android-developers.blogspot.com/2016/09/android-studio-2-2.html">Android
Studio 2.2 enables you to build C/C++ components of Android projects using
CMake and ndk-build.




The Android Studio team plans to continue to support the experimental Gradle plugin.
This will eventually replace the current Gradle plugin, providing additional
tightly-integrated benefits to C/C++ developers such as smarter dependency
management. So if you're interested in someday having the smartest possible
interface between your IDE and your build system, you shouldn't ignore the
experimental plugin.



CMake and ndk-build are useful alternatives to Gradle in several cases:


  • Projects that are already using CMake or ndk-build, such as legacy Eclipse
    ndk projects
  • Projects that are unable to assume the risk of using an experimental plugin
    for their C/C++ builds
  • Projects that will share a C/C++ build system across multiple platforms
  • C/C++ projects that need to use advanced features currently unavailable in
    experimental Gradle such as NEON support


For new projects, we recommend using CMake or experimental Gradle. For new
Android projects with limited C++, we recommend trying the experimental Gradle
plugin. For projects with substantial amounts of C++, or where you want the
maximally stable build configuration, we recommend using a CMake build. Android
Studio intends CMake to be a permanently supported solution.



While we think that there are substantial advantages to having a single build
system able to handle all parts of an Android application, stabilizing the
experimental plugin is not an option for us because it relies on Gradle APIs
that are still a work in progress. Until the Gradle APIs are stabilized, the
experimental plugin will keep changing, particularly in its Domain Specific
Language, and will be strictly tied to a very specific version of Gradle itself.



Note that the the old, undocumented ndkCompile integration is deprecated. If you
are using it, you need to move away from it as we'll remove it completely in the
near future. We recommend migrating to gradle+cmake via our href="https://developer.android.com/studio/projects/add-native-code.html?utm_campaign=android_discussion_cmake_110716&utm_source=anddev&utm_medium=blog">migration
guide.



Migrating from Eclipse to Android Studio



href="https://android-developers.blogspot.com/2016/11/support-ended-for-eclipse-android.html">We
no longer support the Eclipse ADT. To get started migrating, href="https://developer.android.com/studio/index.html?utm_campaign=android_discussion_cmake_110716&utm_source=anddev&utm_medium=blog">download and install
Android Studio. For most projects, migration is as simple as importing your
existing Eclipse ADT projects in Android Studio with the File ? New?
Import Project
menu option. For more details on the migration process,
check out the href="https://developer.android.com/studio/intro/migrate.html?utm_campaign=android_discussion_cmake_110716&utm_source=anddev&utm_medium=blog">migration
guide.



Feedback and Open Source Contributions



We're dedicated to making Android Studio the best possible integrated
development environment for building Android apps, so if there are missing
features or other challenges preventing you from using Android Studio, href="https://goo.gl/forms/aGz9hQyRaTRQzN4s1">we want to hear about it [href="https://goo.gl/forms/aGz9hQyRaTRQzN4s1">please take our survey]. You
can also file bugs or feature
requests
directly with the team, and let us know via our href="http://www.twitter.com/androidstudio">Twitter or href="https://plus.google.com/103342515830390186255">Google+ accounts.



Android Studio is an open source
project, available to all at no cost. Check out our href="http://tools.android.com/contributing">Open Source project page if
you're interested in contributing or learning more.

Monday, June 27, 2016

Android changes for NDK developers

Posted by Dmitry Malykhanov, Developer Advocate




Related to other improvements to the Android platform, the dynamic linker in
Android M and N has stricter requirements for writing clean, cross-platform
compatible native code in order to load. It is necessary that an application�s
native code follows the rules and recommendations in order to ensure a smooth
transition to recent Android releases.



Below we outline in detail each individual change related to native code
loading, the consequences and steps you can take to avoid issues.



Required tools: there is an <arch>-linux-android-readelf binary (e.g.
arm-linux-androideabi-readelf or i686-linux-android-readelf) for each
architecture in the NDK (under toolchains/), but you can use readelf for any
architecture, as we will be doing basic inspection only. On Linux you need to
have the �binutils� package installed for readelf, and �pax-utils� for scanelf.


Private API (Enforced since API 24)



Native libraries must use only href="http://developer.android.com/ndk/guides/stable_apis.html?utm_campaign=android_discussion_ndkchanges_062716&utm_source=anddev&utm_medium=blog">public API,
and must not link against non-NDK platform libraries. Starting with API 24 this
rule is enforced and applications are no longer able to load non-NDK platform
libraries. The rule is enforced by the dynamic linker, so non-public libraries
are not accessible regardless of the way code tries to load them:
System.loadLibrary(...), DT_NEEDED entries, and direct calls to dlopen(...) will
fail in exactly the same way.



Users should have a consistent app experience across updates, and developers
shouldn�t have to make emergency app updates to handle platform changes. For
that reason, we recommend against using private C/C++ symbols. Private symbols
aren�t tested as part of the Compatibility Test Suite (CTS) that all Android
devices must pass. They may not exist, or they may behave differently. This
makes apps that use them more likely to fail on specific devices, or on future
releases --- as many developers found when Android 6.0 Marshmallow switched from
OpenSSL to BoringSSL.



In order to reduce the user impact of this transition, we�ve identified a set of
libraries that see significant use from Google Play�s most-installed apps, and
that are feasible for us to support in the short term (including
libandroid_runtime.so, libcutils.so, libcrypto.so, and libssl.so). In order to
give you more time to transition, we will temporarily support these libraries;
so if you see a warning that means your code will not work in a future release
-- please fix it now!



$ readelf --dynamic libBroken.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [libnativehelper.so]
0x00000001 (NEEDED) Shared library: [libutils.so]
0x00000001 (NEEDED) Shared library: [libstagefright_foundation.so]
0x00000001 (NEEDED) Shared library: [libmedia_jni.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libz.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]


Potential problems: starting from API 24 the dynamic linker will not load
private libraries, preventing the application from loading.



Resolution: rewrite your native code to rely only on public API. As a short term
workaround, platform libraries without complex dependencies (libcutils.so) can
be copied to the project. As a long term solution the relevant code must be
copied to the project tree. SSL/Media/JNI internal/binder APIs should not be
accessed from the native code. When necessary, native code should call
appropriate public Java API methods.



A complete list of public libraries is available within the NDK, under
platforms/android-API/usr/lib.


Note: SSL/crypto is a special case, applications must NOT use platform libcrypto
and libssl libraries directly, even on older platforms. All applications should
use href="http://developer.android.com/training/articles/security-gms-provider.html?utm_campaign=android_discussion_ndkchanges_062716&utm_source=anddev&utm_medium=blog">GMS
Security Provider to ensure they are protected from known vulnerabilities.


Missing Section Headers (Enforced since API 24)



Each ELF file has additional information contained in the section headers. These
headers must be present now, because the dynamic linker uses them for sanity
checking. Some developers try to strip them in an attempt to obfuscate the
binary and prevent reverse engineering. (This doesn�t really help because it is
possible to reconstruct the stripped information using widely-available tools.)



$ readelf --header libBroken.so | grep 'section headers'
Start of section headers: 0 (bytes into file)
Size of section headers: 0 (bytes)
Number of section headers: 0
$


Resolution: remove the extra steps from your build that strip section headers.


Text Relocations (Enforced since API 23)



Starting with API 23, shared objects must not contain text relocations. That is,
the code must be loaded as is and must not be modified. Such an approach reduces
load time and improves security.



The usual reason for text relocations is non-position independent hand-written
assembler. This is not common. Use the href="https://wiki.gentoo.org/wiki/Hardened/Textrels_Guide#Finding_broken_object_code">scanelf
tool as described in href="http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html?utm_campaign=android_discussion_ndkchanges_062716&utm_source=anddev&utm_medium=blog#behavior-runtime">our
documentation for further diagnostics:



$ scanelf -qT libTextRel.so
libTextRel.so: (memory/data?) [0x15E0E2] in (optimized out: previous simd_broken_op1) [0x15E0E0]
libTextRel.so: (memory/data?) [0x15E3B2] in (optimized out: previous simd_broken_op2) [0x15E3B0]
[skipped the rest]


If you have no scanelf tool available, it is possible to do a basic check with
readelf instead, look for either a TEXTREL entry or the TEXTREL flag. Either
alone is sufficient. (The value corresponding to the TEXTREL entry is irrelevant
and typically 0 --- simply the presence of the TEXTREL entry declares that the
.so contains text relocations). This example has both indicators present:



$ readelf --dynamic libTextRel.so | grep TEXTREL
0x00000016 (TEXTREL) 0x0
0x0000001e (FLAGS) SYMBOLIC TEXTREL BIND_NOW
$


Note: it is technically possible to have a shared object with the TEXTREL
entry/flag but without any actual text relocations. This doesn�t happen with the
NDK, but if you�re generating ELF files yourself make sure you�re not generating
ELF files that claim to have text relocations, because the Android dynamic
linker trusts the entry/flag.



Potential problems: Relocations enforce code pages being writable, and
wastefully increase the number of dirty pages in memory. The dynamic linker has
issued warnings about text relocations since Android K (API 19), but on API 23
and above it refuses to load code with text relocations.



Resolution: rewrite assembler to be position independent to ensure no text
relocations are necessary. Check the href="https://wiki.gentoo.org/wiki/Hardened/Textrels_Guide">Gentoo
documentation for cookbook recipes.


Invalid DT_NEEDED Entries (Enforced since API 23)



While library dependencies (DT_NEEDED entries in the ELF headers) can be
absolute paths, that doesn�t make sense on Android because you have no control
over where your library will be installed by the system. A DT_NEEDED entry
should be the same as the needed library�s SONAME, leaving the business of
finding the library at runtime to the dynamic linker.



Before API 23, Android�s dynamic linker ignored the full path, and used only the
basename (the part after the last �/�) when looking up the required libraries.
Since API 23 the runtime linker will honor the DT_NEEDED exactly and so it won�t
be able to load the library if it is not present in that exact location on the
device.



Even worse, some build systems have bugs that cause them to insert DT_NEEDED
entries that point to a file on the build host, something that
cannot be found on the device.



$ readelf --dynamic libSample.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library:
[C:\Users\build\Android\ci\jni\libBroken.so]
$


Potential problems: before API 23 the DT_NEEDED entry�s basename was used, but
starting from API 23 the Android runtime will try to load the library using the path
specified, and that path won�t exist on the device. There are broken third-party
toolchains/build systems that use a path on a build host instead of the SONAME.



Resolution: make sure all required libraries are referenced by SONAME only. It
is better to let the runtime linker to find and load those libraries as the
location may change from device to device.


Missing SONAME (Used since API 23)



Each ELF shared object (�native library�) must have a SONAME (Shared Object
Name) attribute. The NDK toolchain adds this attribute by default, so its
absence indicates either a misconfigured alternative toolchain or a
misconfiguration in your build system. A missing SONAME may lead to runtime
issues such as the wrong library being loaded: the filename is used instead when
this attribute is missing.



$ readelf --dynamic libWithSoName.so | grep SONAME
0x0000000e (SONAME) Library soname: [libWithSoName.so]
$


Potential problems: namespace conflicts may lead to the wrong library being
loaded at runtime, which leads to crashes when required symbols are not found,
or you try to use an ABI-incompatible library that isn�t the library you were
expecting.



Resolution: the current NDK generates the correct SONAME by default. Ensure
you�re using the current NDK and that you haven�t configured your build system
to generate incorrect SONAME entries (using the -soname linker
option).



Please remember, clean, cross-platform code built with a current NDK should have
no issues on Android N. We encourage you to revise your native code build so
that it produces correct binaries.

Tuesday, June 21, 2016

Improving Stability with Private C/C++ Symbol Restrictions in Android N

Posted by Dimitry Ivanov & Elliott Hughes, Software Engineers




As documented in the href="https://developer.android.com/preview/behavior-changes.html#ndk">Android N
behavioral changes, to protect Android users and apps from unforeseen
crashes, Android N will restrict which libraries your C/C++ code can link
against at runtime
. As a result, if your app uses any private symbols from
platform libraries, you will need to update it to either use the public NDK APIs
or to include its own copy of those libraries. Some libraries are public: the
NDK exposes libandroid, libc, libcamera2ndk, libdl,
libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES,
libstdc++, libvulkan, and libz as part of the NDK API. Other libraries are
private, and Android N only allows access to them for platform HALs, system
daemons, and the like. If you aren�t sure whether your app uses private
libraries, you can immediately check it for warnings on the N Developer Preview.



We�re making this change because it�s painful for users when their apps stop
working after a platform update. Whether they blame the app developer or the
platform, everybody loses. Users should have a consistent app experience across
updates, and developers shouldn�t have to make emergency app updates to handle
platform changes. For that reason, we recommend against using private C/C++
symbols. Private symbols aren�t tested as part of the Compatibility Test Suite
(CTS) that all Android devices must pass. They may not exist, or they may behave
differently. This makes apps that use them more likely to fail on specific
devices, or on future releases — as many developers found when Android 6.0
Marshmallow switched from OpenSSL to BoringSSL.



You may be surprised that there�s no STL in the list of NDK libraries. The three
STL implementations included in the NDK — the LLVM libc++, the GNU STL, and
libstlport — are intended to be bundled with your app, either by statically
linking into your library, or by inclusion as a separate shared library. In the
past, some developers have assumed that they didn�t need to package the library
because the OS itself had a copy. This assumption is incorrect: a particular STL
implementation may disappear (as was the case with stlport, which was removed in
Marshmallow), may never have been available (as is the case with the GNU STL),
or it may change in ABI incompatible ways (as is the case with the LLVM libc++).



In order to reduce the user impact of this transition, we�ve identified a set of
libraries that see significant use from Google Play�s most-installed apps, and
that are feasible for us to support in the short term (including
libandroid_runtime.so, libcutils.so, libcrypto.so, and libssl.so). For legacy
code in N, we will temporarily support these libraries in order to give you more
time to transition. Note that we don't intend to continue this support in any
future Android platform release, so if you see a warning that means your code
will not work in a future release — please fix it now!




Table 1. What to expect if your app is linking against private native libraries.














































LibrariesApp's targetSdkVersionRuntime access via dynamic linkerImpact, N Developer PreviewImpact, Final N ReleaseImpact, future platform version
NDK PublicAnyAccessible
Private (graylist)<=23Temporarily accessibleWarning / ToastWarningError
>=24RestrictedErrorErrorError
Private (all other)>AnyRestrictedErrorErrorError



What behavior will I see?



Please test your app during the N Previews.



N Preview behavior



  • All public NDK libraries (libandroid, libc, libcamera2ndk, libdl, libGLES,
    libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++,
    libvulkan, and libz), plus libraries that are part of your app are accessible.
  • For all other libraries you�ll see a warning in logcat and a toast on the
    display. This will happen only if your app�s targetSdkVersion is less than N. If
    you change your manifest to target N, loading will fail: Java�s
    System.loadLibrary will throw, and C/C++�s dlopen(3) will return NULL.






Test your apps on the Developer Preview — if you see a toast like this one, your app is accessing private native APIs. Please fix your code soon!




N Final Release behavior



  • All NDK libraries (libandroid, libc, libcamera2ndk, libdl, libGLES,
    libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++,
    libvulkan, and libz), plus libraries that are part of your app are accessible.
  • For the temporarily accessible libraries (such as libandroid_runtime.so,
    libcutils.so, libcrypto.so, and libssl.so), you�ll see a warning in logcat for
    all API levels before N, but loading will fail if you update your app so that
    its targetSdkVersion is N or later.
  • Attempts to load any other libraries will fail in the final release of
    Android N, even if your app is targeting a pre-N platform version.




Future platform behavior



  • In O, all access to the temporarily accessible libraries will be removed.
    As a result, you should plan to update your app regardless of your
    targetSdkVersion prior to O. If you believe there is missing functionality from
    the NDK API that will make it impossible for you to transition off a temporarily
    accessible library, please file a bug here.




What do the errors look like?



Here�s some example logcat output from an app that hasn�t bumped its target SDK
version (and so the restriction isn�t fully enforced because this is only the
developer preview):




03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120


This is telling you that your library �libapplib.so� refers to the library
�libandroid_runtime.so�, which is a private library.



When Android N ships, or if you set your target SDK version to N now, you�ll see
something like this if you try to use System.loadLibrary from Java:


java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by "/system/lib/libnativeloader.so"
is not accessible for the namespace "classloader-namespace"
at java.lang.Runtime.loadLibrary0(Runtime.java:977)
at java.lang.System.loadLibrary(System.java:1602)


If you�re using href="http://man7.org/linux/man-pages/man3/dlopen.3.html">dlopen(3) from
C/C++ you�ll get a NULL return and href="http://man7.org/linux/man-pages/man3/dlerror.3.html">dlerror(3) will
return the same �dlopen failed...� string as shown above.



For more information about how to check if your app is using private symbols,
see the FAQ on developer.android.com.