android_app.h
An Android app's activity, in C++.
#include <sonore/android_app.h>- 2types
- 28other declarations
- Guides: Getting started, Platforms and formats
On this page
Design notes
NativeActivity, and no Java of our own
Android starts an app as a Java Activity. android.app.NativeActivity is the framework's own one for apps written in C and C++: it loads the library the manifest names and calls ANativeActivity_onCreate in it, then forwards the activity's life -- start, resume, pause, the window, the input queue -- as C callbacks. So an APK built by sonore_add_standalone carries one .so and no dex, and everything an app does runs here, on the activity's MAIN thread, the one Android calls the UI thread.
What this file does with it:
- Puts the window on the screen: the activity's ANativeWindow is attached to gfx::AndroidSurface, the compositor every native-window peer draws into (gfx/window_android.h).
- Runs the UI: the main thread's ALooper gets the input queue, a 60 Hz timerfd for the surface's clock while the activity is visible, and the MessageManager's wake-up descriptor, so callAsync() lands on this thread as it does on every other platform.
- Gives the app a place on disk: HOME is the app's files folder and TMPDIR its cache, which is where every "user folder" and "temporary file" in the SDK then goes. An Android shell's /tmp does not exist for an app.
- Asks the framework what the C side cannot: the screen's density, whether the app may record audio, and whether the sound is going to headphones. Through JNI on framework classes only, which is why there is no dex.
An app implements ActivityHooks and returns one from sonore_android_make_app (standalone_android.h does, for a plugin's standalone).
Types 2
What an app does when its activity moves: all on the main thread. Every hook is optional; the activity itself keeps the window on the surface.
The state of the one activity this process runs, and its looper wiring.
Functions 28
- fn
inline void log(const char* format, ...)printf to the device log (logcat), under the "sonore" tag.android::log · android_app.h:61 - fn
inline float densityScale(ANativeActivity* activity)The density scale: one logical pixel in device pixels (dpi / 160).android::densityScale · android_app.h:97 - fn
inline std::string cacheDir(ANativeActivity* activity)The app's cache folder (Context.getCacheDir), or empty.android::cacheDir · android_app.h:108 - fn
inline bool hasPermission(const char* permission)Whether the app holds an Android permission ("android.permission....").android::hasPermission · android_app.h:134 - fn
inline void requestPermission(const char* permission)Ask the user for a permission. The answer comes back as the activity resuming (the system dialog paused it): check hasPermission() there.android::requestPermission · android_app.h:153 - fn
inline bool outputIsPrivate()Whether the sound is going somewhere only the user hears it -- wired or Bluetooth headphones, a USB interface, a hearing aid -- rather than the built-in speaker, where a microphone would hear it too and howl. AudioManager.getDevices(GET_DEVICES_OUTPUTS), by AudioDeviceInfo type.android::outputIsPrivate · android_app.h:178 - fn
inline bool systemInsets(int* left, int* top, int* right, int* bottom)The system bars and the display cutout over the window, in device pixels: WindowInsets from the decor view (getInsets(systemBars | displayCutout) from Android 11, the system-window insets before). False, all zero, when the view has none yet.android::systemInsets · android_app.h:229 - fn
inline void keepScreenOn(ANativeActivity* activity)Keep the screen on while the app is in front: an instrument being played should not go dark between notes. Window.addFlags(FLAG_KEEP_SCREEN_ON).android::keepScreenOn · android_app.h:298 - fn
inline ActivityState& state()android::state · android_app.h:316 - fn
inline int onInputReady(int, int, void*)android::onInputReady · android_app.h:323 - fn
inline int onFrame(int fd, int, void*)android::onFrame · android_app.h:337 - fn
inline int onMessages(int, int, void*)android::onMessages · android_app.h:347 - fn
inline void setFrameClock(bool running)Run the surface's clock at ~60 Hz while visible, and stop it otherwise.android::setFrameClock · android_app.h:353 - fn
inline void windowChanged()android::windowChanged · android_app.h:364 - fn
inline void onStart(ANativeActivity*)The NativeActivity callbacks, every one on the main thread.android::onStart · android_app.h:376 - fn
inline void onResume(ANativeActivity*)android::onResume · android_app.h:382 - fn
inline void onPause(ANativeActivity*)android::onPause · android_app.h:385 - fn
inline void onStop(ANativeActivity*)android::onStop · android_app.h:388 - fn
inline void onWindowCreated(ANativeActivity*, ANativeWindow* window)android::onWindowCreated · android_app.h:394 - fn
inline void onWindowResized(ANativeActivity*, ANativeWindow*)android::onWindowResized · android_app.h:398 - fn
inline void onWindowRedrawNeeded(ANativeActivity*, ANativeWindow*)android::onWindowRedrawNeeded · android_app.h:399 - fn
inline void onContentRectChanged(ANativeActivity*, const ARect*)The bars appeared, went or moved: the editor follows the free area.android::onContentRectChanged · android_app.h:404 - fn
inline void onWindowDestroyed(ANativeActivity*, ANativeWindow*)android::onWindowDestroyed · android_app.h:407 - fn
inline void onInputQueueCreated(ANativeActivity*, AInputQueue* queue)android::onInputQueueCreated · android_app.h:413 - fn
inline void onInputQueueDestroyed(ANativeActivity*, AInputQueue* queue)android::onInputQueueDestroyed · android_app.h:418 - fn
inline void onConfigurationChanged(ANativeActivity* activity)android::onConfigurationChanged · android_app.h:422 - fn
inline void onDestroy(ANativeActivity*)android::onDestroy · android_app.h:428 - fn
inline void run(ANativeActivity* activity, ActivityHooks* hooks)Wire an activity toandroid::run · android_app.h:449hooks(taken over: deleted when the activity ends).