This directory contains the Android-specific code for building xscreensaver. It is very much a work in progress. If you're messing with this, please let us know: dennis@panaceasupplies.com jwz@jwz.org ############################################################################ # # To set up your Android development environment: # ############################################################################ Install JDK: https://www.oracle.com/java/technologies/downloads/ You might need to nuke the old ones first: rm -r /Library/Java/JavaVirtualMachines/* Install Android Studio: http://developer.android.com/sdk/ Install Android NDK: http://developer.android.com/ndk/downloads Rename or link the "android-ndk-*" directory to "ndk" inside your $ANDROID_HOME (the "sdk/" directory that is the parent of "build-tools/", etc.) That is, it should be "sdk/ndk/". Update 2023: these seem to be DMGs now? Sigh. Mount it and then do: cp -pr /Volumes/Android\ NDK\ r25c/AndroidNDK*.app/Contents/NDK \ ~/Library/Android/sdk/android-ndk-r25c ln -sf sdk/ndk/ndk-build . cd sdk ; ln -sf android-ndk-r* ndk Delete any old NDKs or they get used anyway. Set $ANDROID_HOME to where your SDK is installed, or set "sdk.dir" in the file local.properties. On MacOS, the value you want is probably ~/Library/Android/sdk/ Also set "ndk.dir" in local.properties. Install ImageMagick ("convert"). On an M1 Mac, you might also need to do this to make the emulator work: ln -s darwin-aarch64 ~/Library/Android/sdk/emulator/qemu/darwin-x86_64 ############################################################################ # # To build: # ############################################################################ ./configure cd android make Hopefully an "xscreensaver-debug.apk" file will appear in android/xscreensaver/build/outputs/apk/. Load that onto your device and go to: Settings / Display / Daydream or maybe it's now called Settings / Display / Advanced / Screen saver or just click on the XScreenSaver icon, which is a shortcut to that. To create and configure an emulator image, use the GUI tool and and give the emulator a name (say, "Nexus_5"). View / Tool Windows / Device Manager E.g.: Nexus 5, Android 5, Intel Atom x86_64, RAM 2048 VM 64, storage 200, use host GPU. This used to work but no longer does: $ANDROID_HOME/sdk/tools/android avd Configuration options are in $HOME/.android/avd/*.avd/config.ini To launch it: $ANDROID_HOME/sdk/emulator/emulator -avd Nexus_5 To load xscreensaver into the currently-running emulator or device: $ANDROID_HOME/platform-tools/adb install -r \ xscreensaver/build/outputs/apk/xscreensaver-debug.apk Extremely verbose log output, including stack traces: $ANDROID_HOME/platform-tools/adb logcat Non-fatal log output for only this app: $ANDROID_HOME/platform-tools/adb logcat \ -s xscreensaver:d AndroidRuntime:d libEGL:d Note that sometimes "logcat" will just sit there forever saying "waiting for device". This is because the emulator is a piece of shit and sometimes decides to just randomly not service connections. If you restart the emulator, and wait minutes for the whole damned thing to boot up again, it will probably work next time. Probably. WTF is Gradle? "gradle" is a yet another re-invention of "make" that is written in Java, because we needed that like another hole in the head. The actual gradle app is bundled here, in a .jar file. "gradlew" is an sh script that tries to figure out how to invoke Java to run gradle properly. There are identical copies of gradle and gradlew in both "android/" and in "android/xscreensaver/". I don't know why. The latest Gradle requires Java 11. Because why wouldn't it, a build system needs the bleeding edge, right? That's totally normal. To download Java from Oracle, they want you to make an account and verify your email address, but if you don't want to go through that nonsense (because fuck those guys) you can find a mirror of it at https://www.techspot.com/downloads/5553-java-jdk.html -- but make sure that you verify that download with "shasum -a 256" against https://www.oracle.com/webfolder/s/digest/11-0-10-checksum.html so that you don't get a trojan. Not all versions of Gradle work with all versions of Java because of course they don't. Here's a table listing compatible versions: https://docs.gradle.org/current/userguide/compatibility.html ############################################################################ # # Directory structure: # ############################################################################ Boilerplate for the Java version of "make": *gradle* *.properties xscreensaver/*gradle* xscreensaver/build.* xscreensaver/*.properties The other half of the Makefile: xscreensaver/jni/*.mk Source code: xscreensaver/src/org/jwz/xscreensaver/*.java xscreensaver/res/layout/*.xml Other relevant source code is in ../jwxyz/ and ../hacks/. Icons: xscreensaver/res/drawable-ldpi/ xscreensaver/res/drawable-mdpi/ xscreensaver/res/drawable/ Fonts: xscreensaver/assets/fonts/ Files that we generate: Most of the XML is generated by ../hacks/check-configs.pl gen/function-table.h xscreensaver/AndroidManifest.xml xscreensaver/res/drawable/*.png (except for thumbnail.png) xscreensaver/res/values/settings.xml xscreensaver/res/values/strings.xml xscreensaver/res/xml/*.xml xscreensaver/src/org/jwz/xscreensaver/gen/*.java Other files generated as a part of the build process: build/ gen/ .gradle/ xscreensaver/build/ xscreensaver/build/outputs/apk/ -- app appears here xscreensaver/jni/ xscreensaver/libs/ xscreensaver/obj/ xscreensaver/res/ xscreensaver/res/drawable/ xscreensaver/res/values/ xscreensaver/res/xml/ xscreensaver/src/org/jwz/xscreensaver/gen/ When adding a new hack, edit android/Makefile, then "make clean" and "make". ############################################################################ # # TODO list -- known bugs # # We could really use some help with these! # ############################################################################ - Rotation is wonky (on some devices?) - When a saver exits abnormally, we catch the exception and attempt to display the error message in a dialog. The catch works, but the dialog box does not. - There are lots of deprecation warnings about these, and I don't know what to do about it: - android.preference.* - MediaColumns.DATA - MediaStore.Images.Media.getBitmap - Rendering text into pixmaps doesn't work. Affects: - apple2 - bsod - fontglide - phosphor - Rendering text into textures doesn't work. Possible causes include: the pixmap problem, above; and that retrieving the GL_TEXTURE_MATRIX seems to not work. Affects: Any hack that uses print_texture_label: - FPS displays on every OpenGL hack - engine (engine names) - geodesicgears (number of teeth) - glslideshow (file names) - glsnake (shape names) - juggler3d (pattern names) - molecule (descriptions) - pinion (number of teeth) - polyhedra (object descriptions) - spheremonics (object descriptions) - tangram (object descriptions) - unicrud (character descriptions) Any hack that uses print_texture_string: - carousel (file names) - circuit (labels on components) - esper (coordinates and file names) - fliptext (the whole thing) - geodesicgears (gear numbers) - gibson (text on the towers) - jigsaw (loading message) - molecule (atom names) - photopile (file names) - sonar (everything) - starwars (everything) - unicrud (everything) - winduprobot (word bubbles) Interestingly, splitflap uses print_texture_string successfully, so that bears investigation. - Retrieving GL_MODELVIEW_MATRIX doesn't seem to work. Affects: - discoball (back faces not masked out, billboarded lights) - energystream -- blank in emulator, works on real devices? - glsnake -- blank in emulator, works on real devices? - molecule (billboarded atom labels) - raverhoop -- blank in emulator, works on real devices? - starwars (blank) - winduprobot (billboarded word bubbles) - Pixmap masks don't work. Affects: - barcode -- fails in emulator, works on real devices? - bsod (logos and such) - noseguy (character display as rectangle) - pacman (characters display as rectangles) - polyominoes (can't texture the objects) - spotlight (everything) Dave says: jwxyz_blit() just needs a GCFunction parameter that swaps out that memmove() when it's not GXcopy. I think xscreensaver_logo() is the only thing that needs GC functions under jwxyz-image.c, and that doesn't need fancy blending like jwxyz.m provides, so for instance GXxor could be implemented as `a ^ b` instead of `abs(a - b)`. - Complex polygon fills (XFillPolygon) are not implemented. Affects: - pedal - qix - speedmine - starfish - The code that attempts to grab a screen shot before the Daydream begins doesn't work. Affects every image-loading hack that wants to manipulate the "desktop". - Alpha blending of GL objects doesn't seem to work. Affects: - beats (blur isn't transparent) - molecule (shells are not transparent) - winduprobot (dome is not transparent) - Weird outliers: - kumppa and slip are special-cased to use jwxyz-gl instead of jwxyz-image because otherwise they are too slow, as they do tons of XCopyArea. and OpenGL ES 1.1 doesn't have glCopyPixels or glBlitFramebuffer. - petri is similar, except with tons of XFillRectangle, which, at two triangles each, is a lot of geometry. - Undiagnosed problems: - antinspect has some kind of masking problem. Maybe only in emulator? - cityflow colors and shading are all wrong. - discoball doesn't draw rays. - endgame is insanely slow. - esper images display as black. - glblur is grayscale instead of color. Endian or packing problem? - queens is insanely slow. - sonar doesn't display properly, but once it does, test icmp. - xmatrix is pretty slow. ############################################################################ # # Releasing (this is for my benefit) # ############################################################################ Everything moves around every 6 months, so listing URLs here would be foolish. - Search for "Google play developer console". - When that doesn't work search for "play console" "create a release". - The button is in the upper right, lately. - You might need to use Chrome instead of Safari. - Drag and drop the APK. - Next Google will complain that "Your app currently targets API level N". - Android Studio / Tools / SDK Mananger - SDK Platforms - install the latest released ("R"), note API Level, Rev. - SDK Tools - Show Details, install latest "SDK Build Tools", note version. - Edit xscreensaver/build.gradle, change "compileSdkVersion" and "buildToolsVersion" and "targetSdkVersion" - Also install latest "NDK Side by Side" - Next Android Studio will complain that Gradle is too old. Update it. - "make clean" and note the error that says something like: "Minimum supported Gradle version [...] to gradle-N.N.N-WHAT.zip" - Edit gradle/wrapper/gradle-wrapper.properties and change "distributionUrl" to end with that. - Might need to re-download the NDK and re-create the symlink ~/Library/Android/sdk/ndk Are there now multiple copies of the same version installed? I can't tell. - Delete any old NDKs in ~/Library/Android/sdk/ or they might get picked instead of the newer ones.