Shell Script For Installing/Uninstalling/Launching APK

My job requires me to install APK, launch application, test application, and uninstall application. Wrote this script to automate commands I have to run in console.

#!/usr/bin/php
<?php

$usage = <<<EOD
Usage example:
apker install /path/to/game.apk
apker launch /path/to/game.apk
apker uninstall /path/to/game.apk
apker /path/to/game.apk
EOD;

if (count($argv) == 2) {
    installAPK($argv[1]);
	launchAPK($argv[1]);
	exit(0);
}

if (count($argv) == 3) {
	if (strtolower($argv[1]) == 'install') {
		installAPK($argv[2]);
		exit(0);
	}
	elseif (strtolower($argv[1]) == 'launch') {
		launchAPK($argv[2]);
		exit(0);
	}
	elseif (strtolower($argv[1]) == 'uninstall') {
		uninstallAPK($argv[2]);
		exit(0);
	}
	else {
		echo "$usage\n";
		exit(1);
	}
}

echo "$usage\n";
exit(1);

function installAPK($apk) {
	echo "Install ...\n";
	if (shell_exec("adb install $apk")) {
		echo "Install successful...\n";
	}
	else {
		echo "Install unsuccessful...\n";
		exit(1);
	}
}

function uninstallAPK($apk) {
	$package = getPackage($apk);
	echo "Uninstall $package...\n";
	if (shell_exec("adb uninstall $package")) {
		echo "Uninstall successful...\n";
	}
	else {
		echo "Uninstall unsuccessful...\n";
		exit(1);
	}
}

function launchAPK($apk) {
	$activity = getLaunchableActivity($apk);
	$package = getPackage($apk);
	echo "Launching $activity...\n";
	if (shell_exec("adb shell am start -c android.intent.category.LAUNCHER -n $package/$activity")) {
		echo "Launch successful...\n";
	}
	else {
		echo "Launch unsuccessful...\n";
		exit(1);
	}
}

function getPackage($apk) {
	$output = shell_exec("aapt d badging $apk");
	// package: name='com.spoof.sms'
	preg_match("/package: name='([^']+)'/", $output, $matches);
	return $matches[1];
}

function getLaunchableActivity($apk) {
	$output = shell_exec("aapt d badging $apk");
	// launchable-activity: name='com.spoof.sms.com.home'
	preg_match("/launchable-activity: name='([^']+)'/", $output, $matches);
	return $matches[1];
}
?>

Posted in Tao Of Programming at April 19th, 2012. No Comments.

Connecting Android Devices In Linux

Linux kernel is capable of recognizing many Android devices connected through USB. You can make the device available in userspace through udev. In order to do that, I need to write some udev rules.  I use lsusb to find the vendor ID needed to write udev rules. This is my udev rule (/etc/udev/rules.d/90-android.rules):

# Nexus One
SUBSYSTEM=="usb", SYSFS{idVendor}=="18d1", MODE="0666"
SUBSYSTEM=="usb",ATTR{idVendor}=="18d1",SYMLINK+="android_adb"
SUBSYSTEM=="usb",ATTR{idVendor}=="18d1",SYMLINK+="android_fastboot"

# HTC
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
SUBSYSTEM=="usb",ATTR{idVendor}=="0bb4",SYMLINK+="android_adb"
SUBSYSTEM=="usb",ATTR{idVendor}=="0bb4",SYMLINK+="android_fastboot"

Posted in Blog at February 14th, 2011. No Comments.

Backup SVN Using SSH With Public/Private Key

I have a development server which runs the SVN server that my team works with. I want to backup the SVN repository, using a cron. After some research, I have collected information from several sites. The post gives an instruction to configure a computer (local host) to mirror a remote repository on a remote host.

Create Public/Private Keys

On the local host, create public/private pair:

ssh-keygen -t rsa -b 2048

-t sets the type of key to create. Possible values: “dsa”, “rsa”. -b sets the key size. 786 bits minimum for RSA, and exactly 1024 bits for DSA. Passphrase is optional, you can skip it by pressing Enter key. If you set a passphrase, you need to key in your passphrase everytime the private key is used. If you need to perform automated task over SSH, you might not want to have a passphrase. By default the private key is saved in ~/.ssh/id_rsa, and the public key is saved in ~/.ssh/id_rsa.pub. Copy the content from public key file and append it to the remote host’s ~/.ssh/authorized_keys. Now you can test it by SSH-ing to remote host.

Configure SSH Authentication for SVN

If the above step is performed successfully, you should be able to perform the following command to list the directory entries in the remote host.

svn list svn+ssh://remotehost.com/path/to/repo

For security reason, my remote host use a non-default port for SSH access. I have modified my local host config file (usually ~/.subversion/config) to use port 1234 for access.

[tunnels]
remotesvn = ssh -p 1234

I have defined a scheme called “remotesvn”, and added options to the SSH command. You can add additional options if you want to. This is how I list directory entries in my remote host:

svn list svn+remotesvn://username@remotehost.com/path/to/repo

“username@” is optional if the local username is same as username used to access remote repository.

Initialize Local Repository For Mirroring

# Create a local repository
svnadmin create /var/svn/myrepo
echo '#!/bin/sh' > /var/svn/myrepo/hooks/pre-revprop-change
chmod 755 /var/svn/myrepo/hooks/pre-revprop-change
# Init the local repository for synchronization with remote repository
svnsync init file:///var/svn/myrepo svn+remotesvn://username@remotehost.com/path/to/repo

After svnsync init, the local repository is set revision 0, no useful data is copied yet. Use the following code to synchronize local repository with remote repository:

svnsync sync -q file:///var/svn/myrepo

-q switch is optional, it keeps the textual output to minimal during the synchronization process.
You may add this line in your crontab to backup your remote repository in a regular interval.

References:

Posted in Blog at November 1st, 2010. No Comments.

Format USB Drive In Linux

My USB drive is corrupted. These are the steps I took to reformat it.

Determine drives and partitions:

fdisk -l

My USB drive is /dev/sdb1, formated with W95 FAT32 filesystem. I am going to unmount it:

umount /dev/sdb1

Reformat it:

mkfs.vfat /dev/sdb1

Posted in Blog at March 31st, 2010. No Comments.

[Linux] Aventail VPN Client 8.90.263

In order to connect to my company’s intranet, I need to install an Aventail client. I downloaded the package, unzip it, and execute install.sh. The installation process it as easy as ABC. The applications is installed in the /usr/local/Aventail/ folder. You can run the client either by executing startct or startctui. The startctui is a Java GUI client.

When I tried to establish a connection, it just couldn’t connect to my company’s VPN gateway. The /var/log/AvConnect.log log file tells me that handshake failed. After some googling, I found the solution at http://just-another.net/2008/11/20/ubuntu-intrepid-and-aventail-ssl-client/.

The problem lies in libssl and libcrypto from OpenSSL package. I am running CrunchBang (Ububtu based distro). The OpenSSL offered in the repository is version 0.9.8g. You can verify it by doing a “ldd /usr/local/Aventail/AvConnect“. AvConnect depdends on /usr/lib/libssl.so.0.9.7, which is a symbolic link pointing to libssl.so.0.9.8. Likewise for libcrypto too.

Solution:

  1. Download OpenSSL 0.9.8i.
  2. Compile it, installation is not necessary.
    After compilation, it generates libssl.so and libcrypto.so.
  3. Unlink the original /usr/lib/libssl.so.0.9.7 and /usr/lib/libcrypto.so.0.9.7.
  4. Create symbolic links to the newly created libssl.so and libcrypto.so.

This is just a summary. The detail steps are documented at http://just-another.net/2008/11/20/ubuntu-intrepid-and-aventail-ssl-client/. When unlinking and creating links in /usr/lib, make sure you are doing it as root.

At the time of writing, the latest stable version of OpenSSL is 0.9.8l. It does not work. So you should stick to 0.9.8i! Version i works but not g and l. I guess something must be broken in the later build. Hope the OpenSSL team will retify the problem soon.

Posted in Blog at December 4th, 2009. No Comments.