Emacs and Android
*****************

Android is a mobile operating system developed by the Open Handset Alliance.  This section describes the peculiarities of using Emacs on an Android device running Android 2.2 or later.

Android devices commonly rely on user input through a touch screen or digitizer device and on-screen keyboard.  For more information about using such devices with Emacs, see Other Input Devices.

Android history
===============

Android is an operating system for mobile devices developed by the Open Handset Alliance, a group of companies interested in developing handsets that can run a common set of software.  It is supposedly free software.

Like the X Consortium of times past, the Open Handset Alliance believes that ``openness'' (namely, the regular release of the Android source code) is simply a tool to increase the popularity of the Android platform.  Computer companies normally produce proprietary software.  The companies in the Open Handset Alliance are no different -- most versions of Android installed on devices are proprietary, by virtue of containing proprietary components, that often cannot even be replaced by the user.

Android is not designed to respect users' freedom.  Almost all versions of Android (including some which are supposedly free software) include support for Digital Restrictions Management, technology that is designed to limit users' ability to copy media to and from their own devices.  Most Android devices also come with proprietary Google applications which are required to run the system, and many other Android applications.

Thus, it must be necessary to consider Android proprietary software from a practical standpoint.  That is an injustice.  If you use Android, we urge you to switch to a free operating system, if only for your freedom's sake.

We support GNU Emacs on proprietary operating systems because we hope this taste of freedom will inspire users to escape from them.

Starting up Emacs on Android
============================

Emacs is not installed on Android devices from source code, or by a package manager.  Instead, Emacs is compiled for Android on a different operating system, with the resulting binaries packaged into an archive, that is then transferred to the device and unpacked.

After being unpacked, Emacs instructs the system to display an application icon on the desktop.  Emacs then starts up once the application icon is clicked.

During startup, Emacs will display messages in the system log buffer; reading that buffer requires the Android Debug Bridge (adb) utility to be installed on another computer; it cannot be read on the computer running Android itself.

After enabling the ``USB Debugging'' feature on the Android system, and connecting it via USB to another system with the adb utility installed, the log can be viewed by running the following command on that other system:

     $ adb logcat | grep -E "(android_run_debug_thread|[Ee]macs)"

Since there is no other way to start the emacsclient program (see Emacs Server) from another Android program, Emacs provides a wrapper around the emacsclient program, which is registered with the system as an application that can open all text files.

When that wrapper is selected as the program with which to open a file, it invokes emacsclient with the options --reuse-frame, --timeout=10, --no-wait, and the name of the file being opened.  Then, upon success, the focus is transferred to any open Emacs frame.

It is sadly impossible to open certain kinds of files which are provided by a ``content provider''.  When that is the case, a dialog is displayed with an explanation of the error.

What files Emacs can access under Android
=========================================

Emacs exposes a special directory on Android systems: the name of the directory is /assets, and it contains the etc, lisp and info directories which are normally installed in /usr/share/emacs directory on GNU and Unix systems.  On Android systems, the Lisp emulation of ls (see ls in Lisp) is also enabled by default, as the ls binary which comes with the system varies by manufacturer and usually does not support all of the features required by Emacs.  One copy of ls shipped with some Android devices is even known to lack support for the -l flag.

This directory exists because Android does not extract the contents of application packages on to the file system while unpacking them, but instead requires programs like Emacs to access its contents using a special ``asset manager'' interface.  Here are the peculiarities that result from such an implementation:

  * Subprocesses (such as ls) can not run from the /assets directory.

  * There are no . and .. directories inside the /assets directory.

  * Files in the /assets directory are always read only, and have to be completely read in to memory each time they are opened.

Aside from the /assets directory, Android programs normally have access to three other directories.  They are:

  * The app data directory.  This also serves as the home directory for Emacs, and is always accessible read-write.

  * The app library directory.  This is automatically appended to exec-path upon startup.

  * The external storage directory.  This is accessible to Emacs when the user grants the ``Files and Media'' permission to Emacs via system settings.

The external storage directory is found at /sdcard; the other directories are not found at any fixed location.

On Android 11 and later, the Android system restricts applications from accessing files in the /sdcard directory using file-related system calls such as open and readdir.

This restriction is known as ``Scoped Storage'', and supposedly makes the system more secure.  Unfortunately, it also means that Emacs cannot access files in those directories, despite holding the necessary permissions.  Thankfully, the Open Handset Alliance's version of Android allows this restriction to be disabled on a per-program basis; the corresponding option in the system settings panel is:

     System -> Apps -> Special App Access -> All files access -> Emacs

After you disable or enable this setting as appropriate and grant Emacs the ``Files and Media'' permission, it will be able to access files under /sdcard as usual.

These settings are not present on many proprietary versions of Android.

Running Emacs under Android
===========================

From the perspective of users, Android is mostly a single user operating system; however, from the perspective of applications and Emacs, the system has an overwhelming number of users.

Each application runs in its own user, with his own home directory, which is the app data directory (see Android File System.)

Each application is also prohibited from accessing system directories, and the app data directories of other applications.  In recent versions of Android, the system also prohibits, for security reasons, even Emacs itself from running executables inside the app data directory.

Emacs comes with several binaries.  While being executable files, they are packaged as libraries in the library directory, because otherwise the system will not unpack them while Emacs is being installed.  This means, instead of specifying ctags or emacsclient in a subprocess, Lisp code must specify libctags.so or libemacsclient.so on the commnd line instead when starting either of those programs in a subprocess.

The /assets directory containing Emacs start-up files is supposed to be inaccessible to processes not directly created by zygote, the system service responsible for starting applications.  Since required Lisp is found in the /assets directory, it would thus follow that it is not possible for Emacs to start itself as a subprocess.  A special binary named libandroid-emacs.so is provided with Emacs, and does its best to start Emacs, for the purpose of running Lisp in batch mode. However, the approach it takes was devised by reading Android source code, and is not sanctioned by the Android compatibility definition documents, so your mileage may vary.

Running Emacs in the background
===============================

Application processes are treated as disposable entities by the system.  When all Emacs frames move to the background, Emacs is liable to be killed by the system at any time, for the purpose of saving system resources.

On Android 7.1 and earlier, Emacs tells the system to treat it as a ``background service''.  The system will try to avoid killing Emacs unless the device is under memory stress.

Android 8.0 removed the ability for background services to receive such special treatment.  However, Emacs applies a workaround: the system considers applications that create a permanent notification to be performing active work, and will avoid killing such applications. Thus, on those systems, Emacs displays a permanant notification for as long as it is running.  Once the notification is displayed, it can be safely hidden through the system settings without resulting in Emacs being killed.

However, it is not guaranteed that the system will not kill Emacs, even if the notification is being displayed.  While the Open Handset Alliance's sample implementation of Android behaves correctly, many manufacturers place additional restrictions on program execution in the background in their proprietary versions of Android.  There is a list of such troublesome manufacturers and sometimes workarounds, at https://dontkillmyapp.com/.

Android permissions
===================

Android also defines a permissions system that determines what system services Emacs is allowed to access.  Programs must specify what permissions they want; what then happens depends on the version of Android being used:

  * On Android 5.1 and earlier, Emacs automatically receives the following permissions it has requested upon being installed:

       - android.permission.READ_CONTACTS

       - android.permission.WRITE_CONTACTS

       - android.permission.VIBRATE

       - android.permission.ACCESS_COARSE_LOCATION

       - android.permission.ACCESS_NETWORK_STATE

       - android.permission.INTERNET

       - android.permission.SET_WALLPAPER

       - android.permission.WRITE_EXTERNAL_STORAGE

       - android.permission.SEND_SMS

       - android.permission.RECEIVE_SMS

       - android.permission.RECEIVE_MMS

       - android.permission.WRITE_SMS

       - android.permission.READ_SMS

       - android.permission.NFC

       - android.permission.TRANSMIT_IR

       - android.permission.READ_PHONE_STATE

       - android.permission.WAKE_LOCK

       - android.permission.FOREGROUND_SEVICE

       - android.permission.REQUEST_INSTALL_PACKAGES

       - android.permission.REQUEST_DELETE_PACKAGES

       - android.permission.SYSTEM_ALERT_WINDOW

       - android.permission.RECORD_AUDIO

       - android.permission.CAMERA

     While most of these permissions are left unused by Emacs itself, they are declared by Emacs as they could be useful for other programs; for example, the permission to access contacts may be useful for EUDC.

  * On Android 6.0 and later, Emacs only receives the following permissions upon installation:

       - android.permission.VIBRATE

       - android.permission.ACCESS_NETWORK_STATE

       - android.permission.INTERNET

       - android.permission.SET_WALLPAPER

       - android.permission.NFC

       - android.permission.TRANSMIT_IR

       - android.permission.WAKE_LOCK

       - android.permission.POST_NOTIFICATIONS

     Other permissions must be granted by the user through the system settings application.  Consult the manufacturer of your device for more details, as how to do this varies by device.

The Android window system
=========================

Android has an unusual window system; there, all windows are maximized or full-screen, and only one window can be displayed at a time.  On larger devices, the system allows up to four windows to be tiled on the screen at any time.

Windows on Android do not continue to exist indefinitely after they are created.  Instead, the system may choose to terminate windows that are not on screen in order to save memory, with the assumption that the program will save its contents to disk and restore them later, when the user asks to open it again.  As this is obvious not possible with Emacs, Emacs separates a frame from a system window.

Each system window created (including the initial window created during Emacs startup) is appended to a list of windows that do not have associated frames.  When a frame is created, Emacs looks up any window within that list, and displays the contents of the frame within; if there is no window at all, then one is created.  Likewise, when a new window is created by the system, Emacs places the contents of any frame that is not already displayed within a window inside. When a frame is closed, the corresponding system window is also closed.  Upon startup, the system creates a window itself (within which Emacs displays the first window system frame shortly thereafter.)  Emacs differentiates between that window and windows created on behalf of other frames to determine what to do when the system window associated with a frame is closed:

  * When the system closes the window created during application startup in order to save memory, Emacs retains the frame for when that window is created later.

  * When the user closes the window created during application startup, and the window was not previously closed by the system in order to save resources, Emacs deletes any frame displayed within that window.

  * When the user or the system closes any window created by Emacs on behalf of a specific frame, Emacs deletes the frame displayed within that window.

Due to the unusual nature of the Android windowing environment, Emacs only supports a limited subset of GUI features.  Here is a list of known limitations, and features which are not implemented:

  * Scroll bars are not supported, as they are close to useless on Android devices.

  * The alpha, alpha-background, z-group, override-redirect, mouse-color, cursor-color, cursor-type, title, wait-for-wm, sticky, undecorated and tool-bar-position frame parameters (see Frame Parameters (the Emacs Lisp Reference Manual)) are unsupported.

  * The fullscreen frame parameter is always maximized for top-level frames.

Emacs does not implement all selection related features supported under the X Window System on Android.  For example, only the CLIPBOARD and PRIMARY selections (see Cut and Paste) are supported, and plain text is the only supported data type.

In addition, the Android system itself places certain restrictions on what selection data Emacs can access:

  * On Android 2.3 and earlier, the function gui-selection-owner-p always returns nil for the clipboard selection.

  * On Android 3.0 and later, Emacs can only access clipboard data when one of its frames has the input focus.

Since the Android system itself has no concept of a primary selection, Emacs provides an emulation instead.  This means there is no way to transfer the contents of the primary selection to another application via cut-and-paste.

Font backends and selection under Android
=========================================

Emacs supports two font backends under Android: they are respectively named sfnt-android and android.

Upon startup, Emacs enumerates all the TrueType format fonts in the directory /system/fonts, and the fonts directory inside the Emacs home directory.  Emacs assumes there will always be a font named ``Droid Sans Mono'', and then defaults to using this font. These fonts are then displayed by the sfnt-android font driver.

When running on Android, Emacs currently lacks support for OpenType fonts.  This means that only a subset of the fonts installed on the system are currently available to Emacs.  If you are interested in lifting this limitation, please contact emacs-devel@gnu.org.

If the sfnt-android font driver fails to find any fonts at all, Emacs falls back to the android font driver.  This is a very lousy font driver, because of limitations and inaccuracies in the font metrics provided by the Android platform.  In that case, Emacs uses the ``Monospace'' typeface configured on your system; this should always be Droid Sans Mono.

What to do when something goes wrong on Android
===============================================

Since Android has no command line, there is normally no way to specify command-line arguments when starting Emacs.  This is very nasty when you make a mistake in your Emacs initialization files that prevents Emacs from starting up at all, as the system normally prevents other programs from accessing Emacs's home directory.

However, Emacs can be started with the equivalent of the --quick option (see Initial Options) through a special preferences screen, which can be accessed through the Emacs ``app info'' page in the system settings application.

Consult the manufacturer of your device for more details, as how to do this varies by device.

The first time any given copy of Emacs starts on a device, it spends a while loading the preloaded Lisp files which normally come with Emacs.  This produces a ``dump file'' (see Initial Options) in the files directory, containing an identifier unique to this copy of Emacs.

The next time that same copy of Emacs starts up, it simply loads the data contained in that dump file, greatly improving start up time.

If by some unforseen circumstance the dump file is corrupted, Emacs can crash.  If that happens, the dump file stored in the Emacs files directory can be erased through the same preferences screen.

Emacs supports an alternative method of rescuing broken Emacs installations on Android 4.4 and later: Emacs exports a ``documents provider'' which accesses the contents of Emacs's home directory, that can then be accessed by any file manager program.

If you can find out how to open that documents provider in the file manager that comes with your device, you can rename, delete, or edit your initialization or dump files from there instead.