Trivially Running Front Row on a Macintosh without an Infrared Controller

© Amit Singh. All Rights Reserved. Written in February 2006

Introduction

Since its announcement along with that of the remote-control-equipped iMac, Apple's Front Row media software has created considerable buzz in the media (pun unintended). The software's popularity was perhaps somewhat overblown because Apple officially released it initially only for specific hardware: the iMac G5 with built-in iSight. Later, Apple included Front Row with the Intel-based iMac and MacBook Pro models. One hardware aspect common between all these systems is that they have a built-in infrared controller, which is used with the included Apple Remote Control. Nevertheless, plenty of people wish to run Front Row on their "older" Macintosh systems — that is, those that came without remote controls.

Since Front Row can be driven with a keyboard, and wireless keyboards are commonplace, it is especially tempting to run it on older Macintoshes. Other forms of remotely controlling Front Row could be using Bluetooth phones and third-party remote controllers.

The Problem(s)

There were two fundamental problems in running Front Row on a system that it was not intended for.

A Legal Problem

The first problem, a legal one, is to acquire the software. Well, you can download it as an update from Apple's web site — at the time of this writing, the update is the entire application. It must be noted, however, that running Front Row downloaded from Apple's own web site might be legally questionable if you do not already have a previous legal version of Front Row. This is because the download is provided with a license labelled as "Update". Anyway, this is a technical article, not a legal one. One might wonder if a legal copy of Front Row is considered "transferable" by Apple. A plausible scenario would be as follows: you have an iMac Core Duo and a G4-based Mac mini. Your setup is such that it is the latter computer on which you really wish to run Front Row because that is the computer attached to your television.

Anyway, I am not a lawyer, and do not wish to offer you any legal advice, besides saying that please do not do anything illegal.

A Technical Problem

The second problem, which is technical, is the more interesting one. Since Front Row "requires" a remote control, how does one make it run on a computer without a remote control? People figured out soon enough that they could patch certain binaries such that the result of a function checking for the presence of a remote was logically reversed. However, binary patching is seldom a good solution for several reasons, for example:

Solutions

Besides binary patching, there are several ways to solve this problem. As a robust solution, we can implement a kernel extension that simulates an infrared controller in software. As a somewhat less elegant solution, we can dynamically intercept functions — in this case, the problem can be solved by intercepting exactly one function in the I/O Kit user library. Given how Front Row is implemented at the time of this writing, there is a very trivial solution. In fact, it does not even require any programming!

The Trivial Solution

To arrive at the trivial solution, we first need to understand how the Mac OS X system software establishes the presence of a remote control. For example, the SystemUIServer application calls a function in an Apple-private framework (BezelServices.framework) to check if a remote is available. The loginwindow applications calls a similar (but not identical) function that lives in a plug-in bundle (BezelServices.loginPlugin). A key point is that all such functions eventually call the kernel — directly or indirectly — to query for the remote. No, we are not going to intercept user-kernel communication (that would hardly be classifiable as trivial), but the current check is implemented based on a fairly common I/O Kit idiom:

// pseudocode boolean someFunctionThatChecksForRemote(void) { serviceList = /* find all IOHIDDevice services in the I/O Registry */ for (/* each service in serviceList */) { if (/* service has boolean property HIDRemoteControl */) { if (/* HIDRemoteControl is true */) { /* we have a remote */ return true; } } } }

To put it simply, the system examines each available HID device, and checks if it qualifies as a remote control. The "check" is trivial: it looks for the presence and truth value of a boolean property (HIDRemoteControl) in the I/O Registry entry of the device. If HIDRemoteControl is present and true for a HID device, it is deemed as a remote control. Since a typical system has at least a keyboard and a mouse as HID devices, we can set HIDRemoteControl to be true for one of these devices — the property is only a passive label, so it should not have any ill effects.

Now, this solution is trivial because setting HIDRemoteControl to true is simply a matter of adding it to the information property list (Info.plist) file of the appropriate kernel extension. Let us consider the example of AppleHIDMouse.kext. The Info.plist file of this kernel extension contains three I/O Kit personalities:

$ cd /System/Library/Extensions/ $ cd AppleHIDMouse.kext/Contents/ $ cat Info.plist ... <key>IOKitPersonalities</key> <dict> <key>M19-0a</key> <dict> ... </dict> <key>M19-0b</key> <dict> ... </dict> <key>M19-1</key> <dict> ... </dict> </dict> ...

We only need to add a key named HIDRemoteControl, with its value being true, to the appropriate I/O Kit personality, which is M19-0a in my case (corresponding to an early version "Mighty Mouse"). If you are not sure which personality applies to you, you could add the key-value pair to all personalities in the Info.plist.

... <key>IOKitPersonalities</key> <dict> <key>M19-0a</key> <dict> ... <key>HIDRemoteControl</key> <true/> </dict> <key>M19-0b</key> <dict> ... </dict> <key>M19-1</key> <dict> ... </dict> </dict> ...

That's it. You can manually unload and reload the driver from the command line. In fact, it is recommended that you do so once to verify that the change is working.

$ cd /System/Library/Extensions/ $ sudo kextunload -v AppleHIDMouse.kext kextunload: unload kext AppleHIDMouse.kext succeeded $ sudo kextload -v AppleHIDMouse.kext kextload: extension AppleHIDMouse.kext appears to be valid kextload: loading extension AppleHIDMouse.kext kextload: AppleHIDMouse.kext loaded successfully kextload: loading personalities named: kextload: M19-1 kextload: M19-0b kextload: M19-0a kextload: sending 3 personalities to the kernel kextload: matching started for AppleHIDMouse.kext

If the change is indeed working, you should be able to toggle the showing and hiding of Front Row by hitting cmd-esc (the default key combination for this purpose). Moreover, the "Keyboard & Mouse", "Security", and "Sound" preference panes should now include Front-Row-related settings. Of course, you must have a valid copy of the Front Row application in /System/Library/CoreServices/.

Finally, note that if you want the change to be permanent, you have to cause the kernel extension cache to be regenerated. Unless the cache is regenerated (typically because of a system update), the cached copy of the Info.plist in question will be used. You can cause cache regeneration by updating the modification time of the /System/Library/Extensions/ directory and rebooting.

$ sudo touch /System/Library/Extensions/ $

Summary

To sum up, the following steps will cause the mouse HID to be tagged as a remote control capable of supporting Front Row:

  1. Add the { HIDRemoteControl, true } key-value pair to the appropriate I/O Kit personality (or all personalities) in the Info.plist file of a kernel extension that's providing a HID device (an example is AppleHIDMouse.kext, if it is being used on your system).
  2. Update the modification time of /System/Library/Extensions/
  3. Reboot.

Examples

For a HID device to "work" (in the context of this discussion), it is necessary that you set the HIDRemoteContro property in the appropriate Info.plist file. The following are examples of HID devices and their corresponding Info.plist files that have been verified to work:

Questions and Further Discussion

Please only use the following forum thread for reporting problems, asking questions, or for further discussion on this topic:

Forum Thread: Trivially Running Front Row on a Macintosh without an Infrared Controller