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

make TermuxService (com.termux.service_execute) available to other apps #804

Closed
torappinfo opened this issue Aug 10, 2018 · 25 comments
Closed

Comments

@torappinfo
Copy link

torappinfo commented Aug 10, 2018

So, any app can use the TermuxService execute.

Only minor changes in AndroidManifest.xml are needed:
```
< permission android:name="com.termux.app.TermuxService">
< /permission>

  <service android:name="com.termux.app.TermuxService" android:permission="com.termux.app.TermuxService">
      <intent-filter>
        <action android:name="com.termux.service_execute" />
      </intent-filter>
    </service>
@torappinfo torappinfo changed the title make TermuxService (com.termux.service_execute) available to other app make TermuxService (com.termux.service_execute) available to other apps Aug 10, 2018
@markosjal
Copy link

can you please clarify this? I am interested in executing streamlink which I have running in termux. I want to start the streamlink command from an android app

@ShadowJonathan
Copy link

All similar issues have been closed in favour of this one, yes, but has there been any progress or concidering since the opening of this particular issue, 6 months ago?

@ghost
Copy link

ghost commented Jan 27, 2019

any progress

Currently no, as we need to implement proper permission management so commands may be executed only by programs allowed by user.

Another thing that should be implemented is a way to access Termux files by third-party apps, again this will require implementing permissions.

@ghost ghost added the enhancement label Jan 27, 2019
@edaubert
Copy link

Hi,

I took a look on how to do this.
As I am quite new on this, the approach can be wrong so don't hesitate to tell me

My usecase was to be able to use the TermuxService from the outside and especially from Easer.
To do so, I change the definition of TermuxService in AndroidManifest.xml like this:

        <service
            android:name="com.termux.app.TermuxService"
            android:exported="true"
            android:permission="com.termux.permission.TERMUX_SERVICE">
            <intent-filter>
                <action android:name="com.termux.service_execute" />
            </intent-filter>
        </service>

It seems that the intent-filter is important because without it, there is no dialog to ask the user on Easer to allow the custom permission.

I also need to define my custom permission:

    <permission android:name="com.termux.permission.TERMUX_SERVICE"
        android:label="@string/termux_permission_label"
        android:description="@string/termux_permission_description"
        android:icon="@drawable/ic_launcher"
        android:protectionLevel="dangerous"/>

Then I modify Easer to be able to access Termux.
To do so, I express the requirement of my permission by adding:

    <uses-permission android:name="com.termux.permission.TERMUX_SERVICE" /> 

in AndroidManifest.xml and I add the dynamic permission request in the code of Easer:

    @Override
    public boolean checkPermissions(@NonNull Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return PluginHelper.checkPermission(context, "com.termux.permission.TERMUX_SERVICE");
        } else {
            return true;
        }
//        return true;
    }

    @Override
    public void requestPermissions(@NonNull Activity activity, int requestCode) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PluginHelper.requestPermission(activity, requestCode, "com.termux.permission.TERMUX_SERVICE");
        }
    }

Finally using run command plugin in Easer, I am able to run this following command:

am startservice --user 0 -a com.termux.service_execute -n com.termux/com.termux.app.TermuxService -d com.termux.file:/data/data/com.termux/files/home/.shortcuts/test

The test script should be available on .shortcuts directory.

What do you think about this approach ?

Changes are both available on https://github.com/edaubert/termux-app and https://github.com/edaubert/Easer if you want to try it. I can also provide a pull request if you are interested in. The changes in Termux are only about the AndroidManifest.xml and the string.xml to handle some translation.

@ghost
Copy link

ghost commented Feb 11, 2019

@edaubert Seems okay. Can you open a PR ?

@HarisHashim
Copy link

I really think that Idea in #302 is better and more secure. I.e. embed termux core or environment in another android app and then allow that Android App to execute Termux shell command.

It is cleaner and less security concern than what is attempted by #804.

It is also better to have this "embedded" Termux to operate as different environment than an installed Termux.

Just my $0.02. In case it is still possible to pivot to an "embeded termux" vs the idea in this thread!

@ghost
Copy link

ghost commented Mar 19, 2019

@HarisHashim Note that Termux environment requires specific executable path (/data/data/com.termux/files/usr). This cannot be changed without recompiling packages. Also no one (especially maintainers) want deal with 100500 patches and rewriting them on each package update.

@bdovaz
Copy link

bdovaz commented May 19, 2019

Ping. Any news?

@Ciantic
Copy link

Ciantic commented Jul 13, 2019

Wait, isn't this already possible? There are bunch of apps here that call termux scripts, e.g.

https://github.com/termux/termux-boot/blob/master/app/src/main/java/com/termux/boot/BootJobService.java

Calls a script during boot.

I haven't been able to redo that in my own app yet though. My use case would be to call certain script from my app, one would think this is basic thing for termux.

I'm trying with this code at the moment:

fun runTermuxScriptBackground(filePath: String, ctx: Context) {
    val scriptUri = Uri.Builder().scheme("com.termux.file").path(filePath).build()
    val intent = Intent("com.termux.service_execute", scriptUri)
    intent.setClassName("com.termux", "com.termux.app.TermuxService")
    intent.putExtra("com.termux.execute.background", true)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        ctx.startForegroundService(intent)
    } else {
        ctx.startService(intent)
    }
}

Not yet working though.

@ghost
Copy link

ghost commented Jul 13, 2019

Wait, isn't this already possible? There are bunch of apps here that call termux scripts, e.g.

From third-party apps no.
TermuxService isn't exported.

@AbdullahM0hamed
Copy link

AbdullahM0hamed commented Jul 13, 2019

@Ciantic, the README says:

note that this app needs to be signed with the same key as the main Termux app in order to have the permission to execute scripts, so it's probably only available to be used like this by termux add-ons, unless you build termux yourself, and sign it, then sign whatever app you want to be able to use the service with the same key.

@Ciantic
Copy link

Ciantic commented Jul 13, 2019

Oh bummer, have to wait for the PR.

I've made a nice job service myself I want to run with a script, really dying to use it :)

@gopikrishnanrmg
Copy link

Ping. Any development going on this? If not can you let me know what all I need to integrate from the core to be used in my own app.

@capi
Copy link

capi commented Feb 21, 2020

I'm aware that the main reason there is no "real progress" on this is due to permissions. Maybe this could be simplified by taking a similar approach as the termux-tasker add-on: Let third-party apps call scripts only in $HOME/.third-party-integration/com.thirdparty.apk/.

There could even be a list of directories to check, so that there could be an termux-side-package for any third-party app that wants to integrate + the possibility to add custom scripts for users. The calling APK would just specify the script's name (e.g. "myscript.sh") and TermuxService (or any other receiver) would check for:

  • /var/lib/third-party-integration/com.thirdparty.apk/myscript.sh
  • $HOME/.third-party-integration/com.thirdparty.apk/myscript.sh

The first file to be found would be executed. And there would be not much to worry about permissions, since the scripts could not be dropped in the correct location without the user actually doing that.

@gopikrishnanrmg
Copy link

gopikrishnanrmg commented Apr 20, 2020

Guys while you're at it, there is temporary workaround for this, as for my case I needed to run ipfs(it's an application) commands in my Android app and found that there is an ipfs package available on termux, I wanted to use termux to run the commands and return the results to my app, as it may seem complex, there is a simple solution for this, termux has nodejs package using it we can run a server in termux, which in turn can execute commands on termux using node-cmd package, put it all together and you get a server to which we can send commands from our Android app to execute on termux and the server returns the response back, which fulfills the requirement for the need of integrating the core in the first place,. I've seen that I can even open ports on Android using termux and use the ports in my Android app for communication (ipfs communication stuff which is my requirement, I haven't attached that part in the sample code below). I used this for my project.

You can see a sample code here for reference
https://github.com/gopikrishnanrmg/IPFS_Mobile_Test

@sudomain
Copy link

sudomain commented Jul 3, 2020

The changelog for v0.95 links here, but there's no actual info about how to do it here. This line of a commit sheds some light on the matter

@gopikrishnanrmg
Copy link

gopikrishnanrmg commented Jul 3, 2020 via email

@ghost
Copy link

ghost commented Jul 3, 2020

but there's no actual info about how to do it here.

On Termux side: set allow-external-apps=true in ~/.termux/termux.properties.

On Your App side:

  1. Declare usage of com.termux.permission.RUN_COMMAND permission in AndroidManifest.xml.
  2. Create code which starts a new Termux session. Minimal example with top:
    Intent intent = new Intent();
    intent.setClassName("com.termux", "com.termux.app.RunCommandService");
    intent.setAction("com.termux.RUN_COMMAND");
    intent.putExtra("com.termux.RUN_COMMAND_PATH", "/data/data/com.termux/files/usr/bin/top");
    startService(intent);
  3. Compile and install application.
  4. Give permission com.termux.permission.RUN_COMMAND through Android OS settings or with ADB.

Closing issue as feature is already implemented and v0.95 is released.

@iagows
Copy link

iagows commented Aug 16, 2020

If someone needs to do this without using intention, for any strange reason or just "_because I can", you can install node.js (pkg install nodejs), start a local server that receives the script and executes it. (exec)

Remember, this isn't secure.

@gopikrishnanrmg
Copy link

@iagows yeah, that's what I posted above

@mvuidev
Copy link

mvuidev commented Sep 21, 2020

but there's no actual info about how to do it here.

On Termux side: set allow-external-apps=true in ~/.termux/termux.properties.

On Your App side:

1. Declare usage of `com.termux.permission.RUN_COMMAND` permission in AndroidManifest.xml.

2. Create code which starts a new Termux session. Minimal example with `top`:
   ```java
   Intent intent = new Intent();
   intent.setClassName("com.termux", "com.termux.app.RunCommandService");
   intent.setAction("com.termux.RUN_COMMAND");
   intent.putExtra("com.termux.RUN_COMMAND_PATH", "/data/data/com.termux/files/usr/bin/top");
   startService(intent);
   ```

3. Compile and install application.

4. Give permission `com.termux.permission.RUN_COMMAND` through Android OS settings or with ADB.

Closing issue as feature is already implemented and v0.95 is released.

Thanks for the example, that works great.
But is it possible to run a custom .sh script file ?
Tried to set my custom script path in RUN_COMMAND_PATH but got an error :
exec("/data/data/com.termux/files/home/.scripts/script.sh") no such file or directory.

My script is executable and has the shebang #!$PREFIX/bin/bash

@Grimler91
Copy link
Member

My script is executable and has the shebang #!$PREFIX/bin/bash

Do you literally have $PREFIX in the shebang? environmental variables are (at least generally) not supported in shebangs (https://unix.stackexchange.com/questions/20880/how-can-i-use-environment-variables-in-my-shebang)

@mvuidev
Copy link

mvuidev commented Sep 21, 2020

@Grimler91 Hum, you're right. I used to test with the full path but i switched to $PREFIX for whatever reason...
Thank you for pointing this out.

Can confirm that it's working with the full shebang but i'm wondering :

  • With RUN_COMMAND_BACKGROUND true, everything is ok
  • With RUN_COMMAND_BACKGROUND false and termux is not running, it's not working (error in my app)
  • With RUN_COMMAND_BACKGROUND false and termux is running, it's working but termux doesn't launch itself automatically and when i open it, the session is empty (a simple echo "hello" doesn't return anything)

Maybe i'm missing something simple but is there a way to make termux open when i start the intent and view the result of my script ?

@Grimler91
Copy link
Member

Maybe i'm missing something simple but is there a way to make termux open when i start the intent and view the result of my script ?

There is a pending PR that will open the session automatically, there is a suggested workaround until it is merged and released in the first post of that PR (sleep 1; am start --user 0 -n com.termux/com.termux.app.TermuxActivity)

@mvuidev
Copy link

mvuidev commented Sep 21, 2020

Oh nice, i'll be waiting for the next release then.
Thank you !

bwachter pushed a commit to aardsoft/emacsbridge that referenced this issue Oct 20, 2020
Doing the support for this through a more generic intent caller makes
it possible to add support for calling intents from emacs or
QML. It'll also allow us to easily start emacs if needed, now that
support for calling external commands is merged in termux:

termux/termux-app#804

Currently the implementation is split between GUI and server parts -
it probably makes sense to split that off into an android crap helper
class eventually, callable from both sides.
@ghost ghost locked and limited conversation to collaborators Oct 17, 2021
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests