I am working on developing an Android native executable service which is launched by init(I register it in init.rc) when system boots up. This native executable creates a socket listening on 0.0.0.0:4615 and is supposed to accept connections from outside.
OS is Android K; it runs on a development kit which has Ethernet interface for plugging it onto a Lan.
I have done the test running the same native executable in adb shell as root. It works fine - an external socket client on my Windows machine can connect to the native executable and send/recv message successfully. When I have it launched by init, it listens to 0.0.0.0:4615 successfully, but the external socket client cannot connect to it - connection refused.
The snippet I added in init.rc is:
service msger-daemon /system/bin/msgerd
class main
When "ps" to check the user of msgerd, we found it was root.
Please help, thanks!
Solved by adding a SE policy file under $TOP/external/sepolicy, the content of that file is:
# File types must be defined for file_contexts.
type msgerd, domain;
type msgerd_exec, exec_type, file_type;
init_daemon_domain(msgerd)
permissive msgerd;
# Add msgerd to various domains
net_domain(msgerd)
allow msgerd self:capability { net_admin net_raw };
If anyone would like to review and advice, welcome!
Related
I use couple of Android apps on daily bases, and it's very time consuming.
I want to somehow automatize the process.
The idea is to install some sort of emulator on the server, and program that emulator through some programming language to run the apps on the server when its needed.
I'm a web developer, I work with PHP, nodejs, python,
not really familiar with mobile space.
Is there any solution out there to do what I want?
I search around and found Appium but I'm not sure if it would do what I want.
Please note these apps don't have a public 'api' for me to use.
Also I only have remote access to server via 'ssh terminal', so solutions with 'GUI' dependency wont work for me.
You can use some emulator, like Bluestacks and then run a script to run apps and then use macro tool to emulate clicks in the games or apps
check this link for the macro tool in bluestacks : https://www.bluestacks.com/blog/bluestacks-exclusives/combo-key-bluestacks-record-replay-action-single-key-en.html
Or you can write a script which uses adb commands to run and control the app.
For example.
to run apps. adb shell am start -n com.android.settings/.Settings
this command will open the settings app in the emulator.
to send touch events you can use : adb shell input touch <x> <Y>
adb shell input keyevent <keycode> to send keycodes
I'm assuming that you want to automate native Android apps.
Short answer: Appium will be good solution for you.
On your remote server you will need:
Android SDK and Simulator
Python 2.7 installed
Appium server/node (install using node.js npm )
With everything installed you will be able to start Appium Nodes on your server and run Appium scripts against them.
I suggest using CI server of choise for automating this process. It should make starting your test trough ssh terminal easier / 100% automated.
I never used Selenium/Appium in python, so I can't really help you with Appium tests code examples, but I'm sure there are a lot of basic tutorials for python.
You must install AppiumServer and android sdk/simulator in the remote server. I am going to show how it can be done in java. Hope you can convert it into javascript code.
Check the ip Address of your remote server using ipconfig
Start your appium server in the remote server
>appium -a "ip address of remote server" -p 4732 --session-override
Start the emulator in the remote server.
Define and initialize DesiredCapabilities and AppiumDriver in your code like following.
AppiumDriver<MobileElement> driver;
DesiredCapabilities caps= new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "android device");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
caps.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 300);
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
caps.setCapability("appPackage", "enter your appPackage");
caps.setCapability("appActivity", "enter your appActivity");
driver= new AndroidDriver<MobileElement>(new URL("remote server ip address" + ":4732/wd/hub"), caps);
Make sure both device are in the same network. you must get response while pinging to the remote server ip address
I've trawled through many of the answers here regarding socket access via native code on Android, and others regarding socket access for "androidTest" instrumented tests, but none are able to fully explain some odd behaviour I'm seeing.
Android Studio 2.3.3 on Windows 10, NDK 15.1.x, build tools 25.0.3. Building with Cmake. I am porting some native code over to Android intended to be distributed as a library that is wrapped in a Java JNI-based API. This part seems to be working fine; at least I can debug and log into the native code and see where things go wrong.
I've created a few instrumented tests to exercise the JNI, but it looks like the native side does not have access to sockets, even if the test app that Android Studio wraps up for your intrumented tests does (i.e., it has the INTERNET permission applied, and I can see that it is part of the pushed manifest of the test app. I also applied the ACCESS_NETWORK_STATE perm in a fit of pique.)
That is, parts of the library know how to set up and use TCP sockets (datagram and stream; in this case stream) and resolve DNS, which fails (This might be a bug in my port, since the device itself still seems to resolve DNS based on the adb shell output below). If I test with an IP address it retries until it fails. Each call to socket() returns an ERRNO of 11 EAGAIN ("Try again").
If I use the adb shell to login to the device under test over USB, I can ping and use curl, etc. But, as soon as I run-as as the test app I am no longer allowed to use any network device.
shell#venice:/data/data/org.clvrmnky.library.test $ ping www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
^C
--- www.example.com ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2004ms
1|shell#venice:/data/data/org.clvrmnky.library.test $ ping -I wlan0 www.example.com
ping: SO_BINDTODEVICE: Operation not permitted
2|shell#venice:/data/data/org.clvrmnky.library.test $ curl -4 --verbose www.example.com/
* Trying 93.184.216.34...
* connect to 93.184.216.34 port 80 failed: Connection timed out
* Failed to connect to www.example.com port 80: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to www.example.com port 80: Connection timed out
7|shell#venice:/data/data/org.clvrmnky.library.test $
I won't paste it here, but wlan0 (and others) exists and is UP with a valid, reachable IP address. It is "Link encap:UNSPEC" which I admit I don't fully grok.
I'm making an assumption that the app failing on the successive socket calls and the inability to bind to a network device in and use it in an adb shell are related in some manner, but if someone has a reason why this may not be so, please let me know.
I've tried:
Invoking the test methods in a background thread, just in case the instrumented tests were running in the test app main thread.
Setting the StrictMode thread policy to permitAll() in the #Before clause of the test class.
Running with and without the INTERNET permission set in the test manifest. Without this permission it reaches the native code, but fails much earlier in the initialization. I'd have to dig into my notes to fetch more details about that. I assume that I need this permission. (Side note: if I enable INTERNET then the remote debugger can no longer attach to the device, so I can debug via logs only.)
It looks like instrumented tests, at least as of this writing, do not support access to raw sockets through the NDK. The .test app that is auto-created seemed to have everything it needed in the manifest (I checked base.apk right from the device).
Once a DemoApp was created with identical manifest settings I was able to open sockets, connect to them, do name lookups, etc. Furthermore, I was able to access the network via adb shell when running as ("run-as") the DemoApp.
There is still something strange going on, as I created a separate JNI app that opens sockets, and hacked an instrumented test against that. At least briefly adb shell running as ext.other.app.test did have internet access.
I want to use adb to install apps to my Android-based TV from an Android phone rather than a computer.
So I decide to read adb source code, port the adb code and compile it to a library file (libadb.so) and then invoke it by JNI from within an Android app.
When I test this apk on my telephone, the adb server fails with can not bind 'tcp:5037' port.
I thought the failure to open that port might be a conflict with the existing implementation of ADB which might be using it, so I removed that. It didn't work. I tried to change to other ports, such as 4097,or 6066. It still didn't work. I have no further ideas how to solve this problem.
Android enforces its Internet Permission via a modification to the Linux Kernel which checks that a process is a member of an associated unix group before allowing it to open sockets in the AF_INET domain.
Such membership is inherited, so native code executed, either as a JNI library or by invoking a distinct executable, will only be able to perform network operations if it is either run as a privileged user automatically having this membership (such as adb's "shell" account, or as root on an engineering build) or run under the identify of an application package having the Internet permission in its manifest.
There may be a number of additional challenges with your goal (and it is unclear why the stock adb client on the device is not workable for you), but the immediate solution to your present problem is to run your customized adb tool from an application with Internet permission.
I´m developing an application that will be used on a managed platform. With managed platform I mean that it will run on a device that uses Android as a platform. No usual Android (phone/tablet applications will be installed, just custom company software).
The root file system is mounted as r/w and I'm able to push my apk file into /system/app/ and start my activity and services.
My goal is to provide a service running on a port lower then 1024. When binding this tcp port, I get the EACCES denied error message. How can I allow my application to bind to this port?
I have found the iptables solution, but unfortunately, the iptables executable doesn't work (segmentation faults). I am not able to recompile the platform, nor I have the platform signing key (the platform is provided as an installation on the target device).
My question is: how to give my application the rights to bind to a privileged port when I'm able to install my application as a system application and have root access (on adb shell) to the device.
The 0-1023 is mostly used for other protocols. Have you tried using a higher port? Otherwise make sure the owner is correct, if not then use chown and make sure. If those do not work supply the ls -l for the privileges.
I need to write a script for Android, to be downloaded using ADB, and which performs the following actions on the phone:
Turn off the protocol stack (equivalent to the AT command AT+CFUN=0\n)
Turn on the protocol stack (equivalent to the AT command AT+CFUN=1\n)
Establish PDP context
With devices that identify as COM-ports this is easy - just open the COM port and send the appropriate AT command. But how do I do this with an Android device?
Script manager on android market should provide some direction, as well as a catalyst for using, writing, and scheduling such scripts.