Linux and Android - For all topics that are not only "Linux" and not totally "Android"

How to uninstall system apps (and bloatware) from an Android device ?

This is a non-official unsupported hack : you're NOT supposed to remove bloatware installed by the manufacturer of your Android device. Things may break bad while applying this hack. Use at your own risks.
  1. disable the app you'd like to uninstall, and wait for a few days to see if everything's still working fine
  2. check you can manage your Android device by opening an ADB shell on it. You should get a prompt :
    a5xelte:/ $ 
    leave with exit or CTRL-d
  3. list disabled apps :
    adb shell pm list packages -d		as you probably have guessed, -d is for disabled apps
    alternate solution :
    adb shell pm list packages | grep skype
    you'll get a list formatted like :
    package:applicationId
    package:com.skype.raider
  4. check the application ID : it should be visible on the Google Play Store, at the address :
    https://play.google.com/store/apps/details?id=applicationId
    For skype : https://play.google.com/store/apps/details?id=com.skype.raider
  5. uninstall :
    adb shell pm uninstall --user 0 applicationId
    adb shell pm uninstall --user 0 com.skype.raider
    Success
    alternate method :
    adb shell pm uninstall -k --user 0 applicationId		-k leaves user settings + data while uninstalling

Some more apps / bloatware to remove :

Mind the applicationId in the hyperlinks below
com.samsung.android.dlp.service		https://forum.xda-developers.com/tmobile-s7-edge/how-to/s7-edge-debloat-list-t3330211
com.samsung.android.securitylogagent	https://securitylogagent.en.uptodown.com/android

com.android.calendar			this IS NOT "Google Agenda" : https://play.google.com/store/apps/details?id=com.google.android.calendar

Android tethering with Linux host running as a VirtualBox guest

We have 3 devices here :
  1. Android : a smartphone we'd like to use as a USB modem
  2. Host : this is the PC running the host OS + VirtualBox itself
  3. Linux : the VirtualBox VM

Procedure

Some prerequisites
  • What we're actually doing when fiddling with the USB devices filter of VirtualBox VMs is defining rules to "autoplug" USB devices into the corresponding guest. Thus, upon physically plugging a peripheral, it gets automatically virtually connected into the VM.
    This can lead to difficulties (i.e. impossible to connect device) if any given device is configured into several guests running simultaneously : a device can only be connected once. So when playing with multiple VMs simultaneously, make sure every USB device is configured only once.
  • I don't have all the details about this so far, but I've observed my smartphone, once plugged via USB on a guest, appears as :
    • SAMSUNG_Android [0400] : when initially plugged
    • SAMSUNG_Android [FFFF] : once I've enabled the USB Modem
    The peripheral to add to the USB filter discussed above is the SAMSUNG_Android [FFFF].
Let's connect things !
  1. physically plug Android on Host via USB. Don't do any configuration on the Host OS since we're going to "plug" this device into the Linux guest
  2. If, at any time, on Android, you see a prompt like Allow access to data on Android device ?, deny it.
  3. on Android : enable the USB Modem
  4. open VirtualBox GUI, select Linux then open its Configuration | USB tab
  5. click the USB connector with a green '+' button to add a rule to "connect" a USB device to this host
  6. in the list, pick the corresponding device. For me, it's SAMSUNG_Android [FFFF]
  7. in the VirtualBox guest window, check the smartphone is actually connected to Linux with the Devices | USB menu, or with a right-click on the USB connector icon at the bottom of the window : there should be a check mark leading the device name : SAMSUNG_Android [FFFF]
  8. Unless explicitly specified, all the following steps are on Linux.
    lsusb
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 009: ID 04e8:6864 Samsung Electronics Co., Ltd GT-I9070 (network tethering, USB debugging enabled)	this is my smartphone
    Bus 001 Device 002: ID 13fd:1d40 Initio Corporation
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    If it displays something like this instead :
    Samsung Electronics Co., Ltd Galaxy (MTP)
    you have probably enabled access to the data stored on the smartphone, and it won't work.
  9. ip a
    
    4: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    	link/ether fe:10:26:43:4f:5e brd ff:ff:ff:ff:ff:ff
    if this lists no usbn interface, read this.
  10. Get an IP address via DHCP from the mobile phone operator :
    sudo dhclient usb0
    should be enough to do the job, but sometimes does not work ()
    sudo bash -c 'ifconfig usb0 up && dhclient usb0'
    use this if this one above fails
  11. check it :
    ip a
    
    4: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000		looks like this state UNKNOWN can be safely ignored
    	link/ether fe:10:26:43:4f:5e brd ff:ff:ff:ff:ff:ff
    	inet 192.168.42.15/24 brd 192.168.42.255 scope global usb0		got an IP address from my operator
    		valid_lft forever preferred_lft forever
    	inet6 fe80::fc10:26ff:fe43:4f5e/64 scope link
    		valid_lft forever preferred_lft forever
  12. Make sure routes have been properly set up on Linux side :
    netstat -nr
    Kernel IP routing table
    Destination	Gateway			Genmask		Flags	MSS	Window	irtt	Iface
    0.0.0.0		192.168.42.129		0.0.0.0		UG	0	0	0	usb0		the route to the Internet goes through the operator's gateway via my smartphone
    10.0.2.0	0.0.0.0			255.255.255.0	U	0	0	0	eth0
    192.168.42.0	0.0.0.0			255.255.255.0	U	0	0	0	usb0
    192.168.56.0	0.0.0.0			255.255.255.0	U	0	0	0	eth1
    Equivalent command :
    ip r
    default via 192.168.42.129 dev usb0 
    10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
    192.168.42.0/24 dev usb0 proto kernel scope link src 192.168.42.140
    192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.101 metric 100
    • Mind the gateway IP : 192.168.42.129 : definitely on the same subnet than the IP I received, but my own IP should NOT appear here.
    • My web browser (configured to use a forward proxy on the 10.0.2.0/24 network), doesn't work anymore. This is normal since it can't be reached via the default route.
  13. ping -I usb0 -c 3 www.google.be
    PING www.google.be (216.58.209.227) from 192.168.42.15 usb0: 56(84) bytes of data.
    	64 bytes from par10s29-in-f227.1e100.net (216.58.209.227): icmp_seq=1 ttl=51 time=33.9 ms
    	64 bytes from par10s29-in-f227.1e100.net (216.58.209.227): icmp_seq=2 ttl=51 time=40.9 ms
    	64 bytes from par10s29-in-f227.1e100.net (216.58.209.227): icmp_seq=3 ttl=51 time=38.1 ms
    
    	--- www.google.be ping statistics ---
    	3 packets transmitted, 3 received, 0% packet loss, time 2002ms		
    	rtt min/avg/max/mdev = 33.904/37.666/40.963/2.900 ms

Debugging :

No usbn interface :
The usbn interface is normally detected + configured by ModemManager.service. Let's investigate :
  • systemctl list-unit-files | grep -i modem
    ModemManager.service			disabled
    Looks like we found the culprit
  • systemctl is-enabled ModemManager.service
    disabled
    Confirmed
  • systemctl enable ModemManager.service && systemctl start ModemManager.service
    Created symlink /etc/systemd/system/dbus-org.freedesktop.ModemManager1.service → /lib/systemd/system/ModemManager.service.
    Created symlink /etc/systemd/system/multi-user.target.wants/ModemManager.service → /lib/systemd/system/ModemManager.service.
    Should be better, now
  • ip a
    15: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    	link/ether 56:20:96:c6:f2:d0 brd ff:ff:ff:ff:ff:ff
    Fixed
No network traffic (i.e. can't ping) despite everything looking ok :
I've followed the procedure above, and fail at the final ping step .
So far, I've tested MANY things (it finally works), but I've not found a reproducible way or anything to explain it. Here are some things to consider the next time :
Topic Possible values / configurations So far, it works on...
physical USB port laptop / docking station laptop
physical USB port USB3 (blue / "SS" mark (SuperSpeed) / 5 pins) / USB2 (black, 4 pins) USB2
There's also a pretty complex software stack :
  1. the host OS (Windows 7)
  2. VirtualBox
  3. the guest OS (Debian Stretch)
  4. Android
... including some I don't trust a lot (already observed weird behavior many times...)
The USB network connection disables an existing network connection :
Even though it looks like one of the existing ethx connections is disabled once the usbx connection becomes active, this is not exactly what happens. Actually, the USB network connection becomes an extra default route, overriding the existing default route :
ip r | grep default
default via 192.168.42.129 dev usb0
default via 10.0.2.2 dev eth0 proto static metric 100
Delete the unwanted default route :

adb shell

my notes about adb shell commands be here. 'til then, follow the "source" link below ;-)

How to access the SD Card in read/write mode on a non-rooted device from Debian Stretch ?

On a rooted device, you probably won't need to do this since there are chances you ALREADY have read/write access to your SD Card. Try with SSHDroid as described below.
For others, the solution is ADBFS. You'll also need a USB data cable to connect your Android device to a computer.

Setup :

  1. as root :
  2. as any non-root user :
    wget https://github.com/spion/adbfs-rootless/archive/master.zip -O adbfs-rootless-master.zip
  3. unzip adbfs-rootless-master.zip
  4. cd adbfs-rootless-master && make
  5. as root anew, copy the binary you've just compiled :
    cp adbfs /usr/bin && chmod 755 /usr/bin/adbfs
  6. make the required settings on the Android device (except "root access", that won't be available for obvious reasons )
  7. connect the Android device to the computer with a USB data cable
  8. there is a kind of "peering" between the computer and the phone (like the "known_hosts" mechanism when dealing with SSH). You should be prompted, on the phone, whether you allow USB Debugging from this computer. Don't miss this step.
  9. make sure the peering worked fine :
    adb devices
    List of devices attached
    0019b7cf68b49e	device
    If you get something different, read this.
  10. adb shell
    You should get a shell prompt from your phone. Leave with exit
  11. create a mount point :
    mkdir -p /mount/point
  12. don't leave a process behind :
    adb kill-server

Usage :

  1. plug the USB cable
  2. adb shell
    List of devices attached
    * daemon not running. starting it now on port 5037 *
    * daemon started successfully *
    3300839aba2328c7	device
  3. mount :
    adbfs /mount/point
  4. wander around, copy files, do some stuff...
    For the record :
    /mount/point/sdcard
    directory matching the phone internal storage
    /mount/point/storage/7EFB-7602
    directory matching the actual SD Card
  5. umount :
    fusermount -u /mount/point
  6. adb kill-server

How to copy files between GNU/Linux and Android devices without USB Mass Storage via MTP ?

Recent Android versions (5.x.x here aka Lollipop) have no USB Mass Storage capabilities anymore (WHY??? ). Instead, it is possible to transfer files to/from them via MTP.

Read the solution.

Preliminary notes :

  • MTP originated from Microsoft with DRM in mind. This is why file transfers work out-of-the-box between Android and Windows.
  • The procedure below works "not too bad" to copy a few files to/from Debian but it becomes slow as sh*t and rather unreliable to sync large amounts of data.

About the absence of USB Mass Storage mode :

While some pretend MTP is "better" because it does not require exclusive access to the storage media (what USB Mass Storage requires), there are some thinking that USB Mass Storage has been disabled to "encourage" users to consider cloud storage...

Procedure :

This works also on non-rooted devices.

  1. as root : apt install mtp-tools jmtpfs
  2. if mtp-detect returns :
    Unable to open ~/.mtpz-data for reading, MTPZ disabled.
    libmtp version: 1.1.8
    
    Listing raw device(s)
    Device 0 (VID=04e8 and PID=6860) is a Samsung Galaxy models (MTP).
    	Found 1 device(s):
    	Samsung: Galaxy models (MTP) (04e8:6860) @ bus 2, dev 29
    Attempting to connect device(s)
    USB low-level info:
    
    
     ( MANY lines skipped )
    
    
    OK.
    ... it looks good !
  3. jmtpfs -l confirms the previous result :
    Unable to open ~/.mtpz-data for reading, MTPZ disabled.
    Device 0 (VID=04e8 and PID=6860) is a Samsung Galaxy models (MTP).
    Available devices (busLocation, devNum, productId, vendorId, product, vendor):
    2, 29, 0x6860, 0x04e8, Galaxy models (MTP), Samsung
  4. Mount the storage device : mountPoint='/path/to/mount/point'; mkdir -p "$mountPoint" && jmtpfs "$mountPoint" && ls -l "$mountPoint"
  5. The device is now listed by : mount. Transfer data. Enjoy.
  6. When done, umount : fusermount -u "$mountPoint"

Solution :

So far, I've not found a better solution than running an SSH server on my smartphone, then mounting its SD Card on my PC via SSHFS.

As for the SSH server, the procedure below works with SSHDroid, but not with SSH Server, which can't get access to the SD Card (needs further investigations).

On the Android device
  1. install SSHDroid
  2. Start SSHDroid's SSH daemon. It will display :
On the GNU/Linux device (see also : How to mount / umount a SFTP directory ?)
  1. apt install sshfs
  2. Uncomment #user_allow_other in /etc/fuse.conf
  3. Mount the SD card into your computer, as a non-root user :

    sshfs -o allow_other -p 2222 root@192.168.1.93:/storage/extSdCard /mount/point

    On a rooted device, since SSHDroid is listening on the standard TCP 22 port, you don't need the -p whatever option.
  4. Copy files, do whatever you like, enjoy !
  5. Still as a standard user, unmount : fusermount -u /mount/point
  6. On your smartphone, stop the SSH daemon.
Notes about root-access on your phone :

Looks like this is required to write on the SD Card, otherwise, I get plenty of write errors (possibly due to the VFAT filesystem, too...)

Don't forget that VFAT filesystems have some limitations, such as not supporting some characters in file names : ?, ", ...

How to open an ADB shell ?

When I first had a look at ADB, my purpose was to open a shell from my computer to my smartphone, so that I could wander around in the filesystem. ADB _seems_ to allow this, but there are easier solutions, by installing on the Android device :
  • an SSH server (such as SSHDroid)
  • a terminal emulator (and doing everything locally)
ADB is a command line tool that lets you communicate with an Android device. It's composed of : (details)

To open a shell, via ADB, on an Android smartphone :

  1. Don't plug the phone on the computer yet
  2. On the computer : apt install adb
  3. On the phone, enable :
    1. Developer mode : Settings | About phone | Build number (7 times)
    2. USB Debugging mode : Settings | Developer options | USB Debugging
    3. root access : Settings | Developer options | Root access
  4. Back to the computer, plug the smartphone via USB, then :
    adb devices
    List of devices attached
    0019b7cf68b49e	device
    If you get something different, read this.
  5. To open a shell as a standard user : adb shell
    shell@android:/ $
  6. To open a shell as root : adb shell su
    root@android:/ #
    I've not been able to do a lot this way, maybe I'm still missing something. With a terminal emulator installed on the phone, I've been able to fix things and didn't make any further tests with ADB.

adb device outputs :

Result Cause solution
List of devices attached
			nothing
No device listed : computer and phone are mutual strangers (or you failed to plug the USB cable )
  1. revoke all authorizations on the phone (i.e. purge the "known_hosts" list : Parameters | Development options | Revoke all USB debugging permissions)
  2. toggle "off" then back "on" the USB debugging
  3. unplug + replug USB
  4. retry
List of devices attached
3300839aba2328c7	unauthorized
  • Your phone is probably waiting for you to click on Accept
  • OR your phone does not recognize THIS computer as an authorized host
List of devices attached
3300839aba2328c7	device
Finally, everything is going extremely well. (it ain't broken, don't fix it )

How to stop the local ADB server ?

As soon as you run : adb shell, the ADB daemon is started :
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
And probably, after you've finished playing with your Android device, you'd prefer to stop it. Here's the procedure :
  1. Make sure it's alive : ss -punta | grep 5037
    u_str	LISTEN	0	4	/tmp/5037	1199191184	* 0	users:(("adb",pid=4256,fd=6))
  2. Kill it softly : kill -1 $(ss -punta | grep 5037 | sed -r 's/^.*pid=([0-9]+),.*$/\1/')
    kill -1 $(ss -punta | grep 5037 | sed -r 's/^.*pid=([0-9]+),.*$/\1/')
    "Useless use of grep | sed" bell ringing, it _may_ be possible to fix this with :
    kill -1 $(ss -punta | sed -e '/5037/ p' -r -e 's/^.*pid=([0-9]+),.*$/\1/')
  3. Make sure it's dead.