Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mhuesch opened this issue Sep 11, 2021 · 26 comments
Open

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

mhuesch opened this issue Sep 11, 2021 · 26 comments

Comments

@mhuesch
Copy link

mhuesch commented Sep 11, 2021

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
Copy link
Contributor

573 commented Nov 30, 2021

+1

Would also be interested in this.
termux/termux-app#899

Also:
#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 #118 (comment)

@573
Copy link
Contributor

573 commented Apr 29, 2022

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
Copy link
Collaborator

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
Copy link
Contributor

573 commented Apr 29, 2022

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

@Gerschtli
Copy link
Collaborator

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
Copy link
Contributor

573 commented Apr 29, 2022

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
Copy link
Contributor

573 commented Apr 30, 2022

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

@Julow
Copy link

Julow commented Jun 17, 2022

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:

  • Uptodate application (the 255 open, 1815 closed issues tell me it's a lot of work), which has regularly security issues fixed.
  • Faster am
  • Termux API and other addons
  • Better integration with the system (eg. with the file browser)

(sorry for the rant at the end)

@573
Copy link
Contributor

573 commented Jun 17, 2022

@Julow awesome, thanks for figuring this out.

@bqv
Copy link

bqv commented Feb 14, 2023

how'd it go?

@expenses
Copy link

expenses commented Jun 1, 2024

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
Copy link
Collaborator

t184256 commented Jun 1, 2024

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
Copy link
Collaborator

t184256 commented Jun 1, 2024

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
Copy link
Collaborator

t184256 commented Jun 1, 2024

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

@t184256
Copy link
Collaborator

t184256 commented Jun 1, 2024

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
Copy link
Collaborator

t184256 commented Jun 1, 2024

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

@t184256
Copy link
Collaborator

t184256 commented Jun 1, 2024

@t184256
Copy link
Collaborator

t184256 commented Jun 1, 2024

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

@t184256 t184256 mentioned this issue Jun 5, 2024
@expenses
Copy link

expenses commented Jun 8, 2024

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
Copy link
Collaborator

t184256 commented Jun 8, 2024 via email

@expenses
Copy link

expenses commented Jun 8, 2024

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

@expenses
Copy link

@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
Copy link
Collaborator

t184256 commented Jul 23, 2024 via email

@expenses
Copy link

Ah okay, nice, I was looking at the wrong repository. With tadfisher/gradle2nix#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
Copy link

expenses commented Aug 1, 2024

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. termux/termux-api#194 might be a start at that.

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

@expenses
Copy link

expenses commented Aug 3, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants