Replacing search key with recent apps function for Nexus S

Preface

I’ve mentioned switching between custom ROMs in the previous post and so I’ve finally landed on CyanogenMod1. It had many cool tweaks, specially support for changing the brightness levels and BLN, so I didn’t have to reapply the modifications as the ROM got developed and updated. But initially it missed an useful feature - searchtorecent.


What is “Search to recent” ?

When Android 4.0 ICS2 was launched in December 2011, it featured a major revision in operation. The phone launched with new version was a Samsung Galaxy Nexus, a first consumer phone to come with a HD ready display resolution in 1280x720.

Samsung Galaxy Nexus (Photo Credit: androidbeat.com).

Samsung Galaxy Nexus (Photo Credit: androidbeat.com).

It also featured buttons that were completely software and a part of the software, so called soft touch buttons. Key layout also changed. While previously the standard buttons on Android were four (home, menu, search, back), the Galaxy Nexus had only three (back, home, recent). Menu button was replaced with a software three dot menu called action bar overflow that was part of the UI.

See that three dot button ? That’s the AB overflow. (Photo Credit: ubergizmo.com).

See that three dot button ? That’s the AB overflow. (Photo Credit: ubergizmo.com).

The new overflow received mixed reviews. The standard guideline was to put it in the top right corner, but since the new phone was a lot larger then previous Nexus S (4.7” vs. 4.0”), it was difficult to reach the corner with one hand. Where as the menu key was more easily reach before at the bottom.

They also replaced the search key with a new one called recent apps. It invoked a multitasking overview of ten last opened apps with thumbnails.

Recent apps menu on Galaxy Nexus. (Photo Credit: ubergizmo.com).

Recent apps menu on Galaxy Nexus. (Photo Credit: ubergizmo.com).

This changed quite a bit the way you could use the device and switch quickly between apps. The standard gesture to reach the same recent apps on the Nexus S was to long press the home key for couple seconds. When you got used to the new method, long pressing seemed less fluid. But luckily there was a way to get the same functionality on Nexus S.

Changing key configuration

Xda-developers user evilisto came up with a solution where to change the device configuration for Nexus S keys to remap the search key to serve as recent apps key and posted it on xda-developers.

Changes needed were in the Android ICS framework source file platform/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java from :

        } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
            if (down && repeatCount == 0) {
                showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
            }
            return -1;
        }

To:

        } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
            if (down && repeatCount == 0 && !keyguardOn) {
            try {
                mStatusBarService.toggleRecentApps();
            } catch (RemoteException e) {
                Slog.e(TAG, "RemoteException when showing recent apps", e);
            }
        }
            return -1;
        }

We also needed to change the key layout file specific for Nexus S. Those changes were in /system/usr/keylayout/cypress-touchkey.kl on the phone itself.

key 139    MENU           VIRTUAL
key 102    HOME           VIRTUAL
key 158    BACK           VIRTUAL
key 217    APP_SWITCH     VIRTUAL

And /system/usr/keylayout/mxt224_ts_input.kl.

key 158   BACK              WAKE
key 139   MENU              WAKE
key 217   APP_SWITCH        WAKE
key 102   HOME              WAKE

Where all we did was to replace SEARCH with APP_SWITCH keyword. This invoked the proper recent apps functionality when pressing the search key.

Building the modification

Since CyanogenMod custom ROM was fully open source and I had the experience of doing it before with original ICS source and Bugless Beast custom ROM, I just repeated the exercise and downloaded the full CyanogenMod source for version 9 (CM9 was ICS).

After creating a working directory I initialized the repo with repo command and used -b to indicate I want the ics branch.

$ repo init -u git://github.com/CyanogenMod/android.git -b ics

Then I downloaded the source.

$ repo sync

After couple hours of downloading the source was downloaded and I could continue with build setup. If you remember, those steps are the same as before.

$ source build/envsetup.sh

Then run lunch and select our desired device to build for from the list.

$ lunch

After the build environment is now set, build the ROM.

$ make -j4

After initial build is ready, we can later make the changes above and rebuild android.policy.jar with mmm.

$ mmm frameworks/base

Getting it ready for flashing

As thorougly explained in an earlier post, the simplest way to use this is by making a flashable .zip file, specially because this modification contains two files that aren’t part of the Android source and reside on the Nexus S. Structure for the .zip file is following:

├── system/
|    ├── framework/                     # folder where the .apk will be flashed to /system/framework
|        ├── android.policy.jar         # modified policy for app_switch
|    ├── usr/
|        ├── keylayout/
|            ├── mxt224_ts_input.kl     # keylayout files
|            ├── cypress-touchkey.kl    # where we replaced SEARCH with APP_SWITCH
├── META-INF/
|    ├── com/
         ├── google/
             ├── android/
                 ├── updater-script     # script where you declare how the .zip should operate
                 ├── update-binary      # update binary compatible with the signature, it's reusable               
|    ├── CERT.RSA                       # signature files which
|    ├── CERT.SF                        # are reusable
|    └── MANIFEST.MF                    # in every .zip

update-script, which is written in Edify needs to look like this:

show_progress(0.500000, 0);
ui_print(" ");
ui_print("Installing Search to Recent apps mod");
ui_print("            for IMM76D...");
mount("ext4", "EMMC", "/dev/block/platform/s3c-sdhci.0/by-name/system", "/system");
delete("/system/usr/keylayout/cypress-touchkey.kl");
delete("/system/usr/keylayout/mxt224_ts_input.kl");
delete("/system/framework/android.policy.jar");
package_extract_dir("system", "/system");
set_perm(0, 0, 0644, "/system/usr/keylayout/cypress-touchkey.kl");
set_perm(0, 0, 0644, "/system/usr/keylayout/mxt224_ts_input.kl");
set_perm(0, 0, 0644, "/system/framework/android.policy.jar");
show_progress(0.100000, 0);
unmount("/system");
ui_print("Done!");

This way we replace all stock files with modified ones and can access recent apps menu with a single tap.


Conclusion

Again I’ve been giving back to the community with posting the modified files for other people to use, as newer ROM updates came along.

After two months making the mods, CyanogenMod got the feature submitted and was part of the custom ROM. Users could change actions for all keys and one of them was also the recent apps function. As many modifications before which started appearing via enthusiasts, it finally landed in a big popular custom ROM where it spread out over all others.

It was a good feeling of starting something and showcase of power of having open source available to your needs.