[Galaxy S II Original Android Development] Tungstwenty:
Actions

Here's a collection of the several types of actions that have been identified so far. They're mostly ready to use as-is, but do read the script code and edit where necessary to suit your needs.

Please refer to the previous posts for instructions on how to include this in the gesture detection loop.

For test purposes you can simply execute these from the ADB shell, but for it to be part of your daily usage they must be included on your personal script.

Key presses

With these your gestures can simulate that certain keys were pressed, usually hard-keys that you may wish to avoid wearing out, or special keys that the device may even not have but the ROM can react to,

depending on the ROM

.

Examples: HOME, Power, Volume up/down, Media play/pause, Media stop, Media next/previous, Volume mute/unmute, Recent Apps, etc.

Script code:

input keyevent 26

This has the same effect as pressing the Power key.

For other key codes, check here for ICS or here for JB. Some examples:

3 - HOME

24/25 - Volume up/down

26 - Power

84 - Search

85 - Media play/pause

86 - Media stop

87/88 - Media next/previous

164 - Toggle volume mute

187 or 214 - Recent apps

220 - Voice search

212/213 - Brightness up/down

215 - App drawer

As

an alternative

to executing "input keyevent <code>", it is also possible to inject key press events and even choose the delay between the press and the release to simulate long presses.

Example for a HOME key long press:

sendevent /dev/input/[COLOR="Red"]event1[/COLOR] 1 [COLOR="Red"]102[/COLOR] 1
sendevent /dev/input/event1 0 0 0
usleep [COLOR="red"]500000[/COLOR]
sendevent /dev/input/event1 1 [COLOR="red"]102[/COLOR] 0
sendevent /dev/input/event1 0 0 0

102 is the scan code for the HOME key and it will have a delay of 500ms between pressing and releasing.

Possible scan codes (for the physical buttons):

102 - Home

116 - Power

115 / 114 - Volume up / down

For the touchkeys "menu" and "back", instead of using event1 (gpio-keys as stated by "getevent"), send the scan codes to event7 (sec_touchkey):

139 - Menu

158 - Back

Invoking services

There are quite a few services running on the device, which expose interfaces that can be invoked using the "service call <name> <transaction> <params>..." syntax.

How to explore existing services

To list running services:

# service list
Found 95 services:
0 sip: [android.net.sip.ISipService]
1 phoneext: [com.android.internal.telephony.ITelephonyExt]
2 [COLOR="Red"]phone[/COLOR]: [com.android.internal.telephony.[COLOR="Red"]ITelephony[/COLOR]]
3 iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo]
4 simphonebook: [com.android.internal.telephony.IIccPhoneBook]
5 isms: [com.android.internal.telephony.ISms]
6 voip: [android.os.IVoIPInterface]
7 FMPlayer: [com.samsung.media.fmradio.internal.IFMPlayer]
8 mini_mode_app_manager: [com.sec.android.app.minimode.manager.IMiniModeAppManager]
9 tvoutservice: [android.os.ITvoutService]
10 motion_recognition: [android.hardware.motion.IMotionRecognitionService]
11 samplingprofiler: []
...

Search sources (using for instance grepcode.com) for the interfaces, such as ITelephony in this example.

Here you can find the existing transactions for the "phone" service on 4.0.3 (in some cases it may be slightly different in JB).

If we want to invoke the TRANSACTION_call operation on this service, we'll need to indicate transaction code 2 (1+1) and check what parameters it expects. The code for that is in this line which shows that this particular call it needs a string (with the number to call).

So, in conclusion, to make the device call a certain number one only has to issue this commant:

service call phone 2 s16 "123456789"

replacing the destination number for the one you want.

Note that "service call" accepts arguments of type "i32 <number>" and "s16 <string>", which can be joined together as many times as needed. For transactions expecting "long", you'll need to pass in 2 i32's to make a long value.

In some of them - such as when asking for the current state of something like bluetooth - you'll need to analyze the output (using grep, for instance) to find if the result is "00000000 00000000" vs "00000000 00000001", or some other value.

Collected service calls so far

Calling a phone

service call phone 2 s16 "123456789"

(replace 123456789 by the destination number you want to call)

Toggling bluetooth enabled/disabled

This involves 3 transactions on the bluetooth service: isEnabled, enable, disable (this one changes from ICS to JB); the output of isEnabled must also be analyzed in order to know what to do next.

service call bluetooth 1 | grep "0 00000000"
if [ "$?" -eq "0" ]; then
service call bluetooth 3
else
[ "$is_jb" -eq "1" ] && service call bluetooth 5
[ "$is_jb" -ne "1" ] && service call bluetooth 4
fi

The "is_jb" variable should have been set to 1 prior to this in the case of a JB rom (the script on the OT includes it)

Toggling data connection

Similar to bluetooth, but on the connectivity service.

service call connectivity 18 | grep "0 00000000"
if [ "$?" -eq "0" ]; then
service call connectivity 19 i32 1
else
service call connectivity 19 i32 0
fi

Toggling WiFi on/off

Similar to bluetooth, but on the wifi service.

service call wifi 14 | grep "0 00000001"
if [ "$?" -eq "0" ]; then
service call wifi 13 i32 1
else
service call wifi 13 i32 0
fi

Vibration

Transaction "vibrate" can be called in the vibrator service (it requires a long parameter, which maps to 2 i32 entries)

It is asynchronous, meaning that the instruction ends but the device will continue vibrating for the requested duration. This is important in case you wish to insert pauses between multiple vibrations; in that case you'll need to call "usleep" (to have times smaller than 1s) but pause for the duration of the first vibration + the non-vibration time you want, before invoking it again.

service call vibrator 2 i32 300 i32 0
usleep 600000
service call vibrator 2 i32 300 i32 0

This starts the vibration with a timeout of 300ms, pauses for 600ms (enough for it to stop and stay off for another 300ms) and vibrates a second time.

Expand / collapse the status bar

Not particularly useful, but the transactions "expand" and "collapse" can be called on the statusbar service.

service call statusbar 1

service call statusbar 2

Enable / disable the touch screen

This can be very useful in order to prevent the finger movement for gestures to trigger side-effects on the active app that also receives those events (moving icons on the launcher, etc.)

For best experience, map these to a simple gesture such as pressing 2 or 3 fingers in the screen corners, preferably without movement in order not to cause active apps to do anything.

For ICS:

# Disable
service call window 18 i32 0
# Enable
service call window 18 i32 1

For JB use transaction code 15 instead of 18.

Force-stopping an activity

One of the ways to do this is invoking the FORCE_STOP_PACKAGE_TRANSACTION on the activity service.

service call activity 79 s16 com.swype.android.inputmethod

This will stop the swype package if it's running.

For a more dynamic script that will stop whatever is foreground app, the output of "dumpsys activity" can be combined:

service call activity 79 s16 `dumpsys activity top | grep '^TASK.*' | cut -d ' ' -f2`

Toggling between the last 2 applications / windows

For this, invoke MOVE_TASK_TO_FRONT_TRANSACTION on the activity service with the task id to activate and with the MOVE_TASK_NO_USER_ACTION flag.

Again, "dumpsys activity" can be used to identify the next-to-last activity which will be brought to front:

service call activity 24 i32 `dumpsys activity a | grep "Recent #1:" | grep -o -E "#[0-9]+ " | cut -c2-` i32 2

Since the launcher is just an app like any other, if the previous app was the launcher that's where you'll switch to. If you'd like to exclude it from this logic, a slightly more elaborate script is required:

dumpsys activity a | grep "Recent #1:.* com.sec.android.app.twlauncher"
if [ "$?" -eq "0" ]; then
service call activity 24 i32 `dumpsys activity a | grep "Recent #2:" | grep -o -E "#[0-9]+ " | cut -c2-` i32 2
else
service call activity 24 i32 `dumpsys activity a | grep "Recent #1:" | grep -o -E "#[0-9]+ " | cut -c2-` i32 2
fi

Basically, if the last app was ...twlauncher, switch to the one before that (#2) instead of the last (#1). You'll obviously need to edit the package name to match your launcher.

Launching applications (and other intents)

The "am" command can be used to launch applications, much like what happens when their icons are pressed in the launcher. In fact, this command is so powerful that it can be a challenge to know what to do with it.

The most usual scenario is to merely execute "am start <packagename>/<activity>".

To find out which values to pass as package and activity, you can launch whatever apps you're interested in and then execute "dumpsys activity a" to see what's running and what is their associated activities:

# dumpsys activity a
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Main stack:
* TaskRecord{41d938c8 #48 A com.android.email}
numActivities=1 rootWasReset=false
...
Running activities (most recent first):
TaskRecord{41d938c8 #48 A com.android.email}
Run #3: ActivityRecord{41bbeda0 com.android.email/.activity.MessageListXL}
TaskRecord{41dfff40 #46 A com.seasmind.android.gmappmgr}
Run #2: ActivityRecord{41950668 com.seasmind.android.gmappmgr/.GmUserAppMgr}
TaskRecord{41d9a498 #2 A com.sec.android.app.twlauncher}
Run #1: ActivityRecord{41dd14c0 com.sec.android.app.twlauncher/.Launcher}
TaskRecord{41f12788 #40 A com.cooliris.media}
Run #0: ActivityRecord{4157e130 [COLOR="Green"]com.cooliris.media/.Gallery[/COLOR]}
...
Recent tasks:
* Recent #0: TaskRecord{41d938c8 #48 A com.android.email}
...
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10400000 cmp=com.android.email/.activity.Welcome}
realActivity=[COLOR="green"]com.android.email/.activity.Welcome[/COLOR]
...
* Recent #1: TaskRecord{41dfff40 #46 A com.seasmind.android.gmappmgr}
...
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.seasmind.android.gmappmgr/.GmUserAppMgr}
realActivity=[COLOR="green"]com.seasmind.android.gmappmgr/.GmUserAppMgr[/COLOR]
...

From here you can see that good candidates for the "am start" command would be "com.cooliris.media/.Gallery", "com.android.email/.activity.Welcome", etc.

Invoking the Gallery app, for instance, will output this:

# am start com.cooliris.media/.Gallery
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.cooliris.media/.Gallery }
Warning: Activity not started, its current task has been brought to the front

In this case, the application was already running so it was merely brought to the foreground. Otherwise, it would have been launched.

On the script in the OP you can find the following for the gesture that launches the Camera app:

result=`am start com.sec.android.app.camera/.Camera 2>&1 | grep Error`
[ "$result" != "" ] && result=`am start com.android.camera/.Camera 2>&1 | grep Error`
[ "$result" != "" ] && result=`am start com.android.gallery3d/com.android.camera.CameraLauncher 2>&1 | grep Error`

Since different ROMs have different camera apps, in this code 3 different activities are tried, moving on to the next whenever the previous one failed. This still doesn't cover all possibilities, but at least is not only for stock 4.0.3 roms but also works e.g. on some JB roms.

An interesting use can obtained if you're using the Android 4.2 Camera. It supports taking pictures even from a locked phone, in a secure manner i.e. not requiring to unlock the phone but not allowing to browse the gallery contents (while still allowing to see the ones you took at that time). Here's the am command:

am start -a android.media.action.STILL_IMAGE_CAMERA_SECURE

Check this post for more details.

Finally, there are some topics that you can explore on the "am" command:

1. additional intent details for "am start": instead of merely passing <package>/<activity>, there are many more options to use if you know the action to launch, the category, any data it uses, extra parameters, etc.

2. optional arguments such as "--activity-exclude-from-recents" (which prevents the task to be added to the recents list, in the task manager). Just explore the available options by running "am" only.

3. actions other than "start": force-stop, kill, broadcast, etc.

Again, the "am" command allows lots of things to be done related with Intents, but a lot of investigation is required on what intents exist, what parameters they take, etc.

In pretty much all cases the standard "am start <package>/<activity>" will be the syntax to use.