nix-community / nix-on-droid

Nix-enabled environment for your Android device. [maintainers=@t184256,@Gerschtli]
https://nix-on-droid.unboiled.info
MIT License
1.29k stars 72 forks source link

Termux-clipboard-{get,set} in termux.nix? #133

Open mhuesch opened 3 years ago

mhuesch commented 3 years ago

https://wiki.termux.com/wiki/Termux-clipboard-set https://wiki.termux.com/wiki/Termux-clipboard-get

would it be possible or easy to wrap these Termux commands? they'd be pretty handy for unifying some of my copy/paste workflows between desktop and Android.

I haven't had time to look into their implementation but can if nobody knows...

573 commented 2 years ago

+1

Would also be interested in this. https://github.com/termux/termux-app/issues/899

Also: https://github.com/t184256/nix-on-droid/issues/56 Also:

You can try and play around with the am script available in standard termux installation.

$ cat /data/data/com.termux/files/usr/bin/am
#!/data/data/com.termux/files/usr/bin/sh
export CLASSPATH=/data/data/com.termux/files/usr/libexec/termux-am/am.apk
unset LD_LIBRARY_PATH LD_PRELOAD
exec /system/bin/app_process / com.example.termuxam.Am "$@"

But it seems to rely on the apk to be available anywhere..

Originally posted by @Gerschtli in https://github.com/t184256/nix-on-droid/issues/118#issuecomment-864214444

573 commented 2 years ago

By contemplating about packaging this I found also this and built the latter in nix-on-droid, also installing the Termux:API apk.

Still getting a No such file (...) error though.

Gerschtli commented 2 years ago

The linked termux-clipboard project needs the termux sdk to be available. How did you install termux-clipboard-get/-set commands? Did not search for the source code, maybe there are some inpure dependencies that you need to fix.

573 commented 2 years ago

@Gerschtli I did not yet install the scripts as I could not figure out how. Just the android app, not sufficient.

Gerschtli commented 2 years ago

Without these scripts it will not work. There was not any effort to port these scripts to nix-on-droid yet. I did not have a look at how these scripts are built. Any input would be helpful, because I do not have a lot of time currently.

573 commented 2 years ago

https://github.com/termux/termux-api-package is a cmake project so it should be doable for anyone interested.

Following https://nixos.wiki/wiki/Cheatsheet#Reuse_a_package_as_a_build_environment I fetched the source locally and with default.nix listed there in the wiki started a nix-shell etc.

Running make resulted in:

termux-api-package/termux-api.c:11:10: fatal error: sys/endian.h: No such file or directory 11 | #include <sys/endian.h> | ^~~~~~ compilation terminated. make[2]: [CMakeFiles/termux-api.dir/build.make:76: CMakeFiles/termux-api.dir/termux-api.c.o] Error 1 make[1]: [CMakeFiles/Makefile2:85: CMakeFiles/termux-api.dir/all] Error 2 make: *** [Makefile:136: all] Error 2

EDIT: Error is all the same ~Guess I have to repeat on android device.~

Can I specify something like system = "aarch64-linux-android"; ?

For later ref.
For later ref. endian.h from android ndk seems to be needed. For later ref. has ndk-bundle For later ref. For later ref. For later ref.

573 commented 2 years ago

Must have a fundamental misconception here as endian.h is still not found even with ndk-bundle in buildInputs.

Julow commented 2 years ago

Hi,

I haven't looked at that since half a year but in my opinion, the endian.h problem is just an arbitrary difference between Termux and the NDK (which has a lot of such uncommon things) and isn't more than that.

I stopped at this state:

I can build termux-api, some termux tools and the am command with the nix expression below. The am command don't work however:

Could not connect to socket: No such file or directory

This suggests me that nix-on-droid (the app) needs to create and watch this socket and that the proot setup needs to mount it.

{ pkgs ? import <nixpkgs> {} }:

let
  TERMUX_PREFIX = builtins.getEnv "PREFIX";
  TERMUX_HOME = builtins.getEnv "HOME";

  # Tweak due to difference between Android NDK and Gnu
  termux_patch_include_endian =
    builtins.toFile "endian-patch.patch" ''
      diff --git a/CMakeLists.txt b/CMakeLists.txt
      index 004e509..0ac05a5 100644
      --- a/CMakeLists.txt
      +++ b/CMakeLists.txt
      @@ -9,6 +9,8 @@ add_library(termux-api SHARED termux-api.c)
       add_executable(termux-api-broadcast termux-api-broadcast.c)
       target_link_libraries(termux-api-broadcast termux-api)

      +set(CMAKE_C_FLAGS "''${CMAKE_C_FLAGS} -lbsd -lpthread")
      +
       # TODO: get list through regex or similar
       set(script_files
         scripts/termux-api-start
      diff --git a/termux-api.c b/termux-api.c
      index d6d8b5b..c07214f 100644
      --- a/termux-api.c
      +++ b/termux-api.c
      @@ -8,13 +8,14 @@
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
      -#include <sys/endian.h>
       #include <sys/socket.h>
       #include <sys/stat.h>
       #include <sys/types.h>
       #include <sys/un.h>
       #include <time.h>
       #include <unistd.h>
      +#include <bsd/stdlib.h> // arc4random
      +#include <arpa/inet.h> // htons

       #include "termux-api.h"

    '';

  termux-api =
    pkgs.stdenv.mkDerivation rec {
      pname = "termux-api";
      version = "v0.57";
      src = pkgs.fetchgit {
        url = "https://github.com/termux/termux-api-package";
        rev = version;
        sha256 = "1x9h67f6zbpq3yvz7mzsi0x898ak24kdk0fcrqa0xzjsbaqalc7y";
      };
      buildInputs = with pkgs; [ cmake libbsd ];
      patches = [ termux_patch_include_endian ];
      # Fix the shebangs
      preConfigure = ''
        for s in scripts/* termux-callback.in; do
          sed -i '1c#!${pkgs.runtimeShell}' "$s"
        done
      '';
    };

  termux-am-socket =
    pkgs.stdenv.mkDerivation rec {
      pname = "termux-am-socket";
      version = "1.01";
      src = pkgs.fetchgit {
        url = "https://github.com/termux/termux-am-socket";
        rev = version;
        sha256 = "1jbckqqrwz04q5hcwfpqwk3zba6n6igbxqy0n5b4f8z8af361ijd";
      };
      buildInputs = with pkgs; [ cmake ];
      inherit TERMUX_HOME;
    };

  am =
    pkgs.linkFarm "am" [
      { name = "bin/am"; path = "${termux-am-socket}/bin/termux-am"; }
    ];

  termux-packages_src =
    pkgs.fetchgit {
      url = "https://github.com/termux/termux-packages";
      rev = "bootstrap-2022.01.02-r1";
      sha256 = "0i85awzswd4n5mj0w47564igzh0jn5apmi1kwygnff86q09ydrag";
    };

  termux-tools =
    # Tools not installed:
    #   chsh login motd motd-playstore pkg su termux-change-repo termux-info
    #   termux-backup termux-restore termux-fix-shebang termux-reset
    pkgs.stdenv.mkDerivation rec {
      name = "termux-tools";
      src = termux-packages_src;
      propagatedBuildInputs = [ am ];
      phases = [ "unpackPhase" "installPhase" "fixupPhase" ];
      installPhase = ''
        for tool in \
          dalvikvm termux-open termux-open-url termux-reload-settings \
          termux-wake-lock termux-wake-unlock termux-setup-storage
        do
          out_tool=$out/bin/$tool
          install -Dm700 "packages/termux-tools/$tool" "$out_tool"
          substituteInPlace "$out_tool" \
            --subst-var TERMUX_PREFIX \
            --subst-var TERMUX_HOME
        done
      '';
      inherit TERMUX_PREFIX TERMUX_HOME;
    };

in

[ termux-api termux-am-socket am termux-tools ]

Tbh, I think maintaining a whole app concurrent to Termux is a mistake because it is too much work. I'll try next to run the bootstrap archive into the stock Termux app. Advantages of ditching the nix-on-droid app are:

(sorry for the rant at the end)

573 commented 2 years ago

@Julow awesome, thanks for figuring this out.

bqv commented 1 year ago

how'd it go?

expenses commented 4 months ago

I've been trying to get termux-open working. There's an am socket at /data/data/com.termux.nix/files/apps/com.termux.nix/termux-am/am.sock so I'm trying to use that:

termux-am.nix

{ stdenv, cmake, linkFarm }:
stdenv.mkDerivation {
  name = "termux-am";
  src = fetchGit {
    url = "https://github.com/termux/termux-am-socket";
    rev = "1ac60a15c4fe52c47ed85090088525b8f317f503";
  };
  nativeBuildInputs = [ cmake ];
  patchPhase = ''
    # Header generation doesn't seem to work on android
    echo "#define SOCKET_PATH \"/data/data/com.termux.nix/files/apps/com.termux.nix/termux-am/am.sock\"" > termux-am.h
    # Fix the bash link so that nix can patch it
    sed -i 's/@TERMUX_PREFIX@//' termux-am.sh.in
  '';
  postInstall = ''
    # Scripts use 'am' as an alias.
    ln -s $out/bin/termux-am $out/bin/am
  '';
}

termux-tools.nix

{ stdenv, getopt, lib, makeWrapper, callPackage }:
stdenv.mkDerivation {
  name = "termux-tools";
  src = fetchGit {
    url = "https://github.com/termux/termux-tools";
    rev = "7ce7038cd4b9f6b24ec60b8178903e6da3bfbbda";
  };
  nativeBuildInputs = [ makeWrapper ];
  installPhase =
    let inputs = lib.makeBinPath [ getopt (callPackage ./termux-am.nix { }) ];
    in ''
      mkdir -p $out/bin $out/etc
      for script in scripts/termux-*.in; do
          install $script $out/etc/$(basename $script ".in")
          makeWrapper $out/etc/$(basename $script ".in") $out/bin/$(basename $script ".in") --prefix PATH : ${inputs}
      done
    '';
}

termux-open https://google.com now silently fails as opposed to noisily failing, which I suppose is better. Any help would be appreciated.

t184256 commented 4 months ago

There's an am socket at /data/data/com.termux.nix/files/apps/com.termux.nix/termux-am/am.sock

There's a what now? =O

t184256 commented 4 months ago
06-01 16:12:32.898 11823 11823 D Nix.TermuxAmSocketServer: Starting TermuxAm socket server since its enabled
06-01 16:12:32.899 11823 11823 D Nix.LocalSocketManager: TermuxAm Socket Server Run Config:
06-01 16:12:32.899 11823 11823 D Nix.LocalSocketManager: Path: `/data/data/com.termux.nix/files/apps/com.termux.nix/termux-am/am.sock`
06-01 16:12:32.899 11823 11823 D Nix.LocalSocketManager: LocalSocketManagerClient: `com.termux.shared.termux.shell.am.TermuxAmSocketServer$TermuxAmSocketServerClient`
06-01 16:12:32.901 11823 11823 D Nix.TermuxAmSocketServer: TermuxAm socket server successfully started

All this time I've been trying to invoke am from within proot, there has always been a server already running, specifically engineered for this specific use case?

t184256 commented 4 months ago

And, after "App Info -> Appear on top -> On" termux-am start -a com.android.settings.DISPLAY_SETTINGS worked.

t184256 commented 4 months ago

To answer your original question, our hero of the day @expenses, termux-open does an equivalent of am broadcast --user 0 -a android.intent.action.VIEW -n com.termux/com.termux.app.TermuxOpenReceiver -d <url>, with com.termux instead of com.termux.nix.

t184256 commented 4 months ago

... and we had this intent commented out, so it's time to turn it back on...

t184256 commented 4 months ago

Current progress:

https://nix-on-droid.unboiled.info/com.termux.nix_188035-TermuxOpen-Receiver.apk

https://nix-on-droid.unboiled.info/bootstrap-am

https://github.com/nix-community/nix-on-droid/tree/am

https://github.com/termux/termux-tools/pull/95

t184256 commented 4 months ago

9e516d3 - termux-open works with that patched apk. enough for today, but I'm excited for what could a working am bring.

expenses commented 3 months ago

9e516d3 - termux-open works with that patched apk. enough for today, but I'm excited for what could a working am bring.

Yep termux-open works well now! I don't think getting termux-api and https://github.com/termux/termux-api-package/blob/master/scripts/termux-clipboard-set.in working should be too hard.

t184256 commented 3 months ago

termux-api is a bunch of Java code that has to be added back to our apk; this requires a level of android expertise I do not possess =(

expenses commented 3 months ago

Ah, right, yeah. I just saw the C code. Unfortunately I don't have time to dig into this

expenses commented 2 months ago

@t184256 if you could be more specific in what Java code were talking about then I'm happy to attempt getting termux-api working

t184256 commented 2 months ago

This code: https://github.com/termux/termux-api

is missing from our fork of Termux: https://github.com/nix-community/nix-on-droid-app

expenses commented 2 months ago

Ah okay, nice, I was looking at the wrong repository. With https://github.com/tadfisher/gradle2nix/pull/62 we can build android apps deterministically with nix, so I'll try and come up with a nice flake for nix-on-droid that builds everything.

expenses commented 2 months ago

It might be easier to start by just having a separate Nix::API APK, although it would definitely be better to have the two bundled together. https://github.com/termux/termux-api/issues/194 might be a start at that.

Edit: https://stackoverflow.com/a/51623602

expenses commented 2 months ago

Okay, I've made a start at building a corresponding termux-api plugin for nix-on-droid-app here: https://github.com/expenses/nix-on-droid-app/tree/nix-termux-api. I added the repository as a submodule so that a simple ./gradlew build builds everything and so termux-shared can be shared between both easily. I haven't gotten it to receive anything yet though and I think the android manifest is slightly broken as the settings panel doesn't come up.